texlive[50131] trunk: luaotfload (25feb19)

commits+karl at tug.org commits+karl at tug.org
Mon Feb 25 23:22:50 CET 2019


Revision: 50131
          http://tug.org/svn/texlive?view=revision&revision=50131
Author:   karl
Date:     2019-02-25 23:22:50 +0100 (Mon, 25 Feb 2019)
Log Message:
-----------
luaotfload (25feb19)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl
    trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun
    trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua
    trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS
    trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md
    trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst
    trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1
    trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf
    trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5
    trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf
    trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua

Added Paths:
-----------
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-02-14.lua

Removed Paths:
-------------
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-01-28.lua

Modified: trunk/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Build/source/texk/texlive/linked_scripts/context/perl/mptopdf.pl	2019-02-25 22:22:50 UTC (rev 50131)
@@ -118,14 +118,9 @@
     @files = glob "$pattern" ;
 }
 
-# this patch was send via debian but is not tested by me
-
 foreach my $file (@files) {
     $_ = $file ;
-  # if (s/\.(\d+|mps)$// && -e $file) {
-    if (s/\.(\d+|mps|ps)$// && -e $file) {
-        my $suffix = $1 ;
-        my $pdf = basename($_).".pdf" ;
+    if (s/\.(\d+|mps)$// && -e $file) {
         if ($miktex) {
             $command = "pdftex -undump=mptopdf" ;
         } else {
@@ -141,22 +136,15 @@
             print "\n$program : error while processing tex file\n" ;
             exit 1 ;
         }
-      # my $pdfsrc = basename($_).".pdf";
-      # rename ($pdfsrc, "$_-$1.pdf") ;
-      # if (-e $pdfsrc) {
-      #     CopyFile ($pdfsrc, "$_-$1.pdf") ;
-        if ($suffix =~ m/\.\d+$/) {
-            rename ($pdf, "$_-$suffix.pdf") ;
-            if (-e $pdf) {
-                CopyFile ($pdf, "$_-$suffix.pdf") ;
-            }
-            $pdf = "$_-$suffix.pdf" ;
+        my $pdfsrc = basename($_).".pdf";
+        rename ($pdfsrc, "$_-$1.pdf") ;
+        if (-e $pdfsrc) {
+            CopyFile ($pdfsrc, "$_-$1.pdf") ;
         }
         if ($done) {
             $report .= " +" ;
         }
-      # $report .= " $_-$1.pdf" ;
-        $report .= " $pdf" ;
+        $report .= " $_-$1.pdf" ;
         ++$done  ;
     }
 }

Modified: trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Build/source/texk/texlive/linked_scripts/context/stubs/unix/mtxrun	2019-02-25 22:22:50 UTC (rev 50131)
@@ -1,5 +1,16 @@
 #!/usr/bin/env texlua
 
+-- for k, v in next, _G.string do
+--     local tv = type(v)
+--     if tv == "table" then
+--         for kk, vv in next, v do
+--             print(k,kk,vv)
+--         end
+--     else
+--         print(tv,k,v)
+--     end
+-- end
+
 if not modules then modules = { } end modules ['mtxrun'] = {
     version   = 1.001,
     comment   = "runner, lua replacement for texmfstart.rb",
@@ -9,16 +20,10 @@
 }
 
 -- one can make a stub:
-
--- mtxrun :
 --
 -- #!/bin/sh
 -- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@"
 
--- mtxrun.cmd :
---
--- @luatex --luaonly %~d0%~p0mtxrun.lua %*
-
 -- filename : mtxrun.lua
 -- comment  : companion to context.tex
 -- author   : Hans Hagen, PRAGMA-ADE, Hasselt NL
@@ -25,27 +30,15 @@
 -- copyright: PRAGMA ADE / ConTeXt Development Team
 -- license  : see context related readme files
 
--- This script is based on texmfstart.rb but does not use kpsewhich to locate files.
--- Although kpse is a library it never came to opening up its interface to other
--- programs (esp scripting languages) and so we do it ourselves. The lua variant
--- evolved out of an experimental ruby one. Interesting is that using a scripting
--- language instead of c does not have a speed penalty. Actually the lua variant is
--- more efficient, especially when multiple calls to kpsewhich are involved. The lua
+-- This script is based on texmfstart.rb but does not use kpsewhich to
+-- locate files. Although kpse is a library it never came to opening up
+-- its interface to other programs (esp scripting languages) and so we
+-- do it ourselves. The lua variant evolved out of an experimental ruby
+-- one. Interesting is that using a scripting language instead of c does
+-- not have a speed penalty. Actually the lua variant is more efficient,
+-- especially when multiple calls to kpsewhich are involved. The lua
 -- library also gives way more control.
 
--- When libraries used here are updates you can run
---
---   mtxrun --selfmerge
---
--- to update the embedded code. After that you might need to run
---
---   mtxrun --selfupdate
---
--- to copy the new script (from scripts/context/lua) to location where
--- binaries are expected. If you want to remove the embedded code you can run
---
---   mtxxun --selfclean
-
 -- to be done / considered
 --
 -- support for --exec or make it default
@@ -61,147 +54,16 @@
 
 do -- create closure to overcome 200 locals limit
 
-package.loaded["l-bit32"] = package.loaded["l-bit32"] or true
-
--- original size: 3607, stripped down to: 3009
-
-if not modules then modules={} end modules ['l-bit32']={
- version=1.001,
- license="the same as regular Lua",
- source="bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto",
- comment="drop-in for bit32, adapted a bit by Hans Hagen",
-}
-if bit32 then
-elseif utf8 then
- load ([[
-local select = select -- instead of: arg = { ... }
-bit32 = {
-  bnot = function (a)
-    return ~a & 0xFFFFFFFF
-  end,
-  band = function (x, y, z, ...)
-    if not z then
-      return ((x or -1) & (y or -1)) & 0xFFFFFFFF
-    else
-      local res = x & y & z
-      for i=1,select("#",...) do
-        res = res & select(i,...)
-      end
-      return res & 0xFFFFFFFF
-    end
-  end,
-  bor = function (x, y, z, ...)
-    if not z then
-      return ((x or 0) | (y or 0)) & 0xFFFFFFFF
-    else
-      local res = x | y | z
-      for i=1,select("#",...) do
-        res = res | select(i,...)
-      end
-      return res & 0xFFFFFFFF
-    end
-  end,
-  bxor = function (x, y, z, ...)
-    if not z then
-      return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
-    else
-      local res = x ~ y ~ z
-      for i=1,select("#",...) do
-        res = res ~ select(i,...)
-      end
-      return res & 0xFFFFFFFF
-    end
-  end,
-  btest = function (x, y, z, ...)
-    if not z then
-      return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
-    else
-      local res = x & y & z
-      for i=1,select("#",...) do
-          res = res & select(i,...)
-      end
-      return (res & 0xFFFFFFFF) ~= 0
-    end
-  end,
-  lshift = function (a, b)
-    return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
-  end,
-  rshift = function (a, b)
-    return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
-  end,
-  arshift = function (a, b)
-    a = a & 0xFFFFFFFF
-    if b <= 0 or (a & 0x80000000) == 0 then
-      return (a >> b) & 0xFFFFFFFF
-    else
-      return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
-    end
-  end,
-  lrotate = function (a ,b)
-    b = b & 31
-    a = a & 0xFFFFFFFF
-    a = (a << b) | (a >> (32 - b))
-    return a & 0xFFFFFFFF
-  end,
-  rrotate = function (a, b)
-    b = -b & 31
-    a = a & 0xFFFFFFFF
-    a = (a << b) | (a >> (32 - b))
-    return a & 0xFFFFFFFF
-  end,
-  extract = function (a, f, w)
-    return (a >> f) & ~(-1 << (w or 1))
-  end,
-  replace = function (a, v, f, w)
-    local mask = ~(-1 << (w or 1))
-    return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
-  end,
-}
-        ]] ) ()
-elseif bit then
- load ([[
-local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
-bit32 = {
-  arshift = bit.arshift,
-  band    = band,
-  bnot    = bnot,
-  bor     = bit.bor,
-  bxor    = bit.bxor,
-  btest   = function(...)
-    return band(...) ~= 0
-  end,
-  extract = function(a,f,w)
-    return band(rshift(a,f),2^(w or 1)-1)
-  end,
-  lrotate = bit.rol,
-  lshift  = lshift,
-  replace = function(a,v,f,w)
-    local mask = 2^(w or 1)-1
-    return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
-  end,
-  rrotate = bit.ror,
-  rshift  = rshift,
-}
-        ]] ) ()
-else
- xpcall(function() local _,t=require("bit32") if t then bit32=t end return end,function() end)
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
 package.loaded["l-lua"] = package.loaded["l-lua"] or true
 
--- original size: 6281, stripped down to: 2863
+-- original size: 6230, stripped down to: 3662
 
 if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local next,type,tonumber=next,type,tonumber
 LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -209,111 +71,122 @@
 LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
 LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
 if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
+  MINORVERSION=2
+  LUAVERSION=5.2
 end
+_LUAVERSION=LUAVERSION
 if not lpeg then
- lpeg=require("lpeg")
+  lpeg=require("lpeg")
 end
 if loadstring then
- local loadnormal=load
- function load(first,...)
-  if type(first)=="string" then
-   return loadstring(first,...)
-  else
-   return loadnormal(first,...)
+  local loadnormal=load
+  function load(first,...)
+    if type(first)=="string" then
+      return loadstring(first,...)
+    else
+      return loadnormal(first,...)
+    end
   end
- end
 else
- loadstring=load
+  loadstring=load
 end
 if not ipairs then
- local function iterate(a,i)
-  i=i+1
-  local v=a[i]
-  if v~=nil then
-   return i,v 
+  local function iterate(a,i)
+    i=i+1
+    local v=a[i]
+    if v~=nil then
+      return i,v 
+    end
   end
- end
- function ipairs(a)
-  return iterate,a,0
- end
+  function ipairs(a)
+    return iterate,a,0
+  end
 end
 if not pairs then
- function pairs(t)
-  return next,t 
- end
+  function pairs(t)
+    return next,t 
+  end
 end
 if not table.unpack then
- table.unpack=_G.unpack
+  table.unpack=_G.unpack
 elseif not unpack then
- _G.unpack=table.unpack
+  _G.unpack=table.unpack
 end
 if not package.loaders then 
- package.loaders=package.searchers
+  package.loaders=package.searchers
 end
 local print,select,tostring=print,select,tostring
 local inspectors={}
 function setinspector(kind,inspector) 
- inspectors[kind]=inspector
+  inspectors[kind]=inspector
 end
 function inspect(...) 
- for s=1,select("#",...) do
-  local value=select(s,...)
-  if value==nil then
-   print("nil")
-  else
-   local done=false
-   local kind=type(value)
-   local inspector=inspectors[kind]
-   if inspector then
-    done=inspector(value)
-    if done then
-     break
+  for s=1,select("#",...) do
+    local value=select(s,...)
+    if value==nil then
+      print("nil")
+    else
+      local done=false
+      local kind=type(value)
+      local inspector=inspectors[kind]
+      if inspector then
+        done=inspector(value)
+        if done then
+          break
+        end
+      end
+      for kind,inspector in next,inspectors do
+        done=inspector(value)
+        if done then
+          break
+        end
+      end
+      if not done then
+        print(tostring(value))
+      end
     end
-   end
-   for kind,inspector in next,inspectors do
-    done=inspector(value)
-    if done then
-     break
-    end
-   end
-   if not done then
-    print(tostring(value))
-   end
   end
- end
 end
 local dummy=function() end
 function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
-  return result
- end
+  local ok,result=xpcall(require,dummy,...)
+  if ok then
+    return result
+  end
 end
 if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+  lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
 end
 local flush=io.flush
 if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec   (...) flush() return exec   (...) end end
- local spawn=os.spawn   if spawn   then function os.spawn  (...) flush() return spawn  (...) end end
- local popen=io.popen   if popen   then function io.popen  (...) flush() return popen  (...) end end
+  local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+  local exec=os.exec  if exec  then function os.exec  (...) flush() return exec  (...) end end
+  local spawn=os.spawn  if spawn  then function os.spawn (...) flush() return spawn (...) end end
+  local popen=io.popen  if popen  then function io.popen (...) flush() return popen (...) end end
 end
 FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
 if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+  local okay;okay,ffi=pcall(require,"ffi")
+  FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
 end
 if not FFISUPPORTED then
- ffi=nil
+  ffi=nil
 elseif not ffi.number then
- ffi.number=tonumber
+  ffi.number=tonumber
 end
-if LUAVERSION>5.3 then
- collectgarbage("generational")
+if not bit32 then
+  bit32=require("l-bit32")
 end
+local loaded=package.loaded
+if not loaded["socket"] then loaded["socket"]=loaded["socket.core"] end
+if not loaded["mime"]  then loaded["mime"]=loaded["mime.core"]  end
+if not socket.mime then socket.mime=package.loaded["mime"] end
+if not loaded["socket.mime"] then loaded["socket.mime"]=socket.mime end
+if not loaded["socket.http"] then loaded["socket.http"]=socket.http end
+if not loaded["socket.ftp"] then loaded["socket.ftp"]=socket.ftp end
+if not loaded["socket.smtp"] then loaded["socket.smtp"]=socket.smtp end
+if not loaded["socket.tp"]  then loaded["socket.tp"]=socket.tp  end
+if not loaded["socket.url"] then loaded["socket.url"]=socket.url end
 
 
 end -- of closure
@@ -322,27 +195,25 @@
 
 package.loaded["l-macro"] = package.loaded["l-macro"] or true
 
--- original size: 10131, stripped down to: 5991
+-- original size: 8260, stripped down to: 5213
 
 if not modules then modules={} end modules ['l-macros']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg
 local lpegmatch=lpeg.match
 local concat=table.concat
-local format,sub,match=string.format,string.sub,string.match
+local format,sub=string.format,string.sub
 local next,load,type=next,load,type
 local newline=S("\n\r")^1
 local continue=P("\\")*newline
-local whitespace=S(" \t\n\r")
 local spaces=S(" \t")+continue
-local nametoken=R("az","AZ","__","09")
-local name=nametoken^1
-local body=((continue/""+1)-newline)^1
+local name=R("az","AZ","__","09")^1
+local body=((1+continue/"")-newline)^1
 local lparent=P("(")
 local rparent=P(")")
 local noparent=1-(lparent+rparent)
@@ -359,214 +230,172 @@
 local resolve
 local subparser
 local report_lua=function(...)
- if logs and logs.reporter then
-  report_lua=logs.reporter("system","lua")
-  report_lua(...)
- else
-  print(format(...))
- end
+  if logs and logs.reporter then
+    report_lua=logs.reporter("system","lua")
+    report_lua(...)
+  else
+    print(format(...))
+  end
 end
-local safeguard=P("local")*whitespace^1*name*(whitespace+P("="))
-resolve=safeguard+C(C(name)*(arguments^-1))/function(raw,s,a)
- local d=definitions[s]
- if d then
-  if a then
-   local n=#a
-   local p=patterns[s][n]
-   if p then
-    local d=d[n]
-    for i=1,n do
-     a[i]=lpegmatch(subparser,a[i]) or a[i]
+resolve=C(C(name)*arguments^-1)/function(raw,s,a)
+  local d=definitions[s]
+  if d then
+    if a then
+      local n=#a
+      local p=patterns[s][n]
+      if p then
+        local d=d[n]
+        for i=1,n do
+          a[i]=lpegmatch(subparser,a[i]) or a[i]
+        end
+        return lpegmatch(p,d,1,a) or d
+      else
+        return raw
+      end
+    else
+      return d[0] or raw
     end
-    return lpegmatch(p,d,1,a) or d
-   else
+  elseif a then
+    for i=1,#a do
+      a[i]=lpegmatch(subparser,a[i]) or a[i]
+    end
+    return s.."("..concat(a,",")..")"
+  else
     return raw
-   end
-  else
-   return d[0] or raw
   end
- elseif a then
-  for i=1,#a do
-   a[i]=lpegmatch(subparser,a[i]) or a[i]
-  end
-  return s.."("..concat(a,",")..")"
- else
-  return raw
- end
 end
 subparser=Cs((resolve+P(1))^1)
 local enddefine=P("#enddefine")/""
-local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
- local n=0
- if a then
-  n=#a
-  local pattern=P(false)
-  for i=1,n do
-   pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+local beginregister=(C(name)*spaces^0*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
+  local n=0
+  if a then
+    n=#a
+    local pattern=P(false)
+    for i=1,n do
+      pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+    end
+    pattern=Cs((pattern+P(1))^1)
+    local p=patterns[k]
+    if not p then
+      p={ [0]=false,false,false,false,false,false,false,false,false }
+      patterns[k]=p
+    end
+    p[n]=pattern
   end
-  pattern=Cs((pattern+P(1))^1)
-  local p=patterns[k]
-  if not p then
-   p={ [0]=false,false,false,false,false,false,false,false,false }
-   patterns[k]=p
+  local d=definitions[k]
+  if not d then
+    d={ [0]=false,false,false,false,false,false,false,false,false }
+    definitions[k]=d
   end
-  p[n]=pattern
- end
- local d=definitions[k]
- if not d then
-  d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
-  definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+  d[n]=lpegmatch(subparser,v) or v
+  return ""
 end
-local register=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
- local n=0
- if a then
-  n=#a
-  local pattern=P(false)
-  for i=1,n do
-   pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+local register=(C(name)*spaces^0*(arguments+Cc(false))*spaces^0*C(body))/function(k,a,v)
+  local n=0
+  if a then
+    n=#a
+    local pattern=P(false)
+    for i=1,n do
+      pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+    end
+    pattern=Cs((pattern+P(1))^1)
+    local p=patterns[k]
+    if not p then
+      p={ [0]=false,false,false,false,false,false,false,false,false }
+      patterns[k]=p
+    end
+    p[n]=pattern
   end
-  pattern=Cs((pattern+P(1))^1)
-  local p=patterns[k]
-  if not p then
-   p={ [0]=false,false,false,false,false,false,false,false,false }
-   patterns[k]=p
+  local d=definitions[k]
+  if not d then
+    d={ [0]=false,false,false,false,false,false,false,false,false }
+    definitions[k]=d
   end
-  p[n]=pattern
- end
- local d=definitions[k]
- if not d then
-  d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
-  definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+  d[n]=lpegmatch(subparser,v) or v
+  return ""
 end
 local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
-  n=#a
-  local p=patterns[k]
-  if p then
-   p[n]=false
+  local n=0
+  if a then
+    n=#a
+    local p=patterns[k]
+    if p then
+      p[n]=false
+    end
   end
- end
- local d=definitions[k]
- if d then
-  d[n]=false
- end
- return ""
+  local d=definitions[k]
+  if d then
+    d[n]=false
+  end
+  return ""
 end
 local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define"  )*spaces^0/"")*register
-local undefine=(P("undefine"   )*spaces^0/"")*unregister
+local define=(P("define"   )*spaces^0/"")*register
+local undefine=(P("undefine"  )*spaces^0/"")*unregister
 local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
 function macros.reset()
- definitions={}
- patterns={}
+  definitions={}
+  patterns={}
 end
-function macros.showdefinitions()
- for name,list in table.sortedhash(definitions) do
-  local arguments=list.a
-  if arguments then
-   arguments="("..concat(arguments,",")..")"
-  else
-   arguments=""
-  end
-  print("macro: "..name..arguments)
-  for i=0,#list do
-   local l=list[i]
-   if l then
-    print("  "..l)
-   end
-  end
- end
-end
 function macros.resolvestring(str)
- return lpegmatch(parser,str) or str
+  return lpegmatch(parser,str) or str
 end
 function macros.resolving()
- return next(patterns)
+  return next(patterns)
 end
-local function reload(path,name,data)
- local only=match(name,".-([^/]+)%.lua")
- if only and only~="" then
-  local name=path.."/"..only
-  local f=io.open(name,"wb")
-  f:write(data)
+local function loaded(name,trace,detail)
+  local f=io.open(name,"rb")
+  if not f then
+    return false,format("file '%s' not found",name)
+  end
+  local c=f:read("*a")
+  if not c then
+    return false,format("file '%s' is invalid",name)
+  end
   f:close()
-  local f=loadfile(name)
-  os.remove(name)
-  return f
- end
-end
-local function reload(path,name,data)
- if path and path~="" then
-  local only=string.match(name,".-([^/]+)%.lua")
-  if only and only~="" then
-   local name=path.."/"..only.."-macro.lua"
-   local f=io.open(name,"wb")
-   if f then
-    f:write(data)
-    f:close()
-    local l=loadfile(name)
-    os.remove(name)
-    return l
-   end
+  local n=lpegmatch(parser,c)
+  if trace then
+    if #n~=#c then
+      report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+      if detail then
+        report_lua()
+        report_lua(n)
+        report_lua()
+      end
+    elseif detail then
+      report_lua("no macros expanded in '%s'",name)
+    end
   end
- end
- return load(data,name)
-end
-local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
-  return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
-  return false,format("file '%s' is invalid",name)
- end
- f:close()
- local n=lpegmatch(parser,c)
- if trace then
-  if #n~=#c then
-   report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
-   if detail then
-    report_lua()
-    report_lua(n)
-    report_lua()
-   end
-  elseif detail then
-   report_lua("no macros expanded in '%s'",name)
+  if #name>30 then
+    n="--[["..sub(name,-30).."]] "..n
+  else
+    n="--[["..name.."]] "..n
   end
- end
- return reload(lfs and lfs.currentdir(),name,n)
+  return load(n)
 end
 macros.loaded=loaded
 function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
-  return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
-  return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
-  code=code()
- else
-  report_lua("error when loading '%s'",fullname)
-  return false,message
- end
- if code==nil then
-  code=false
- end
- package.loaded[fullname]=code
- return code
+  local filename=file.addsuffix(name,"lua")
+  local fullname=resolvers and resolvers.find_file(filename) or filename
+  if not fullname or fullname=="" then
+    return false
+  end
+  local codeblob=package.loaded[fullname]
+  if codeblob then
+    return codeblob
+  end
+  local code,message=loaded(fullname,macros,trace,trace)
+  if type(code)=="function" then
+    code=code()
+  else
+    report_lua("error when loading '%s'",fullname)
+    return false,message
+  end
+  if code==nil then
+    code=false
+  end
+  package.loaded[fullname]=code
+  return code
 end
 macros.required=required
 
@@ -577,14 +406,14 @@
 
 package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
 
--- original size: 9747, stripped down to: 6313
+-- original size: 9678, stripped down to: 6688
 
 if not modules then modules={} end modules ['l-sandbox']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local global=_G
 local next=next
@@ -610,195 +439,192 @@
 local logger=false
 local blocked={}
 local function report(...)
- tprint("sandbox         ! "..format(...)) 
+  tprint("sandbox         ! "..format(...)) 
 end
 sandbox.report=report
 function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+  report=r
+  sandbox.report=r
 end
 function sandbox.settrace(v)
- trace=v
+  trace=v
 end
 function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+  logger=type(l)=="function" and l or false
 end
 local function register(func,overload,comment)
- if type(func)=="function" then
-  if type(overload)=="string" then
-   comment=overload
-   overload=nil
-  end
-  local function f(...)
-   if sandboxed then
-    local overload=overloads[f]
-    if overload then
-     if logger then
-      local result={ overload(func,...) }
-      logger {
-       comment=comments[f] or tostring(f),
-       arguments={... },
-       result=result[1] and true or false,
-      }
-      return unpack(result)
-     else
-      return overload(func,...)
-     end
-    else
+  if type(func)=="function" then
+    if type(overload)=="string" then
+      comment=overload
+      overload=nil
     end
-   else
-    return func(...)
-   end
+    local function f(...)
+      if sandboxed then
+        local overload=overloads[f]
+        if overload then
+          if logger then
+            local result={ overload(func,...) }
+            logger {
+              comment=comments[f] or tostring(f),
+              arguments={... },
+              result=result[1] and true or false,
+            }
+            return unpack(result)
+          else
+            return overload(func,...)
+          end
+        else
+        end
+      else
+        return func(...)
+      end
+    end
+    if comment then
+      comments[f]=comment
+      if trace then
+        report("registering function: %s",comment)
+      end
+    end
+    overloads[f]=overload or false
+    originals[f]=func
+    return f
   end
-  if comment then
-   comments[f]=comment
-   if trace then
-    report("registering function: %s",comment)
-   end
-  end
-  overloads[f]=overload or false
-  originals[f]=func
-  return f
- end
 end
 local function redefine(func,comment)
- if type(func)=="function" then
-  skiploads[func]=comment or comments[func] or "unknown"
-  if overloads[func]==false then
-   overloads[func]=nil 
+  if type(func)=="function" then
+    skiploads[func]=comment or comments[func] or "unknown"
+    if overloads[func]==false then
+      overloads[func]=nil 
+    end
   end
- end
 end
 sandbox.register=register
 sandbox.redefine=redefine
 function sandbox.original(func)
- return originals and originals[func] or func
+  return originals and originals[func] or func
 end
 function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
-  if trace then
-   report("overloading unknown function: %s",comment)
+  comment=comment or comments[func] or "?"
+  if type(func)~="function" then
+    if trace then
+      report("overloading unknown function: %s",comment)
+    end
+  elseif type(overload)~="function" then
+    if trace then
+      report("overloading function with bad overload: %s",comment)
+    end
+  elseif overloads[func]==nil then
+    if trace then
+      report("function is not registered: %s",comment)
+    end
+  elseif skiploads[func] then
+    if trace then
+      report("function is not skipped: %s",comment)
+    end
+  else
+    if trace then
+      report("overloading function: %s",comment)
+    end
+    overloads[func]=overload
   end
- elseif type(overload)~="function" then
-  if trace then
-   report("overloading function with bad overload: %s",comment)
-  end
- elseif overloads[func]==nil then
-  if trace then
-   report("function is not registered: %s",comment)
-  end
- elseif skiploads[func] then
-  if trace then
-   report("function is not skipped: %s",comment)
-  end
- else
-  if trace then
-   report("overloading function: %s",comment)
-  end
-  overloads[func]=overload
- end
- return func
+  return func
 end
 local function whatever(specification,what,target)
- if type(specification)~="table" then
-  report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
-  report("%s needs a category and action",what)
- elseif not sandboxed then
-  target[#target+1]=specification
- elseif trace then
-  report("already enabled, discarding %s",what)
- end
+  if type(specification)~="table" then
+    report("%s needs a specification",what)
+  elseif type(specification.category)~="string" or type(specification.action)~="function" then
+    report("%s needs a category and action",what)
+  elseif not sandboxed then
+    target[#target+1]=specification
+  elseif trace then
+    report("already enabled, discarding %s",what)
+  end
 end
 function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+  whatever(specification,"initializer",initializers)
 end
 function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+  whatever(specification,"finalizer",finalizers)
 end
 function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
-  return nil 
- elseif b then
-  if trace then
-   report("using blocked: %s",n)
+  local n=gsub(name,"^.*[\\/]","")
+  local n=gsub(n,"[%.].*$","")
+  local b=blocked[n]
+  if b==false then
+    return nil 
+  elseif b then
+    if trace then
+      report("using blocked: %s",n)
+    end
+    return b
+  else
+    if trace then
+      report("requiring: %s",name)
+    end
+    return requiem(name)
   end
-  return b
- else
+end
+function blockrequire(name,lib)
   if trace then
-   report("requiring: %s",name)
+    report("preventing reload of: %s",name)
   end
-  return requiem(name)
- end
+  blocked[name]=lib or _G[name] or false
 end
-function blockrequire(name,lib)
- if trace then
-  report("preventing reload of: %s",name)
- end
- blocked[name]=lib or _G[name] or false
-end
 function sandbox.enable()
- if not sandboxed then
-  debug={
-   traceback=debug.traceback,
-  }
-  for i=1,#initializers do
-   initializers[i].action()
-  end
-  for i=1,#finalizers do
-   finalizers[i].action()
-  end
-  local nnot=0
-  local nyes=0
-  local cnot={}
-  local cyes={}
-  local skip={}
-  for k,v in next,overloads do
-   local c=comments[k]
-   if v then
-    if c then
-     cyes[#cyes+1]=c
-    else 
-     nyes=nyes+1
+  if not sandboxed then
+    for i=1,#initializers do
+      initializers[i].action()
     end
-   else
-    if c then
-     cnot[#cnot+1]=c
-    else 
-     nnot=nnot+1
+    for i=1,#finalizers do
+      finalizers[i].action()
     end
-   end
+    local nnot=0
+    local nyes=0
+    local cnot={}
+    local cyes={}
+    local skip={}
+    for k,v in next,overloads do
+      local c=comments[k]
+      if v then
+        if c then
+          cyes[#cyes+1]=c
+        else 
+          nyes=nyes+1
+        end
+      else
+        if c then
+          cnot[#cnot+1]=c
+        else 
+          nnot=nnot+1
+        end
+      end
+    end
+    for k,v in next,skiploads do
+      skip[#skip+1]=v
+    end
+    if #cyes>0 then
+      sort(cyes)
+      report("overloaded known: %s",concat(cyes," | "))
+    end
+    if nyes>0 then
+      report("overloaded unknown: %s",nyes)
+    end
+    if #cnot>0 then
+      sort(cnot)
+      report("not overloaded known: %s",concat(cnot," | "))
+    end
+    if nnot>0 then
+      report("not overloaded unknown: %s",nnot)
+    end
+    if #skip>0 then
+      sort(skip)
+      report("not overloaded redefined: %s",concat(skip," | "))
+    end
+    initializers=nil
+    finalizers=nil
+    originals=nil
+    sandboxed=true
   end
-  for k,v in next,skiploads do
-   skip[#skip+1]=v
-  end
-  if #cyes>0 then
-   sort(cyes)
-   report("overloaded known: %s",concat(cyes," | "))
-  end
-  if nyes>0 then
-   report("overloaded unknown: %s",nyes)
-  end
-  if #cnot>0 then
-   sort(cnot)
-   report("not overloaded known: %s",concat(cnot," | "))
-  end
-  if nnot>0 then
-   report("not overloaded unknown: %s",nnot)
-  end
-  if #skip>0 then
-   sort(skip)
-   report("not overloaded redefined: %s",concat(skip," | "))
-  end
-  initializers=nil
-  finalizers=nil
-  originals=nil
-  sandboxed=true
- end
 end
 blockrequire("lfs",lfs)
 blockrequire("io",io)
@@ -805,39 +631,39 @@
 blockrequire("os",os)
 blockrequire("ffi",ffi)
 local function supported(library)
- local l=_G[library]
- return l
+  local l=_G[library]
+  return l
 end
 loadfile=register(loadfile,"loadfile")
 if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen") 
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+  io.open=register(io.open,"io.open")
+  io.popen=register(io.popen,"io.popen") 
+  io.lines=register(io.lines,"io.lines")
+  io.output=register(io.output,"io.output")
+  io.input=register(io.input,"io.input")
 end
 if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+  os.execute=register(os.execute,"os.execute")
+  os.spawn=register(os.spawn,"os.spawn")
+  os.exec=register(os.exec,"os.exec")
+  os.rename=register(os.rename,"os.rename")
+  os.remove=register(os.remove,"os.remove")
 end
 if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+  lfs.chdir=register(lfs.chdir,"lfs.chdir")
+  lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+  lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+  lfs.isfile=register(lfs.isfile,"lfs.isfile")
+  lfs.isdir=register(lfs.isdir,"lfs.isdir")
+  lfs.attributes=register(lfs.attributes,"lfs.attributes")
+  lfs.dir=register(lfs.dir,"lfs.dir")
+  lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+  lfs.touch=register(lfs.touch,"lfs.touch")
+  lfs.link=register(lfs.link,"lfs.link")
+  lfs.setmode=register(lfs.setmode,"lfs.setmode")
+  lfs.readlink=register(lfs.readlink,"lfs.readlink")
+  lfs.shortname=register(lfs.shortname,"lfs.shortname")
+  lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
 end
 
 
@@ -847,14 +673,14 @@
 
 package.loaded["l-package"] = package.loaded["l-package"] or true
 
--- original size: 11605, stripped down to: 8299
+-- original size: 11562, stripped down to: 8625
 
 if not modules then modules={} end modules ['l-package']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type=type
 local gsub,format,find=string.gsub,string.format,string.find
@@ -862,40 +688,40 @@
 local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
 local package=package
 local searchers=package.searchers or package.loaders
-local filejoin=file and file.join  or function(path,name)   return path.."/"..name end
-local isreadable=file and file.is_readable or function(name)  local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix   or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join    or function(path,name)  return path.."/"..name end
+local isreadable=file and file.is_readable or function(name)    local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix  or function(name,suffix) return name.."."..suffix end
 local function cleanpath(path) 
- return path
+  return path
 end
 local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
 local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+  return lpegmatch(pattern,name) or name
 end
 local offset=luarocks and 1 or 0 
 local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
-  ["preload table"]=searchers[1+offset],
-  ["path specification"]=searchers[2+offset],
-  ["cpath specification"]=searchers[3+offset],
-  ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
-  "already loaded",
-  "preload table",
-  "qualified path",
-  "lua extra list",
-  "lib extra list",
-  "path specification",
-  "cpath specification",
-  "all in one fallback",
-  "not loaded",
- }
+  cleanpath=cleanpath,
+  lualibfile=lualibfile,
+  trace=false,
+  report=function(...) print(format(...)) end,
+  builtin={
+    ["preload table"]=searchers[1+offset],
+    ["path specification"]=searchers[2+offset],
+    ["cpath specification"]=searchers[3+offset],
+    ["all in one fallback"]=searchers[4+offset],
+  },
+  methods={},
+  sequence={
+    "already loaded",
+    "preload table",
+    "qualified path",
+    "lua extra list",
+    "lib extra list",
+    "path specification",
+    "cpath specification",
+    "all in one fallback",
+    "not loaded",
+  }
 }
 package.helpers=helpers
 local methods=helpers.methods
@@ -911,51 +737,51 @@
 local nofpathlua=-1
 local nofpathlib=-1
 local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
-  for i=1,nofpaths do
-   helpers.report("using %s path %i: %s",what,i,paths[i])
+  local nofpaths=#paths
+  if nofpaths>0 then
+    for i=1,nofpaths do
+      helpers.report("using %s path %i: %s",what,i,paths[i])
+    end
+  else
+    helpers.report("no %s paths defined",what)
   end
- else
-  helpers.report("no %s paths defined",what)
- end
- return nofpaths
+  return nofpaths
 end
 local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
-  nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+  if helpers.trace and #extraluapaths~=nofextralua then
+    nofextralua=listpaths("extra lua",extraluapaths)
+  end
+  return extraluapaths
 end
 local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
-  nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+  if helpers.trace and #extralibpaths~=nofextralib then
+    nofextralib=listpaths("extra lib",extralibpaths)
+  end
+  return extralibpaths
 end
 local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
-  luapaths=file.splitpath(luapath,";")
-  oldluapath=luapath
-  nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
-  nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+  local luapath=package.path or ""
+  if oldluapath~=luapath then
+    luapaths=file.splitpath(luapath,";")
+    oldluapath=luapath
+    nofpathlua=-1
+  end
+  if helpers.trace and #luapaths~=nofpathlua then
+    nofpathlua=listpaths("builtin lua",luapaths)
+  end
+  return luapaths
 end
 local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
-  libpaths=file.splitpath(libpath,";")
-  oldlibpath=libpath
-  nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
-  nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+  local libpath=package.cpath or ""
+  if oldlibpath~=libpath then
+    libpaths=file.splitpath(libpath,";")
+    oldlibpath=libpath
+    nofpathlib=-1
+  end
+  if helpers.trace and #libpaths~=nofpathlib then
+    nofpathlib=listpaths("builtin lib",libpaths)
+  end
+  return libpaths
 end
 package.luapaths=getluapaths
 package.libpaths=getlibpaths
@@ -962,205 +788,202 @@
 package.extraluapaths=getextraluapaths
 package.extralibpaths=getextralibpaths
 local hashes={
- lua={},
- lib={},
+  lua={},
+  lib={},
 }
 local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
-  local path=cleanpath(path)
-  if not hash[path] then
-   target[#target+1]=path
-   hash[path]=true
-   if trace then
-    report("registered %s path %s: %s",tag,#target,path)
-   end
-  else
-   if trace then
-    report("duplicate %s path: %s",tag,path)
-   end
+  local pathlist={... }
+  local cleanpath=helpers.cleanpath
+  local trace=helpers.trace
+  local report=helpers.report
+  local hash=hashes[what]
+  local function add(path)
+    local path=cleanpath(path)
+    if not hash[path] then
+      target[#target+1]=path
+      hash[path]=true
+      if trace then
+        report("registered %s path %s: %s",tag,#target,path)
+      end
+    else
+      if trace then
+        report("duplicate %s path: %s",tag,path)
+      end
+    end
   end
- end
- for p=1,#pathlist do
-  local path=pathlist[p]
-  if type(path)=="table" then
-   for i=1,#path do
-    add(path[i])
-   end
-  else
-   add(path)
+  for p=1,#pathlist do
+    local path=pathlist[p]
+    if type(path)=="table" then
+      for i=1,#path do
+        add(path[i])
+      end
+    else
+      add(path)
+    end
   end
- end
 end
 local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
-  helpers.report("pushing %s path in front: %s",tag,path)
- end
+  local path=helpers.cleanpath(path)
+  insert(target,1,path)
+  if helpers.trace then
+    helpers.report("pushing %s path in front: %s",tag,path)
+  end
 end
 local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
-  if path then
-   helpers.report("popping %s path from front: %s",tag,path)
-  else
-   helpers.report("no %s path to pop",tag)
+  local path=remove(target,1)
+  if helpers.trace then
+    if path then
+      helpers.report("popping %s path from front: %s",tag,path)
+    else
+      helpers.report("no %s path to pop",tag)
+    end
   end
- end
 end
 helpers.registerpath=registerpath
 function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+  registerpath("extra lua","lua",extraluapaths,...)
 end
 function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+  pushpath("extra lua","lua",extraluapaths,path)
 end
 function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+  poppath("extra lua","lua",extraluapaths)
 end
 function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+  registerpath("extra lib","lib",extralibpaths,...)
 end
 function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+  pushpath("extra lib","lib",extralibpaths,path)
 end
 function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+  poppath("extra lib","lua",extralibpaths)
 end
 local function loadedaslib(resolved,rawname) 
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
-  helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+  local base=gsub(rawname,"%.","_")
+  local init="luaopen_"..gsub(base,"%.","_")
+  if helpers.trace then
+    helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+  end
+  return package.loadlib(resolved,init)
 end
 helpers.loadedaslib=loadedaslib
 local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
-  local path=paths[p]
-  local resolved=filejoin(path,name)
-  if trace then
-   helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+  local trace=helpers.trace
+  for p=1,#paths do
+    local path=paths[p]
+    local resolved=filejoin(path,name)
+    if trace then
+      helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+    end
+    if isreadable(resolved) then
+      if trace then
+        helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+      end
+      if islib then
+        return loadedaslib(resolved,rawname)
+      else
+        return loadfile(resolved)
+      end
+    end
   end
-  if isreadable(resolved) then
-   if trace then
-    helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
-   end
-   if islib then
-    return loadedaslib(resolved,rawname)
-   else
-    return loadfile(resolved)
-   end
-  end
- end
 end
 helpers.loadedbypath=loadedbypath
 local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
-  local trace=helpers.trace
-  if trace then
-   helpers.report("qualified name, identifying '%s'",what,name)
+  if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+    local trace=helpers.trace
+    if trace then
+      helpers.report("qualified name, identifying '%s'",what,name)
+    end
+    if isreadable(name) then
+      if trace then
+        helpers.report("qualified name, '%s' found",what,name)
+      end
+      return loadfile(name)
+    end
   end
-  if isreadable(name) then
-   if trace then
-    helpers.report("qualified name, '%s' found",what,name)
-   end
-   return loadfile(name)
-  end
- end
 end
 helpers.loadedbyname=loadedbyname
 methods["already loaded"]=function(name)
- return package.loaded[name]
+  return package.loaded[name]
 end
 methods["preload table"]=function(name)
- return builtin["preload table"](name)
+  return builtin["preload table"](name)
 end
 methods["qualified path"]=function(name)
-  return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
 end
 methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+  return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
 end
 methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+  return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
 end
 methods["path specification"]=function(name)
- getluapaths() 
- return builtin["path specification"](name)
+  getluapaths() 
+  return builtin["path specification"](name)
 end
 methods["cpath specification"]=function(name)
- getlibpaths() 
- return builtin["cpath specification"](name)
+  getlibpaths() 
+  return builtin["cpath specification"](name)
 end
 methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+  return builtin["all in one fallback"](name)
 end
 methods["not loaded"]=function(name)
- if helpers.trace then
-  helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+  if helpers.trace then
+    helpers.report("unable to locate '%s'",name or "?")
+  end
+  return nil
 end
 local level=0
 local used={}
 helpers.traceused=false
 function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
-  local method=sequence[i]
-  if helpers.trace then
-   helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
+  local sequence=helpers.sequence
+  level=level+1
+  for i=1,#sequence do
+    local method=sequence[i]
+    if helpers.trace then
+      helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
+    end
+    local result,rest=methods[method](name)
+    if type(result)=="function" then
+      if helpers.trace then
+        helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+      end
+      if helpers.traceused then
+        used[#used+1]={ level=level,name=name }
+      end
+      level=level-1
+      return result,rest
+    end
   end
-  local result,rest=methods[method](name)
-  if type(result)=="function" then
-   if helpers.trace then
-    helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
-   end
-   if helpers.traceused then
-    used[#used+1]={ level=level,name=name }
-   end
-   level=level-1
-   return result,rest
-  end
- end
- level=level-1
- return nil
+  level=level-1
+  return nil
 end
 function helpers.showused()
- local n=#used
- if n>0 then
-  helpers.report("%s libraries loaded:",n)
-  helpers.report()
-  for i=1,n do
-   local u=used[i]
-   helpers.report("%i %a",u.level,u.name)
-  end
-  helpers.report()
-  end
+  local n=#used
+  if n>0 then
+    helpers.report("%s libraries loaded:",n)
+    helpers.report()
+    for i=1,n do
+      local u=used[i]
+      helpers.report("%i %a",u.level,u.name)
+    end
+    helpers.report()
+   end
 end
 function helpers.unload(name)
- if helpers.trace then
-  if package.loaded[name] then
-   helpers.report("unloading, name '%s', %s",name,"done")
-  else
-   helpers.report("unloading, name '%s', %s",name,"not loaded")
+  if helpers.trace then
+    if package.loaded[name] then
+      helpers.report("unloading, name '%s', %s",name,"done")
+    else
+      helpers.report("unloading, name '%s', %s",name,"not loaded")
+    end
   end
- end
- package.loaded[name]=nil
+  package.loaded[name]=nil
 end
 table.insert(searchers,1,helpers.loaded)
-if context then
- package.path=""
-end
 
 
 end -- of closure
@@ -1169,14 +992,14 @@
 
 package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
 
--- original size: 38434, stripped down to: 19310
+-- original size: 38582, stripped down to: 20518
 
 if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 lpeg=require("lpeg") 
 local lpeg=lpeg
@@ -1187,7 +1010,7 @@
 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
 if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+  setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
 end
 lpeg.patterns=lpeg.patterns or {} 
 local patterns=lpeg.patterns
@@ -1210,7 +1033,7 @@
 local hexdigit=digit+lowercase+uppercase
 local hexdigits=hexdigit^1
 local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")  
+local newline=P("\r")*(P("\n")+P(true))+P("\n") 
 local escaped=P("\\")*anything
 local squote=P("'")
 local dquote=P('"')
@@ -1219,9 +1042,9 @@
 local comma=P(",")
 local utfbom_32_be=P('\000\000\254\255') 
 local utfbom_32_le=P('\255\254\000\000') 
-local utfbom_16_be=P('\254\255')   
-local utfbom_16_le=P('\255\254')   
-local utfbom_8=P('\239\187\191')  
+local utfbom_16_be=P('\254\255')     
+local utfbom_16_le=P('\255\254')     
+local utfbom_8=P('\239\187\191')   
 local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
 local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8") 
 local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -1253,7 +1076,7 @@
 patterns.validutf8=validutf8char
 patterns.validutf8char=validutf8char
 local eol=S("\n\r")
-local spacer=S(" \t\f\v")  
+local spacer=S(" \t\f\v") 
 local whitespace=eol+spacer
 local nonspacer=1-spacer
 local nonwhitespace=1-whitespace
@@ -1262,15 +1085,15 @@
 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))
 local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
 local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0)
-local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0)
+local e_collapser=Cs((whitespace^1*P(-1)/""+nonwhitespace^1+whitespace^1/" ")^0)
 local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0)
 local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0)
-local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0)
+local e_stripper=Cs((spacer^1*P(-1)/""+nonspacer^1+spacer^1/" ")^0)
 local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0)
 patterns.stripper=stripper
 patterns.fullstripper=fullstripper
@@ -1327,7 +1150,7 @@
 patterns.number=patterns.float+patterns.integer
 patterns.cnumber=patterns.cfloat+patterns.integer
 patterns.cpnumber=patterns.cpfloat+patterns.integer
-patterns.oct=zero*octdigits 
+patterns.oct=zero*octdigits
 patterns.octal=patterns.oct
 patterns.HEX=zero*P("X")*(digit+uppercase)^1
 patterns.hex=zero*P("x")*(digit+lowercase)^1
@@ -1337,85 +1160,77 @@
 patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
 patterns.somecontent=(anything-newline-space)^1 
 patterns.beginline=#(1-newline)
-patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
-function anywhere(pattern) 
- return (1-P(pattern))^0*P(pattern)
+patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0))
+local function anywhere(pattern) 
+  return P { P(pattern)+1*V(1) }
 end
 lpeg.anywhere=anywhere
 function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
-  return lpegmatch(p,str) and true or false
- end
+  p=anywhere(p)
+  return function(str)
+    return lpegmatch(p,str) and true or false
+  end
 end
 function lpeg.splitter(pattern,action)
- if action then
   return (((1-P(pattern))^1)/action+1)^0
- else
-  return (Cs((1-P(pattern))^1)+1)^0
- end
 end
 function lpeg.tsplitter(pattern,action)
- if action then
   return Ct((((1-P(pattern))^1)/action+1)^0)
- else
-  return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
 end
 local splitters_s,splitters_m,splitters_t={},{},{}
 local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
-  separator=P(separator)
-  local other=C((1-separator)^0)
-  if single then
-   local any=anything
-   splitter=other*(separator*C(any^0)+"") 
-   splitters_s[separator]=splitter
-  else
-   splitter=other*(separator*other)^0
-   splitters_m[separator]=splitter
+  local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+  if not splitter then
+    separator=P(separator)
+    local other=C((1-separator)^0)
+    if single then
+      local any=anything
+      splitter=other*(separator*C(any^0)+"") 
+      splitters_s[separator]=splitter
+    else
+      splitter=other*(separator*other)^0
+      splitters_m[separator]=splitter
+    end
   end
- end
- return splitter
+  return splitter
 end
 local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
-  splitter=Ct(splitat(separator))
-  splitters_t[separator]=splitter
- end
- return splitter
+  local splitter=splitters_t[separator]
+  if not splitter then
+    splitter=Ct(splitat(separator))
+    splitters_t[separator]=splitter
+  end
+  return splitter
 end
 lpeg.splitat=splitat
 lpeg.tsplitat=tsplitat
 function string.splitup(str,separator)
- if not separator then
-  separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+  if not separator then
+    separator=","
+  end
+  return lpegmatch(splitters_m[separator] or splitat(separator),str)
 end
 local cache={}
 function lpeg.split(separator,str)
- local c=cache[separator]
- if not c then
-  c=tsplitat(separator)
-  cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
   local c=cache[separator]
   if not c then
-   c=tsplitat(separator)
-   cache[separator]=c
+    c=tsplitat(separator)
+    cache[separator]=c
   end
   return lpegmatch(c,str)
- else
-  return { str }
- end
 end
+function string.split(str,separator)
+  if separator then
+    local c=cache[separator]
+    if not c then
+      c=tsplitat(separator)
+      cache[separator]=c
+    end
+    return lpegmatch(c,str)
+  else
+    return { str }
+  end
+end
 local spacing=patterns.spacer^0*newline 
 local empty=spacing*Cc("")
 local nonempty=Cs((1-spacing)^1)*spacing^-1
@@ -1424,276 +1239,334 @@
 local linesplitter=tsplitat(newline)
 patterns.linesplitter=linesplitter
 function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+  return lpegmatch(linesplitter,str)
 end
 local cache={}
 function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
-  separator=P(separator)
-  local other=C((1-separator)^1)
-  c=Ct(separator^0*other*(separator^1*other)^0)
-  cache[separator]=c
- end
- return lpegmatch(c,str)
+  local c=cache[separator]
+  if not c then
+    separator=P(separator)
+    local other=C((1-separator)^1)
+    c=Ct(separator^0*other*(separator^1*other)^0)
+    cache[separator]=c
+  end
+  return lpegmatch(c,str)
 end
 function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
-  separator=P(separator)
-  local other=C((1-separator)^1)
-  c=Ct(separator^0*other*(separator^1*other)^0)
-  cache[separator]=c
- end
- return lpegmatch(c,str)
+  local c=cache[separator]
+  if not c then
+    separator=P(separator)
+    local other=C((1-separator)^1)
+    c=Ct(separator^0*other*(separator^1*other)^0)
+    cache[separator]=c
+  end
+  return lpegmatch(c,str)
 end
-local function f2(s) local c1,c2=byte(s,1,2) return   c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return  (c1*64+c2)*64+c3-925824 end
+local function f2(s) local c1,c2=byte(s,1,2) return  c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
 local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
 local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
 patterns.utf8byte=utf8byte
 local cache={}
 function lpeg.stripper(str)
- if type(str)=="string" then
-  local s=cache[str]
-  if not s then
-   s=Cs(((S(str)^1)/""+1)^0)
-   cache[str]=s
+  if type(str)=="string" then
+    local s=cache[str]
+    if not s then
+      s=Cs(((S(str)^1)/""+1)^0)
+      cache[str]=s
+    end
+    return s
+  else
+    return Cs(((str^1)/""+1)^0)
   end
-  return s
- else
-  return Cs(((str^1)/""+1)^0)
- end
 end
 local cache={}
 function lpeg.keeper(str)
- if type(str)=="string" then
-  local s=cache[str]
-  if not s then
-   s=Cs((((1-S(str))^1)/""+1)^0)
-   cache[str]=s
+  if type(str)=="string" then
+    local s=cache[str]
+    if not s then
+      s=Cs((((1-S(str))^1)/""+1)^0)
+      cache[str]=s
+    end
+    return s
+  else
+    return Cs((((1-str)^1)/""+1)^0)
   end
-  return s
- else
-  return Cs((((1-str)^1)/""+1)^0)
- end
 end
 function lpeg.frontstripper(str) 
- return (P(str)+P(true))*Cs(anything^0)
+  return (P(str)+P(true))*Cs(anything^0)
 end
 function lpeg.endstripper(str) 
- return Cs((1-P(str)*endofstring)^0)
+  return Cs((1-P(str)*endofstring)^0)
 end
 function lpeg.replacer(one,two,makefunction,isutf) 
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
-  local no=#one
-  local p=P(false)
-  if no==0 then
-   for k,v in next,one do
-    p=p+P(k)/v
-   end
-   pattern=Cs((p+u)^0)
-  elseif no==1 then
-   local o=one[1]
-   one,two=P(o[1]),o[2]
-   pattern=Cs((one/two+u)^0)
+  local pattern
+  local u=isutf and utf8char or 1
+  if type(one)=="table" then
+    local no=#one
+    local p=P(false)
+    if no==0 then
+      for k,v in next,one do
+        p=p+P(k)/v
+      end
+      pattern=Cs((p+u)^0)
+    elseif no==1 then
+      local o=one[1]
+      one,two=P(o[1]),o[2]
+      pattern=Cs((one/two+u)^0)
+    else
+      for i=1,no do
+        local o=one[i]
+        p=p+P(o[1])/o[2]
+      end
+      pattern=Cs((p+u)^0)
+    end
   else
-   for i=1,no do
-    local o=one[i]
-    p=p+P(o[1])/o[2]
-   end
-   pattern=Cs((p+u)^0)
+    pattern=Cs((P(one)/(two or "")+u)^0)
   end
- else
-  pattern=Cs((P(one)/(two or "")+u)^0)
- end
- if makefunction then
-  return function(str)
-   return lpegmatch(pattern,str)
+  if makefunction then
+    return function(str)
+      return lpegmatch(pattern,str)
+    end
+  else
+    return pattern
   end
- else
-  return pattern
- end
 end
 function lpeg.finder(lst,makefunction,isutf) 
- local pattern
- if type(lst)=="table" then
-  pattern=P(false)
-  if #lst==0 then
-   for k,v in next,lst do
-    pattern=pattern+P(k) 
-   end
+  local pattern
+  if type(lst)=="table" then
+    pattern=P(false)
+    if #lst==0 then
+      for k,v in next,lst do
+        pattern=pattern+P(k) 
+      end
+    else
+      for i=1,#lst do
+        pattern=pattern+P(lst[i])
+      end
+    end
   else
-   for i=1,#lst do
-    pattern=pattern+P(lst[i])
-   end
+    pattern=P(lst)
   end
- else
-  pattern=P(lst)
- end
- 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)
+  if isutf then
+    pattern=((utf8char or 1)-pattern)^0*pattern
+  else
+    pattern=(1-pattern)^0*pattern
   end
- else
-  return pattern
- end
+  if makefunction then
+    return function(str)
+      return lpegmatch(pattern,str)
+    end
+  else
+    return pattern
+  end
 end
 local splitters_f,splitters_s={},{}
 function lpeg.firstofsplit(separator) 
- local splitter=splitters_f[separator]
- if not splitter then
-  local pattern=P(separator)
-  splitter=C((1-pattern)^0)
-  splitters_f[separator]=splitter
- end
- return splitter
+  local splitter=splitters_f[separator]
+  if not splitter then
+    local pattern=P(separator)
+    splitter=C((1-pattern)^0)
+    splitters_f[separator]=splitter
+  end
+  return splitter
 end
 function lpeg.secondofsplit(separator) 
- local splitter=splitters_s[separator]
- if not splitter then
-  local pattern=P(separator)
-  splitter=(1-pattern)^0*pattern*C(anything^0)
-  splitters_s[separator]=splitter
- end
- return splitter
+  local splitter=splitters_s[separator]
+  if not splitter then
+    local pattern=P(separator)
+    splitter=(1-pattern)^0*pattern*C(anything^0)
+    splitters_s[separator]=splitter
+  end
+  return splitter
 end
 local splitters_s,splitters_p={},{}
 function lpeg.beforesuffix(separator) 
- local splitter=splitters_s[separator]
- if not splitter then
-  local pattern=P(separator)
-  splitter=C((1-pattern)^0)*pattern*endofstring
-  splitters_s[separator]=splitter
- end
- return splitter
+  local splitter=splitters_s[separator]
+  if not splitter then
+    local pattern=P(separator)
+    splitter=C((1-pattern)^0)*pattern*endofstring
+    splitters_s[separator]=splitter
+  end
+  return splitter
 end
 function lpeg.afterprefix(separator) 
- local splitter=splitters_p[separator]
- if not splitter then
-  local pattern=P(separator)
-  splitter=pattern*C(anything^0)
-  splitters_p[separator]=splitter
- end
- return splitter
+  local splitter=splitters_p[separator]
+  if not splitter then
+    local pattern=P(separator)
+    splitter=pattern*C(anything^0)
+    splitters_p[separator]=splitter
+  end
+  return splitter
 end
 function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
+  left,right=P(left),P(right)
+  return P { left*((1-left-right)+V(1))^0*right }
 end
 function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
-  return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
-  return function(str) n=0;lpegmatch(pattern,str);return n end
- end
+  local n=0
+  local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+  if action then
+    return function(str) n=0;lpegmatch(pattern,str);action(n) end
+  else
+    return function(str) n=0;lpegmatch(pattern,str);return n end
+  end
 end
+utf=utf or (unicode and unicode.utf8) or {}
+local utfcharacters=utf and utf.characters or string.utfcharacters
+local utfgmatch=utf and utf.gmatch
+local utfchar=utf and utf.char
+lpeg.UP=lpeg.P
+if utfcharacters then
+  function lpeg.US(str)
+    local p=P(false)
+    for uc in utfcharacters(str) do
+      p=p+P(uc)
+    end
+    return p
+  end
+elseif utfgmatch then
+  function lpeg.US(str)
+    local p=P(false)
+    for uc in utfgmatch(str,".") do
+      p=p+P(uc)
+    end
+    return p
+  end
+else
+  function lpeg.US(str)
+    local p=P(false)
+    local f=function(uc)
+      p=p+P(uc)
+    end
+    lpegmatch((utf8char/f)^0,str)
+    return p
+  end
+end
+local range=utf8byte*utf8byte+Cc(false) 
+function lpeg.UR(str,more)
+  local first,last
+  if type(str)=="number" then
+    first=str
+    last=more or first
+  else
+    first,last=lpegmatch(range,str)
+    if not last then
+      return P(str)
+    end
+  end
+  if first==last then
+    return P(str)
+  elseif utfchar and (last-first<8) then 
+    local p=P(false)
+    for i=first,last do
+      p=p+P(utfchar(i))
+    end
+    return p 
+  else
+    local f=function(b)
+      return b>=first and b<=last
+    end
+    return utf8byte/f 
+  end
+end
 function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
+  return p and lpegtype(p)=="pattern"
 end
 function lpeg.oneof(list,...) 
- if type(list)~="table" then
-  list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
-  p=p+P(list[l])
- end
- return p
+  if type(list)~="table" then
+    list={ list,... }
+  end
+  local p=P(list[1])
+  for l=2,#list do
+    p=p+P(list[l])
+  end
+  return p
 end
 local sort=table.sort
 local function copyindexed(old)
- local new={}
- for i=1,#old do
-  new[i]=old
- end
- return new
+  local new={}
+  for i=1,#old do
+    new[i]=old
+  end
+  return new
 end
 local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
-  s=s+1
-  keys[s]=key
- end
- sort(keys)
- return keys
+  local keys,s={},0
+  for key,_ in next,tab do
+    s=s+1
+    keys[s]=key
+  end
+  sort(keys)
+  return keys
 end
 function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
-  local keys=copyindexed(list)
-  sort(keys)
-  for i=#keys,1,-1 do
-   local k=keys[i]
-   if p then
-    p=P(k)+p
-   else
-    p=P(k)
-   end
-  end
- elseif delayed then 
-  local keys=sortedkeys(list)
-  if p then
-   for i=1,#keys,1 do
-    local k=keys[i]
-    local v=list[k]
-    p=P(k)/list+p
-   end
-  else
-   for i=1,#keys do
-    local k=keys[i]
-    local v=list[k]
+  local p=pp
+  if #list>0 then
+    local keys=copyindexed(list)
+    sort(keys)
+    for i=#keys,1,-1 do
+      local k=keys[i]
+      if p then
+        p=P(k)+p
+      else
+        p=P(k)
+      end
+    end
+  elseif delayed then 
+    local keys=sortedkeys(list)
     if p then
-     p=P(k)+p
+      for i=1,#keys,1 do
+        local k=keys[i]
+        local v=list[k]
+        p=P(k)/list+p
+      end
     else
-     p=P(k)
+      for i=1,#keys do
+        local k=keys[i]
+        local v=list[k]
+        if p then
+          p=P(k)+p
+        else
+          p=P(k)
+        end
+      end
+      if p then
+        p=p/list
+      end
     end
-   end
-   if p then
-    p=p/list
-   end
-  end
- elseif checked then
-  local keys=sortedkeys(list)
-  for i=1,#keys do
-   local k=keys[i]
-   local v=list[k]
-   if p then
-    if k==v then
-     p=P(k)+p
-    else
-     p=P(k)/v+p
+  elseif checked then
+    local keys=sortedkeys(list)
+    for i=1,#keys do
+      local k=keys[i]
+      local v=list[k]
+      if p then
+        if k==v then
+          p=P(k)+p
+        else
+          p=P(k)/v+p
+        end
+      else
+        if k==v then
+          p=P(k)
+        else
+          p=P(k)/v
+        end
+      end
     end
-   else
-    if k==v then
-     p=P(k)
-    else
-     p=P(k)/v
+  else
+    local keys=sortedkeys(list)
+    for i=1,#keys do
+      local k=keys[i]
+      local v=list[k]
+      if p then
+        p=P(k)/v+p
+      else
+        p=P(k)/v
+      end
     end
-   end
   end
- else
-  local keys=sortedkeys(list)
-  for i=1,#keys do
-   local k=keys[i]
-   local v=list[k]
-   if p then
-    p=P(k)/v+p
-   else
-    p=P(k)/v
-   end
-  end
- end
- return p
+  return p
 end
 local p_false=P(false)
 local p_true=P(true)
@@ -1700,187 +1573,171 @@
 local lower=utf and utf.lower or string.lower
 local upper=utf and utf.upper or string.upper
 function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
+  lower=l or lower
+  upper=u or upper
 end
 local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
-  local k=keys[i]
-  if k~="" then
-   local v=t[k]
-   if v==true then
-    p=p+P(k)*p_true
-   elseif v==false then
-   else
-    p=p+P(k)*make1(v,v[""])
-   end
+  local p=p_false
+  local keys=sortedkeys(t)
+  for i=1,#keys do
+    local k=keys[i]
+    if k~="" then
+      local v=t[k]
+      if v==true then
+        p=p+P(k)*p_true
+      elseif v==false then
+      else
+        p=p+P(k)*make1(v,v[""])
+      end
+    end
   end
- end
- if rest then
-  p=p+p_true
- end
- return p
+  if rest then
+    p=p+p_true
+  end
+  return p
 end
 local function make2(t,rest) 
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
-  local k=keys[i]
-  if k~="" then
-   local v=t[k]
-   if v==true then
-    p=p+(P(lower(k))+P(upper(k)))*p_true
-   elseif v==false then
-   else
-    p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
-   end
+  local p=p_false
+  local keys=sortedkeys(t)
+  for i=1,#keys do
+    local k=keys[i]
+    if k~="" then
+      local v=t[k]
+      if v==true then
+        p=p+(P(lower(k))+P(upper(k)))*p_true
+      elseif v==false then
+      else
+        p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+      end
+    end
   end
- end
- if rest then
-  p=p+p_true
- end
- return p
+  if rest then
+    p=p+p_true
+  end
+  return p
 end
-local function utfchartabletopattern(list,insensitive) 
- local tree={}
- local n=#list
- if n==0 then
-  for s in next,list do
-   local t=tree
-   local p,pk
-   for c in gmatch(s,".") do
-    if t==true then
-     t={ [c]=true,[""]=true }
-     p[pk]=t
-     p=t
-     t=false
-    elseif t==false then
-     t={ [c]=false }
-     p[pk]=t
-     p=t
-     t=false
-    else
-     local tc=t[c]
-     if not tc then
-      tc=false
-      t[c]=false
-     end
-     p=t
-     t=tc
+function lpeg.utfchartabletopattern(list,insensitive) 
+  local tree={}
+  local n=#list
+  if n==0 then
+    for s in next,list do
+      local t=tree
+      local p,pk
+      for c in gmatch(s,".") do
+        if t==true then
+          t={ [c]=true,[""]=true }
+          p[pk]=t
+          p=t
+          t=false
+        elseif t==false then
+          t={ [c]=false }
+          p[pk]=t
+          p=t
+          t=false
+        else
+          local tc=t[c]
+          if not tc then
+            tc=false
+            t[c]=false
+          end
+          p=t
+          t=tc
+        end
+        pk=c
+      end
+      if t==false then
+        p[pk]=true
+      elseif t==true then
+      else
+        t[""]=true
+      end
     end
-    pk=c
-   end
-   if t==false then
-    p[pk]=true
-   elseif t==true then
-   else
-    t[""]=true
-   end
-  end
- else
-  for i=1,n do
-   local s=list[i]
-   local t=tree
-   local p,pk
-   for c in gmatch(s,".") do
-    if t==true then
-     t={ [c]=true,[""]=true }
-     p[pk]=t
-     p=t
-     t=false
-    elseif t==false then
-     t={ [c]=false }
-     p[pk]=t
-     p=t
-     t=false
-    else
-     local tc=t[c]
-     if not tc then
-      tc=false
-      t[c]=false
-     end
-     p=t
-     t=tc
+  else
+    for i=1,n do
+      local s=list[i]
+      local t=tree
+      local p,pk
+      for c in gmatch(s,".") do
+        if t==true then
+          t={ [c]=true,[""]=true }
+          p[pk]=t
+          p=t
+          t=false
+        elseif t==false then
+          t={ [c]=false }
+          p[pk]=t
+          p=t
+          t=false
+        else
+          local tc=t[c]
+          if not tc then
+            tc=false
+            t[c]=false
+          end
+          p=t
+          t=tc
+        end
+        pk=c
+      end
+      if t==false then
+        p[pk]=true
+      elseif t==true then
+      else
+        t[""]=true
+      end
     end
-    pk=c
-   end
-   if t==false then
-    p[pk]=true
-   elseif t==true then
-   else
-    t[""]=true
-   end
   end
- end
- return (insensitive and make2 or make1)(tree)
+  return (insensitive and make2 or make1)(tree)
 end
-lpeg.utfchartabletopattern=utfchartabletopattern
-function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
-  return lpegmatch(pattern,str) or str
- end
-end
 patterns.containseol=lpeg.finder(eol)
 local function nextstep(n,step,result)
- local m=n%step   
- local d=floor(n/step) 
- if d>0 then
-  local v=V(tostring(step))
-  local s=result.start
-  for i=1,d do
-   if s then
-    s=v*s
-   else
-    s=v
-   end
+  local m=n%step   
+  local d=floor(n/step) 
+  if d>0 then
+    local v=V(tostring(step))
+    local s=result.start
+    for i=1,d do
+      if s then
+        s=v*s
+      else
+        s=v
+      end
+    end
+    result.start=s
   end
-  result.start=s
- end
- if step>1 and result.start then
-  local v=V(tostring(step/2))
-  result[tostring(step)]=v*v
- end
- if step>0 then
-  return nextstep(m,step/2,result)
- else
-  return result
- end
+  if step>1 and result.start then
+    local v=V(tostring(step/2))
+    result[tostring(step)]=v*v
+  end
+  if step>0 then
+    return nextstep(m,step/2,result)
+  else
+    return result
+  end
 end
 function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+  return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
 end
-do
- local trailingzeros=zero^0*-digit 
- local stripper=Cs((
-  digits*(
-   period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
-  )+1
- )^0)
- lpeg.patterns.stripzeros=stripper 
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
-  period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
-end
+local trailingzeros=zero^0*-digit 
+local case_1=period*trailingzeros/""
+local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"")
+local number=digits*(case_1+case_2)
+local stripper=Cs((number+1)^0)
+lpeg.patterns.stripzeros=stripper
 local byte_to_HEX={}
 local byte_to_hex={}
 local byte_to_dec={} 
 local hex_to_byte={}
 for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
+  local H=format("%02X",i)
+  local h=format("%02x",i)
+  local d=format("%03i",i)
+  local c=char(i)
+  byte_to_HEX[c]=H
+  byte_to_hex[c]=h
+  byte_to_dec[c]=d
+  hex_to_byte[h]=c
+  hex_to_byte[H]=c
 end
 local hextobyte=P(2)/hex_to_byte
 local bytetoHEX=P(1)/byte_to_HEX
@@ -1899,48 +1756,33 @@
 patterns.bytestohex=bytestohex
 patterns.bytestodec=bytestodec
 function string.toHEX(s)
- if not s or s=="" then
-  return s
- else
-  return lpegmatch(bytestoHEX,s)
- end
+  if not s or s=="" then
+    return s
+  else
+    return lpegmatch(bytestoHEX,s)
+  end
 end
 function string.tohex(s)
- if not s or s=="" then
-  return s
- else
-  return lpegmatch(bytestohex,s)
- end
+  if not s or s=="" then
+    return s
+  else
+    return lpegmatch(bytestohex,s)
+  end
 end
 function string.todec(s)
- if not s or s=="" then
-  return s
- else
-  return lpegmatch(bytestodec,s)
- end
+  if not s or s=="" then
+    return s
+  else
+    return lpegmatch(bytestodec,s)
+  end
 end
 function string.tobytes(s)
- if not s or s=="" then
-  return s
- else
-  return lpegmatch(hextobytes,s)
- end
+  if not s or s=="" then
+    return s
+  else
+    return lpegmatch(hextobytes,s)
+  end
 end
-local patterns={} 
-local function containsws(what)
- local p=patterns[what]
- if not p then
-  local p1=P(what)*(whitespace+endofstring)*Cc(true)
-  local p2=whitespace*P(p1)
-  p=P(p1)+P(1-p2)^0*p2+Cc(false)
-  patterns[what]=p
- end
- return p
-end
-lpeg.containsws=containsws
-function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
-end
 
 
 end -- of closure
@@ -1949,14 +1791,14 @@
 
 package.loaded["l-function"] = package.loaded["l-function"] or true
 
--- original size: 361, stripped down to: 317
+-- original size: 361, stripped down to: 322
 
 if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 functions=functions or {}
 function functions.dummy() end
@@ -1968,14 +1810,14 @@
 
 package.loaded["l-string"] = package.loaded["l-string"] or true
 
--- original size: 6461, stripped down to: 3255
+-- original size: 6461, stripped down to: 3341
 
 if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local string=string
 local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -1983,25 +1825,25 @@
 local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
 local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
 function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
+  return lpegmatch(unquoted,str) or str
 end
 function string.quoted(str)
- return format("%q",str) 
+  return format("%q",str) 
 end
 function string.count(str,pattern) 
- local n=0
- for _ in gmatch(str,pattern) do 
-  n=n+1
- end
- return n
+  local n=0
+  for _ in gmatch(str,pattern) do 
+    n=n+1
+  end
+  return n
 end
 function string.limit(str,n,sentinel) 
- if #str>n then
-  sentinel=sentinel or "..."
-  return sub(str,1,(n-#sentinel))..sentinel
- else
-  return str
- end
+  if #str>n then
+    sentinel=sentinel or "..."
+    return sub(str,1,(n-#sentinel))..sentinel
+  else
+    return str
+  end
 end
 local stripper=patterns.stripper
 local fullstripper=patterns.fullstripper
@@ -2009,81 +1851,81 @@
 local nospacer=patterns.nospacer
 local longtostring=patterns.longtostring
 function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
+  return str and lpegmatch(stripper,str) or ""
 end
 function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
+  return str and lpegmatch(fullstripper,str) or ""
 end
 function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
+  return str and lpegmatch(collapser,str) or ""
 end
 function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
+  return str and lpegmatch(nospacer,str) or ""
 end
 function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
+  return str and lpegmatch(longtostring,str) or ""
 end
 local pattern=P(" ")^0*P(-1)
 function string.is_empty(str)
- if not str or str=="" then
-  return true
- else
-  return lpegmatch(pattern,str) and true or false
- end
+  if not str or str=="" then
+    return true
+  else
+    return lpegmatch(pattern,str) and true or false
+  end
 end
 local anything=patterns.anything
 local allescapes=Cc("%")*S(".-+%?()[]*") 
-local someescapes=Cc("%")*S(".-+%()[]")   
-local matchescapes=Cc(".")*S("*?")   
+local someescapes=Cc("%")*S(".-+%()[]")  
+local matchescapes=Cc(".")*S("*?")     
 local pattern_a=Cs ((allescapes+anything )^0 )
 local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
 local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
 function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
+  return lpegmatch(simple and pattern_b or pattern_a,str)
 end
 function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
-  return ".*"
- elseif strict then
-  str=lpegmatch(pattern_c,str)
- else
-  str=lpegmatch(pattern_b,str)
- end
- if lowercase then
-  return lower(str)
- else
-  return str
- end
+  if str=="" or type(str)~="string" then
+    return ".*"
+  elseif strict then
+    str=lpegmatch(pattern_c,str)
+  else
+    str=lpegmatch(pattern_b,str)
+  end
+  if lowercase then
+    return lower(str)
+  else
+    return str
+  end
 end
 function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
+  return (type(str)=="string" and str~="" and str) or default or nil
 end
 string.itself=function(s) return s end
 local pattern_c=Ct(C(1)^0) 
 local pattern_b=Ct((C(1)/byte)^0)
 function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
+  return lpegmatch(bytes and pattern_b or pattern_c,str)
 end
 local replacer=lpeg.replacer("@","%%") 
 function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
+  return format(lpegmatch(replacer,fmt),...)
 end
 string.quote=string.quoted
 string.unquote=string.unquoted
 if not string.bytetable then 
- local limit=5000 
- function string.bytetable(str) 
-  local n=#str
-  if n>limit then
-   local t={ byte(str,1,limit) }
-   for i=limit+1,n do
-    t[i]=byte(str,i)
-   end
-   return t
-  else
-   return { byte(str,1,n) }
+  local limit=5000 
+  function string.bytetable(str) 
+    local n=#str
+    if n>limit then
+      local t={ byte(str,1,limit) }
+      for i=limit+1,n do
+        t[i]=byte(str,i)
+      end
+      return t
+    else
+      return { byte(str,1,n) }
+    end
   end
- end
 end
 
 
@@ -2093,172 +1935,166 @@
 
 package.loaded["l-table"] = package.loaded["l-table"] or true
 
--- original size: 41298, stripped down to: 21498
+-- original size: 40197, stripped down to: 23561
 
 if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
 local table,string=table,string
-local concat,sort=table.concat,table.sort
+local concat,sort,insert,remove=table.concat,table.sort,table.insert,table.remove
 local format,lower,dump=string.format,string.lower,string.dump
 local getmetatable,setmetatable=getmetatable,setmetatable
+local getinfo=debug.getinfo
 local lpegmatch,patterns=lpeg.match,lpeg.patterns
 local floor=math.floor
 local stripper=patterns.stripper
 function table.getn(t)
- return t and #t 
+  return t and #t 
 end
 function table.strip(tab)
- local lst={}
- local l=0
- for i=1,#tab do
-  local s=lpegmatch(stripper,tab[i]) or ""
-  if s=="" then
-  else
-   l=l+1
-   lst[l]=s
+  local lst,l={},0
+  for i=1,#tab do
+    local s=lpegmatch(stripper,tab[i]) or ""
+    if s=="" then
+    else
+      l=l+1
+      lst[l]=s
+    end
   end
- end
- return lst
+  return lst
 end
 function table.keys(t)
- if t then
-  local keys={}
-  local k=0
-  for key in next,t do
-   k=k+1
-   keys[k]=key
+  if t then
+    local keys,k={},0
+    for key in next,t do
+      k=k+1
+      keys[k]=key
+    end
+    return keys
+  else
+    return {}
   end
-  return keys
- else
-  return {}
- end
 end
 local function compare(a,b)
- local ta=type(a) 
- if ta=="number" then
-  local tb=type(b) 
-  if ta==tb then
-   return a<b
-  elseif tb=="string" then
-   return tostring(a)<b
+  local ta=type(a) 
+  if ta=="number" then
+    local tb=type(b) 
+    if ta==tb then
+      return a<b
+    elseif tb=="string" then
+      return tostring(a)<b
+    end
+  elseif ta=="string" then
+    local tb=type(b) 
+    if ta==tb then
+      return a<b
+    else
+      return a<tostring(b)
+    end
   end
- elseif ta=="string" then
-  local tb=type(b) 
-  if ta==tb then
-   return a<b
-  else
-   return a<tostring(b)
-  end
- end
- return tostring(a)<tostring(b) 
+  return tostring(a)<tostring(b) 
 end
 local function sortedkeys(tab)
- if tab then
-  local srt={}
-  local category=0 
-  local s=0
-  for key in next,tab do
-   s=s+1
-   srt[s]=key
-   if category==3 then
-   elseif category==1 then
-    if type(key)~="string" then
-     category=3
+  if tab then
+    local srt,category,s={},0,0 
+    for key in next,tab do
+      s=s+1
+      srt[s]=key
+      if category==3 then
+      elseif category==1 then
+        if type(key)~="string" then
+          category=3
+        end
+      elseif category==2 then
+        if type(key)~="number" then
+          category=3
+        end
+      else
+        local tkey=type(key)
+        if tkey=="string" then
+          category=1
+        elseif tkey=="number" then
+          category=2
+        else
+          category=3
+        end
+      end
     end
-   elseif category==2 then
-    if type(key)~="number" then
-     category=3
-    end
-   else
-    local tkey=type(key)
-    if tkey=="string" then
-     category=1
-    elseif tkey=="number" then
-     category=2
+    if s<2 then
+    elseif category==3 then
+      sort(srt,compare)
     else
-     category=3
+      sort(srt)
     end
-   end
-  end
-  if s<2 then
-  elseif category==3 then
-   sort(srt,compare)
+    return srt
   else
-   sort(srt)
+    return {}
   end
-  return srt
- else
-  return {}
- end
 end
 local function sortedhashonly(tab)
- if tab then
-  local srt={}
-  local s=0
-  for key in next,tab do
-   if type(key)=="string" then
-    s=s+1
-    srt[s]=key
-   end
+  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
+    if s>1 then
+      sort(srt)
+    end
+    return srt
+  else
+    return {}
   end
-  if s>1 then
-   sort(srt)
-  end
-  return srt
- else
-  return {}
- end
 end
 local function sortedindexonly(tab)
- if tab then
-  local srt={}
-  local s=0
-  for key in next,tab do
-   if type(key)=="number" then
-    s=s+1
-    srt[s]=key
-   end
+  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
+    if s>1 then
+      sort(srt)
+    end
+    return srt
+  else
+    return {}
   end
-  if s>1 then
-   sort(srt)
-  end
-  return srt
- else
-  return {}
- end
 end
 local function sortedhashkeys(tab,cmp) 
- if tab then
-  local srt={}
-  local s=0
-  for key in next,tab do
-   if key then
-    s=s+1
-    srt[s]=key
-   end
+  if tab then
+    local srt,s={},0
+    for key in next,tab do
+      if key then
+        s=s+1
+        srt[s]=key
+      end
+    end
+    if s>1 then
+      sort(srt,cmp)
+    end
+    return srt
+  else
+    return {}
   end
-  if s>1 then
-   sort(srt,cmp)
-  end
-  return srt
- else
-  return {}
- end
 end
 function table.allkeys(t)
- local keys={}
- for k,v in next,t do
-  for k in next,v do
-   keys[k]=true
+  local keys={}
+  for k,v in next,t do
+    for k in next,v do
+      keys[k]=true
+    end
   end
- end
- return sortedkeys(keys)
+  return sortedkeys(keys)
 end
 table.sortedkeys=sortedkeys
 table.sortedhashonly=sortedhashonly
@@ -2266,944 +2102,907 @@
 table.sortedhashkeys=sortedhashkeys
 local function nothing() end
 local function sortedhash(t,cmp)
- if t then
-  local s
-  if cmp then
-   s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
-  else
-   s=sortedkeys(t) 
-  end
-  local m=#s
-  if m==1 then
-   return next,t
-  elseif m>0 then
-   local n=0
-   return function()
-    if n<m then
-     n=n+1
-     local k=s[n]
-     return k,t[k]
+  if t then
+    local s
+    if cmp then
+      s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+    else
+      s=sortedkeys(t) 
     end
-   end
+    local m=#s
+    if m==1 then
+      return next,t
+    elseif m>0 then
+      local n=0
+      return function()
+        if n<m then
+          n=n+1
+          local k=s[n]
+          return k,t[k]
+        end
+      end
+    end
   end
- end
- return nothing
+  return nothing
 end
 table.sortedhash=sortedhash
 table.sortedpairs=sortedhash 
 function table.append(t,list)
- local n=#t
- for i=1,#list do
-  n=n+1
-  t[n]=list[i]
- end
- return t
+  local n=#t
+  for i=1,#list do
+    n=n+1
+    t[n]=list[i]
+  end
+  return t
 end
 function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
-  t[nt]=t[i]
-  nt=nt-1
- end
- for i=1,#list do
-  t[i]=list[i]
- end
- return t
+  local nl=#list
+  local nt=nl+#t
+  for i=#t,1,-1 do
+    t[nt]=t[i]
+    nt=nt-1
+  end
+  for i=1,#list do
+    t[i]=list[i]
+  end
+  return t
 end
 function table.merge(t,...) 
- if not t then
-  t={}
- end
- for i=1,select("#",...) do
-  for k,v in next,(select(i,...)) do
-   t[k]=v
+  t=t or {}
+  for i=1,select("#",...) do
+    for k,v in next,(select(i,...)) do
+      t[k]=v
+    end
   end
- end
- return t
+  return t
 end
 function table.merged(...)
- local t={}
- for i=1,select("#",...) do
-  for k,v in next,(select(i,...)) do
-   t[k]=v
+  local t={}
+  for i=1,select("#",...) do
+    for k,v in next,(select(i,...)) do
+      t[k]=v
+    end
   end
- end
- return t
+  return t
 end
 function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
-  local nst=select(i,...)
-  for j=1,#nst do
-   nt=nt+1
-   t[nt]=nst[j]
+  local nt=#t
+  for i=1,select("#",...) do
+    local nst=select(i,...)
+    for j=1,#nst do
+      nt=nt+1
+      t[nt]=nst[j]
+    end
   end
- end
- return t
+  return t
 end
 function table.imerged(...)
- local tmp={}
- local ntmp=0
- for i=1,select("#",...) do
-  local nst=select(i,...)
-  for j=1,#nst do
-   ntmp=ntmp+1
-   tmp[ntmp]=nst[j]
+  local tmp,ntmp={},0
+  for i=1,select("#",...) do
+    local nst=select(i,...)
+    for j=1,#nst do
+      ntmp=ntmp+1
+      tmp[ntmp]=nst[j]
+    end
   end
- end
- return tmp
+  return tmp
 end
 local function fastcopy(old,metatabletoo) 
- if old then
-  local new={}
-  for k,v in next,old do
-   if type(v)=="table" then
-    new[k]=fastcopy(v,metatabletoo) 
-   else
-    new[k]=v
-   end
+  if old then
+    local new={}
+    for k,v in next,old do
+      if type(v)=="table" then
+        new[k]=fastcopy(v,metatabletoo) 
+      else
+        new[k]=v
+      end
+    end
+    if metatabletoo then
+      local mt=getmetatable(old)
+      if mt then
+        setmetatable(new,mt)
+      end
+    end
+    return new
+  else
+    return {}
   end
-  if metatabletoo then
-   local mt=getmetatable(old)
-   if mt then
-    setmetatable(new,mt)
-   end
-  end
-  return new
- else
-  return {}
- end
 end
 local function copy(t,tables) 
- if not tables then
-  tables={}
- end
- local tcopy={}
- if not tables[t] then
-  tables[t]=tcopy
- end
- for i,v in next,t do 
-  if type(i)=="table" then
-   if tables[i] then
-    i=tables[i]
-   else
-    i=copy(i,tables)
-   end
+  tables=tables or {}
+  local tcopy={}
+  if not tables[t] then
+    tables[t]=tcopy
   end
-  if type(v)~="table" then
-   tcopy[i]=v
-  elseif tables[v] then
-   tcopy[i]=tables[v]
-  else
-   tcopy[i]=copy(v,tables)
+  for i,v in next,t do 
+    if type(i)=="table" then
+      if tables[i] then
+        i=tables[i]
+      else
+        i=copy(i,tables)
+      end
+    end
+    if type(v)~="table" then
+      tcopy[i]=v
+    elseif tables[v] then
+      tcopy[i]=tables[v]
+    else
+      tcopy[i]=copy(v,tables)
+    end
   end
- end
- local mt=getmetatable(t)
- if mt then
-  setmetatable(tcopy,mt)
- end
- return tcopy
+  local mt=getmetatable(t)
+  if mt then
+    setmetatable(tcopy,mt)
+  end
+  return tcopy
 end
 table.fastcopy=fastcopy
 table.copy=copy
 function table.derive(parent) 
- local child={}
- if parent then
-  setmetatable(child,{ __index=parent })
- end
- return child
+  local child={}
+  if parent then
+    setmetatable(child,{ __index=parent })
+  end
+  return child
 end
 function table.tohash(t,value)
- local h={}
- if t then
-  if value==nil then value=true end
-  for _,v in next,t do
-   h[v]=value
+  local h={}
+  if t then
+    if value==nil then value=true end
+    for _,v in next,t do
+      h[v]=value
+    end
   end
- end
- return h
+  return h
 end
 function table.fromhash(t)
- local hsh={}
- local h=0
- for k,v in next,t do
-  if v then
-   h=h+1
-   hsh[h]=k
+  local hsh,h={},0
+  for k,v in next,t do
+    if v then
+      h=h+1
+      hsh[h]=k
+    end
   end
- end
- return hsh
+  return hsh
 end
 local noquotes,hexify,handle,compact,inline,functions,metacheck
 local reserved=table.tohash { 
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+  'and','break','do','else','elseif','end','false','for','function','if',
+  'in','local','nil','not','or','repeat','return','then','true','until','while',
+  'NaN','goto',
 }
 local function is_simple_table(t,hexify) 
- local nt=#t
- if nt>0 then
-  local n=0
-  for _,v in next,t do
-   n=n+1
-   if type(v)=="table" then
-    return nil
-   end
-  end
-  local haszero=rawget(t,0) 
-  if n==nt then
-   local tt={}
-   for i=1,nt do
-    local v=t[i]
-    local tv=type(v)
-    if tv=="number" then
-     if hexify then
-      tt[i]=format("0x%X",v)
-     else
-      tt[i]=v 
-     end
-    elseif tv=="string" then
-     tt[i]=format("%q",v) 
-    elseif tv=="boolean" then
-     tt[i]=v and "true" or "false"
-    else
-     return nil
+  local nt=#t
+  if nt>0 then
+    local n=0
+    for _,v in next,t do
+      n=n+1
+      if type(v)=="table" then
+        return nil
+      end
     end
-   end
-   return tt
-  elseif haszero and (n==nt+1) then
-   local tt={}
-   for i=0,nt do
-    local v=t[i]
-    local tv=type(v)
-    if tv=="number" then
-     if hexify then
-      tt[i+1]=format("0x%X",v)
-     else
-      tt[i+1]=v 
-     end
-    elseif tv=="string" then
-     tt[i+1]=format("%q",v) 
-    elseif tv=="boolean" then
-     tt[i+1]=v and "true" or "false"
-    else
-     return nil
+    local haszero=rawget(t,0) 
+    if n==nt then
+      local tt={}
+      for i=1,nt do
+        local v=t[i]
+        local tv=type(v)
+        if tv=="number" then
+          if hexify then
+            tt[i]=format("0x%X",v)
+          else
+            tt[i]=v 
+          end
+        elseif tv=="string" then
+          tt[i]=format("%q",v) 
+        elseif tv=="boolean" then
+          tt[i]=v and "true" or "false"
+        else
+          return nil
+        end
+      end
+      return tt
+    elseif haszero and (n==nt+1) then
+      local tt={}
+      for i=0,nt do
+        local v=t[i]
+        local tv=type(v)
+        if tv=="number" then
+          if hexify then
+            tt[i+1]=format("0x%X",v)
+          else
+            tt[i+1]=v 
+          end
+        elseif tv=="string" then
+          tt[i+1]=format("%q",v) 
+        elseif tv=="boolean" then
+          tt[i+1]=v and "true" or "false"
+        else
+          return nil
+        end
+      end
+      tt[1]="[0] = "..tt[1]
+      return tt
     end
-   end
-   tt[1]="[0] = "..tt[1]
-   return tt
   end
- end
- return nil
+  return nil
 end
 table.is_simple_table=is_simple_table
 local propername=patterns.propername 
 local function dummy() end
 local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
-  depth=depth.." "
-  if indexed then
-   handle(format("%s{",depth))
-  else
-   local tn=type(name)
-   if tn=="number" then
-    if hexify then
-     handle(format("%s[0x%X]={",depth,name))
+  if level>0 then
+    depth=depth.." "
+    if indexed then
+      handle(format("%s{",depth))
     else
-     handle(format("%s[%s]={",depth,name))
+      local tn=type(name)
+      if tn=="number" then
+        if hexify then
+          handle(format("%s[0x%X]={",depth,name))
+        else
+          handle(format("%s[%s]={",depth,name))
+        end
+      elseif tn=="string" then
+        if noquotes and not reserved[name] and lpegmatch(propername,name) then
+          handle(format("%s%s={",depth,name))
+        else
+          handle(format("%s[%q]={",depth,name))
+        end
+      elseif tn=="boolean" then
+        handle(format("%s[%s]={",depth,name and "true" or "false"))
+      else
+        handle(format("%s{",depth))
+      end
     end
-   elseif tn=="string" then
-    if noquotes and not reserved[name] and lpegmatch(propername,name) then
-     handle(format("%s%s={",depth,name))
-    else
-     handle(format("%s[%q]={",depth,name))
-    end
-   elseif tn=="boolean" then
-    handle(format("%s[%s]={",depth,name and "true" or "false"))
-   else
-    handle(format("%s{",depth))
-   end
   end
- end
- if root and next(root)~=nil then
-  local first=nil
-  local last=0
-  if compact then
-   last=#root
-   for k=1,last do
-    if rawget(root,k)==nil then
-     last=k-1
-     break
+  if root and next(root)~=nil then
+    local first,last=nil,0
+    if compact then
+      last=#root
+      for k=1,last do
+        if rawget(root,k)==nil then
+          last=k-1
+          break
+        end
+      end
+      if last>0 then
+        first=1
+      end
     end
-   end
-   if last>0 then
-    first=1
-   end
-  end
-  local sk=sortedkeys(root)
-  for i=1,#sk do
-   local k=sk[i]
-   local v=root[k]
-   local tv=type(v)
-   local tk=type(k)
-   if compact and first and tk=="number" and k>=first and k<=last then
-    if tv=="number" then
-     if hexify then
-      handle(format("%s 0x%X,",depth,v))
-     else
-      handle(format("%s %s,",depth,v)) 
-     end
-    elseif tv=="string" then
-     handle(format("%s %q,",depth,v))
-    elseif tv=="table" then
-     if next(v)==nil then
-      handle(format("%s {},",depth))
-     elseif inline then 
-      local st=is_simple_table(v,hexify)
-      if st then
-       handle(format("%s { %s },",depth,concat(st,", ")))
+    local sk=sortedkeys(root)
+    for i=1,#sk do
+      local k=sk[i]
+      local v=root[k]
+      local tv=type(v)
+      local tk=type(k)
+      if compact and first and tk=="number" and k>=first and k<=last then
+        if tv=="number" then
+          if hexify then
+            handle(format("%s 0x%X,",depth,v))
+          else
+            handle(format("%s %s,",depth,v)) 
+          end
+        elseif tv=="string" then
+          handle(format("%s %q,",depth,v))
+        elseif tv=="table" then
+          if next(v)==nil then
+            handle(format("%s {},",depth))
+          elseif inline then 
+            local st=is_simple_table(v,hexify)
+            if st then
+              handle(format("%s { %s },",depth,concat(st,", ")))
+            else
+              do_serialize(v,k,depth,level+1,true)
+            end
+          else
+            do_serialize(v,k,depth,level+1,true)
+          end
+        elseif tv=="boolean" then
+          handle(format("%s %s,",depth,v and "true" or "false"))
+        elseif tv=="function" then
+          if functions then
+            handle(format('%s load(%q),',depth,dump(v))) 
+          else
+            handle(format('%s "function",',depth))
+          end
+        else
+          handle(format("%s %q,",depth,tostring(v)))
+        end
+      elseif k=="__p__" then 
+        if false then
+          handle(format("%s __p__=nil,",depth))
+        end
+      elseif tv=="number" then
+        if tk=="number" then
+          if hexify then
+            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%X,",depth,k and "true" or "false",v))
+          else
+            handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) 
+          end
+        elseif tk~="string" then
+        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+          if hexify then
+            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%X,",depth,k,v))
+          else
+            handle(format("%s [%q]=%s,",depth,k,v)) 
+          end
+        end
+      elseif tv=="string" then
+        if tk=="number" then
+          if hexify then
+            handle(format("%s [0x%X]=%q,",depth,k,v))
+          else
+            handle(format("%s [%s]=%q,",depth,k,v))
+          end
+        elseif tk=="boolean" then
+          handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+        elseif tk~="string" then
+        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+          handle(format("%s %s=%q,",depth,k,v))
+        else
+          handle(format("%s [%q]=%q,",depth,k,v))
+        end
+      elseif tv=="table" then
+        if next(v)==nil then
+          if tk=="number" then
+            if hexify then
+              handle(format("%s [0x%X]={},",depth,k))
+            else
+              handle(format("%s [%s]={},",depth,k))
+            end
+          elseif tk=="boolean" then
+            handle(format("%s [%s]={},",depth,k and "true" or "false"))
+          elseif tk~="string" then
+          elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+            handle(format("%s %s={},",depth,k))
+          else
+            handle(format("%s [%q]={},",depth,k))
+          end
+        elseif inline then
+          local st=is_simple_table(v,hexify)
+          if st then
+            if tk=="number" then
+              if hexify then
+                handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+              else
+                handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+              end
+            elseif tk=="boolean" then
+              handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+            elseif tk~="string" then
+            elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+              handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+            else
+              handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+            end
+          else
+            do_serialize(v,k,depth,level+1)
+          end
+        else
+          do_serialize(v,k,depth,level+1)
+        end
+      elseif tv=="boolean" then
+        if tk=="number" then
+          if hexify then
+            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
+        elseif tk=="boolean" then
+          handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+        elseif tk~="string" then
+        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+          handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+        else
+          handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+        end
+      elseif tv=="function" then
+        if functions then
+          local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+          if tk=="number" then
+            if hexify then
+              handle(format("%s [0x%X]=load(%q),",depth,k,f))
+            else
+              handle(format("%s [%s]=load(%q),",depth,k,f))
+            end
+          elseif tk=="boolean" then
+            handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+          elseif tk~="string" then
+          elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+            handle(format("%s %s=load(%q),",depth,k,f))
+          else
+            handle(format("%s [%q]=load(%q),",depth,k,f))
+          end
+        end
       else
-       do_serialize(v,k,depth,level+1,true)
+        if tk=="number" then
+          if hexify then
+            handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+          else
+            handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+          end
+        elseif tk=="boolean" then
+          handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+        elseif tk~="string" then
+        elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+          handle(format("%s %s=%q,",depth,k,tostring(v)))
+        else
+          handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+        end
       end
-     else
-      do_serialize(v,k,depth,level+1,true)
-     end
-    elseif tv=="boolean" then
-     handle(format("%s %s,",depth,v and "true" or "false"))
-    elseif tv=="function" then
-     if functions then
-      handle(format('%s load(%q),',depth,dump(v))) 
-     else
-      handle(format('%s "function",',depth))
-     end
-    else
-     handle(format("%s %q,",depth,tostring(v)))
     end
-   elseif k=="__p__" then 
-    if false then
-     handle(format("%s __p__=nil,",depth))
+  end
+  if level>0 then
+    handle(format("%s},",depth))
+  end
+end
+local function serialize(_handle,root,name,specification) 
+  local tname=type(name)
+  if type(specification)=="table" then
+    noquotes=specification.noquotes
+    hexify=specification.hexify
+    handle=_handle or specification.handle or print
+    functions=specification.functions
+    compact=specification.compact
+    inline=specification.inline and compact
+    metacheck=specification.metacheck
+    if functions==nil then
+      functions=true
     end
-   elseif tv=="number" then
-    if tk=="number" then
-     if hexify then
-      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%X,",depth,k and "true" or "false",v))
-     else
-      handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) 
-     end
-    elseif tk~="string" then
-    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-     if hexify then
-      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%X,",depth,k,v))
-     else
-      handle(format("%s [%q]=%s,",depth,k,v)) 
-     end
+    if compact==nil then
+      compact=true
     end
-   elseif tv=="string" then
-    if tk=="number" then
-     if hexify then
-      handle(format("%s [0x%X]=%q,",depth,k,v))
-     else
-      handle(format("%s [%s]=%q,",depth,k,v))
-     end
-    elseif tk=="boolean" then
-     handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
-    elseif tk~="string" then
-    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-     handle(format("%s %s=%q,",depth,k,v))
-    else
-     handle(format("%s [%q]=%q,",depth,k,v))
+    if inline==nil then
+      inline=compact
     end
-   elseif tv=="table" then
-    if next(v)==nil then
-     if tk=="number" then
-      if hexify then
-       handle(format("%s [0x%X]={},",depth,k))
-      else
-       handle(format("%s [%s]={},",depth,k))
-      end
-     elseif tk=="boolean" then
-      handle(format("%s [%s]={},",depth,k and "true" or "false"))
-     elseif tk~="string" then
-     elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-      handle(format("%s %s={},",depth,k))
-     else
-      handle(format("%s [%q]={},",depth,k))
-     end
-    elseif inline then
-     local st=is_simple_table(v,hexify)
-     if st then
-      if tk=="number" then
-       if hexify then
-        handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
-       else
-        handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
-       end
-      elseif tk=="boolean" then
-       handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
-      elseif tk~="string" then
-      elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-       handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
-      else
-       handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
-      end
-     else
-      do_serialize(v,k,depth,level+1)
-     end
+    if metacheck==nil then
+      metacheck=true
+    end
+  else
+    noquotes=false
+    hexify=false
+    handle=_handle or print
+    compact=true
+    inline=true
+    functions=true
+    metacheck=true
+  end
+  if tname=="string" then
+    if name=="return" then
+      handle("return {")
     else
-     do_serialize(v,k,depth,level+1)
+      handle(name.."={")
     end
-   elseif tv=="boolean" then
-    if tk=="number" then
-     if hexify then
-      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
-    elseif tk=="boolean" then
-     handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
-    elseif tk~="string" then
-    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-     handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+  elseif tname=="number" then
+    if hexify then
+      handle(format("[0x%X]={",name))
     else
-     handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+      handle("["..name.."]={")
     end
-   elseif tv=="function" then
-    if functions then
-     local getinfo=debug and debug.getinfo
-     if getinfo then
-      local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
-      if tk=="number" then
-       if hexify then
-        handle(format("%s [0x%X]=load(%q),",depth,k,f))
-       else
-        handle(format("%s [%s]=load(%q),",depth,k,f))
-       end
-      elseif tk=="boolean" then
-       handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
-      elseif tk~="string" then
-      elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-       handle(format("%s %s=load(%q),",depth,k,f))
-      else
-       handle(format("%s [%q]=load(%q),",depth,k,f))
-      end
-     end
-    end
-   else
-    if tk=="number" then
-     if hexify then
-      handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
-     else
-      handle(format("%s [%s]=%q,",depth,k,tostring(v)))
-     end
-    elseif tk=="boolean" then
-     handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
-    elseif tk~="string" then
-    elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
-     handle(format("%s %s=%q,",depth,k,tostring(v)))
+  elseif tname=="boolean" then
+    if name then
+      handle("return {")
     else
-     handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+      handle("{")
     end
-   end
-  end
- end
- if level>0 then
-  handle(format("%s},",depth))
- end
-end
-local function serialize(_handle,root,name,specification) 
- local tname=type(name)
- if type(specification)=="table" then
-  noquotes=specification.noquotes
-  hexify=specification.hexify
-  handle=_handle or specification.handle or print
-  functions=specification.functions
-  compact=specification.compact
-  inline=specification.inline and compact
-  metacheck=specification.metacheck
-  if functions==nil then
-   functions=true
-  end
-  if compact==nil then
-   compact=true
-  end
-  if inline==nil then
-   inline=compact
-  end
-  if metacheck==nil then
-   metacheck=true
-  end
- else
-  noquotes=false
-  hexify=false
-  handle=_handle or print
-  compact=true
-  inline=true
-  functions=true
-  metacheck=true
- end
- if tname=="string" then
-  if name=="return" then
-   handle("return {")
   else
-   handle(name.."={")
+    handle("t={")
   end
- elseif tname=="number" then
-  if hexify then
-   handle(format("[0x%X]={",name))
-  else
-   handle("["..name.."]={")
+  if root then
+    if metacheck and getmetatable(root) then
+      local dummy=root._w_h_a_t_e_v_e_r_
+      root._w_h_a_t_e_v_e_r_=nil
+    end
+    if next(root)~=nil then
+      do_serialize(root,name,"",0)
+    end
   end
- elseif tname=="boolean" then
-  if name then
-   handle("return {")
-  else
-   handle("{")
-  end
- else
-  handle("t={")
- end
- if root then
-  if metacheck and getmetatable(root) then
-   local dummy=root._w_h_a_t_e_v_e_r_
-   root._w_h_a_t_e_v_e_r_=nil
-  end
-  if next(root)~=nil then
-   do_serialize(root,name,"",0)
-  end
- end
- handle("}")
+  handle("}")
 end
 function table.serialize(root,name,specification)
- local t={}
- local n=0
- local function flush(s)
-  n=n+1
-  t[n]=s
- end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+  local t,n={},0
+  local function flush(s)
+    n=n+1
+    t[n]=s
+  end
+  serialize(flush,root,name,specification)
+  return concat(t,"\n")
 end
 table.tohandle=serialize
 local maxtab=2*1024
 function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
-  if maxtab>1 then
-   local t={}
-   local n=0
-   local function flush(s)
-    n=n+1
-    t[n]=s
-    if n>maxtab then
-     f:write(concat(t,"\n"),"\n") 
-     t={} 
-     n=0
+  local f=io.open(filename,'w')
+  if f then
+    if maxtab>1 then
+      local t,n={},0
+      local function flush(s)
+        n=n+1
+        t[n]=s
+        if n>maxtab then
+          f:write(concat(t,"\n"),"\n") 
+          t,n={},0 
+        end
+      end
+      serialize(flush,root,name,specification)
+      f:write(concat(t,"\n"),"\n")
+    else
+      local function flush(s)
+        f:write(s,"\n")
+      end
+      serialize(flush,root,name,specification)
     end
-   end
-   serialize(flush,root,name,specification)
-   f:write(concat(t,"\n"),"\n")
-  else
-   local function flush(s)
-    f:write(s,"\n")
-   end
-   serialize(flush,root,name,specification)
+    f:close()
+    io.flush()
   end
-  f:close()
-  io.flush()
- end
 end
 local function flattened(t,f,depth) 
- if f==nil then
-  f={}
-  depth=0xFFFF
- elseif tonumber(f) then
-  depth=f
-  f={}
- elseif not depth then
-  depth=0xFFFF
- end
- for k,v in next,t do
-  if type(k)~="number" then
-   if depth>0 and type(v)=="table" then
-    flattened(v,f,depth-1)
-   else
-    f[#f+1]=v
-   end
+  if f==nil then
+    f={}
+    depth=0xFFFF
+  elseif tonumber(f) then
+    depth=f
+    f={}
+  elseif not depth then
+    depth=0xFFFF
   end
- end
- for k=1,#t do
-  local v=t[k]
-  if depth>0 and type(v)=="table" then
-   flattened(v,f,depth-1)
-  else
-   f[#f+1]=v
+  for k,v in next,t do
+    if type(k)~="number" then
+      if depth>0 and type(v)=="table" then
+        flattened(v,f,depth-1)
+      else
+        f[#f+1]=v
+      end
+    end
   end
- end
- return f
+  for k=1,#t do
+    local v=t[k]
+    if depth>0 and type(v)=="table" then
+      flattened(v,f,depth-1)
+    else
+      f[#f+1]=v
+    end
+  end
+  return f
 end
 table.flattened=flattened
 local function collapsed(t,f,h)
- if f==nil then
-  f={}
-  h={}
- end
- for k=1,#t do
-  local v=t[k]
-  if type(v)=="table" then
-   collapsed(v,f,h)
-  elseif not h[v] then
-   f[#f+1]=v
-   h[v]=true
+  if f==nil then
+    f={}
+    h={}
   end
- end
- return f
+  for k=1,#t do
+    local v=t[k]
+    if type(v)=="table" then
+      collapsed(v,f,h)
+    elseif not h[v] then
+      f[#f+1]=v
+      h[v]=true
+    end
+  end
+  return f
 end
 local function collapsedhash(t,h)
- if h==nil then
-  h={}
- end
- for k=1,#t do
-  local v=t[k]
-  if type(v)=="table" then
-   collapsedhash(v,h)
-  else
-   h[v]=true
+  if h==nil then
+    h={}
   end
- end
- return h
+  for k=1,#t do
+    local v=t[k]
+    if type(v)=="table" then
+      collapsedhash(v,h)
+    else
+      h[v]=true
+    end
+  end
+  return h
 end
-table.collapsed=collapsed  
+table.collapsed=collapsed   
 table.collapsedhash=collapsedhash
 local function unnest(t,f) 
- if not f then    
-  f={}   
- end
- for i=1,#t do
-  local v=t[i]
-  if type(v)=="table" then
-   if type(v[1])=="table" then
-    unnest(v,f)
-   else
-    f[#f+1]=v
-   end
-  else
-   f[#f+1]=v
+  if not f then     
+    f={}      
   end
- end
- return f
+  for i=1,#t do
+    local v=t[i]
+    if type(v)=="table" then
+      if type(v[1])=="table" then
+        unnest(v,f)
+      else
+        f[#f+1]=v
+      end
+    else
+      f[#f+1]=v
+    end
+  end
+  return f
 end
 function table.unnest(t) 
- return unnest(t)
+  return unnest(t)
 end
 local function are_equal(a,b,n,m) 
- if a==b then
-  return true
- elseif a and b and #a==#b then
-  if not n then
-   n=1
-  end
-  if not m then
-   m=#a
-  end
-  for i=n,m do
-   local ai,bi=a[i],b[i]
-   if ai==bi then
-   elseif type(ai)=="table" and type(bi)=="table" then
-    if not are_equal(ai,bi) then
-     return false
+  if a==b then
+    return true
+  elseif a and b and #a==#b then
+    n=n or 1
+    m=m or #a
+    for i=n,m do
+      local ai,bi=a[i],b[i]
+      if ai==bi then
+      elseif type(ai)=="table" and type(bi)=="table" then
+        if not are_equal(ai,bi) then
+          return false
+        end
+      else
+        return false
+      end
     end
-   else
+    return true
+  else
     return false
-   end
   end
-  return true
- else
-  return false
- end
 end
 local function identical(a,b) 
- if a~=b then
-  for ka,va in next,a do
-   local vb=b[ka]
-   if va==vb then
-   elseif type(va)=="table" and  type(vb)=="table" then
-    if not identical(va,vb) then
-     return false
+  if a~=b then
+    for ka,va in next,a do
+      local vb=b[ka]
+      if va==vb then
+      elseif type(va)=="table" and type(vb)=="table" then
+        if not identical(va,vb) then
+          return false
+        end
+      else
+        return false
+      end
     end
-   else
-    return false
-   end
   end
- end
- return true
+  return true
 end
 table.identical=identical
 table.are_equal=are_equal
 local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
-  if not (v=="" or v==false) then
-   if nest and type(v)=="table" then
-    v=sparse(v,nest)
-    if keeptables or next(v)~=nil then
-     new[k]=v
+  local new={}
+  for k,v in next,old do
+    if not (v=="" or v==false) then
+      if nest and type(v)=="table" then
+        v=sparse(v,nest)
+        if keeptables or next(v)~=nil then
+          new[k]=v
+        end
+      else
+        new[k]=v
+      end
     end
-   else
-    new[k]=v
-   end
   end
- end
- return new
+  return new
 end
 table.sparse=sparse
 function table.compact(t)
- return sparse(t,true,true)
+  return sparse(t,true,true)
 end
 function table.contains(t,v)
- if t then
-  for i=1,#t do
-   if t[i]==v then
-    return i
-   end
+  if t then
+    for i=1,#t do
+      if t[i]==v then
+        return i
+      end
+    end
   end
- end
- return false
+  return false
 end
 function table.count(t)
- local n=0
- for k,v in next,t do
-  n=n+1
- end
- return n
+  local n=0
+  for k,v in next,t do
+    n=n+1
+  end
+  return n
 end
 function table.swapped(t,s) 
- local n={}
- if s then
-  for k,v in next,s do
-   n[k]=v
+  local n={}
+  if s then
+    for k,v in next,s do
+      n[k]=v
+    end
   end
- end
- for k,v in next,t do
-  n[v]=k
- end
- return n
+  for k,v in next,t do
+    n[v]=k
+  end
+  return n
 end
 function table.hashed(t) 
- for i=1,#t do
-  t[t[i]]=i
- end
- return t
+  for i=1,#t do
+    t[t[i]]=i
+  end
+  return t
 end
 function table.mirrored(t) 
- local n={}
- for k,v in next,t do
-  n[v]=k
-  n[k]=v
- end
- return n
+  local n={}
+  for k,v in next,t do
+    n[v]=k
+    n[k]=v
+  end
+  return n
 end
 function table.reversed(t)
- if t then
-  local tt={}
-  local tn=#t
-  if tn>0 then
-   local ttn=0
-   for i=tn,1,-1 do
-    ttn=ttn+1
-    tt[ttn]=t[i]
-   end
+  if t then
+    local tt,tn={},#t
+    if tn>0 then
+      local ttn=0
+      for i=tn,1,-1 do
+        ttn=ttn+1
+        tt[ttn]=t[i]
+      end
+    end
+    return tt
   end
-  return tt
- end
 end
 function table.reverse(t) 
- if t then
-  local n=#t
-  local m=n+1
-  for i=1,floor(n/2) do 
-   local j=m-i
-   t[i],t[j]=t[j],t[i]
+  if t then
+    local n=#t
+    for i=1,floor(n/2) do 
+      local j=n-i+1
+      t[i],t[j]=t[j],t[i]
+    end
+    return t
   end
-  return t
- end
 end
-local function sequenced(t,sep,simple)
- if not t then
-  return ""
- elseif type(t)=="string" then
-  return t 
- end
- local n=#t
- local s={}
- if n>0 then
-  for i=1,n do
-   local v=t[i]
-   if type(v)=="table" then
-    s[i]="{"..sequenced(v,sep,simple).."}"
-   else
-    s[i]=tostring(t[i])
-   end
+function table.sequenced(t,sep,simple) 
+  if not t then
+    return ""
   end
- else
-  n=0
-  for k,v in sortedhash(t) do
-   if simple then
-    if v==true then
-     n=n+1
-     s[n]=k
-    elseif v and v~="" then
-     n=n+1
-     if type(v)=="table" then
-      s[n]=k.."={"..sequenced(v,sep,simple).."}"
-     else
-      s[n]=k.."="..tostring(v)
-     end
+  local n=#t
+  local s={}
+  if n>0 then
+    for i=1,n do
+      s[i]=tostring(t[i])
     end
-   else
-    n=n+1
-    if type(v)=="table" then
-     s[n]=k.."={"..sequenced(v,sep,simple).."}"
-    else
-     s[n]=k.."="..tostring(v)
+  else
+    n=0
+    for k,v in sortedhash(t) do
+      if simple then
+        if v==true then
+          n=n+1
+          s[n]=k
+        elseif v and v~="" then
+          n=n+1
+          s[n]=k.."="..tostring(v)
+        end
+      else
+        n=n+1
+        s[n]=k.."="..tostring(v)
+      end
     end
-   end
   end
- end
- return concat(s,sep or " | ")
+  return concat(s,sep or " | ")
 end
-table.sequenced=sequenced
 function table.print(t,...)
- if type(t)~="table" then
-  print(tostring(t))
- else
-  serialize(print,t,...)
- end
+  if type(t)~="table" then
+    print(tostring(t))
+  else
+    serialize(print,t,...)
+  end
 end
 if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+  setinspector("table",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) }
+  return { unpack(t,i,j) }
 end
 function table.is_empty(t)
- return not t or next(t)==nil
+  return not t or next(t)==nil
 end
 function table.has_one_entry(t)
- return t and next(t,next(t))==nil
+  return t and next(t,next(t))==nil
 end
 function table.loweredkeys(t) 
- local l={}
- for k,v in next,t do
-  l[lower(k)]=v
- end
- return l
+  local l={}
+  for k,v in next,t do
+    l[lower(k)]=v
+  end
+  return l
 end
 function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
-  local oi=old[i]
-  if not hash[oi] then
-   n=n+1
-   new[n]=oi
-   hash[oi]=true
+  local hash={}
+  local new={}
+  local n=0
+  for i=1,#old do
+    local oi=old[i]
+    if not hash[oi] then
+      n=n+1
+      new[n]=oi
+      hash[oi]=true
+    end
   end
- end
- return new
+  return new
 end
 function table.sorted(t,...)
- sort(t,...)
- return t 
+  sort(t,...)
+  return t 
 end
 function table.values(t,s) 
- if t then
-  local values={}
-  local keys={}
-  local v=0
-  for key,value in next,t do
-   if not keys[value] then
-    v=v+1
-    values[v]=value
-    keys[k]=key
-   end
+  if t then
+    local values,keys,v={},{},0
+    for key,value in next,t do
+      if not keys[value] then
+        v=v+1
+        values[v]=value
+        keys[k]=key
+      end
+    end
+    if s then
+      sort(values)
+    end
+    return values
+  else
+    return {}
   end
-  if s then
-   sort(values)
-  end
-  return values
- else
-  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<m do
-     n=n+1
-     local k=s[n]
-     if find(k,pattern) then
-      return k,t[k]
-     end
+  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<m do
+          n=n+1
+          local k=s[n]
+          if find(k,pattern) then
+            return k,t[k]
+          end
+        end
+      end
+      return kv,s
+    else
+      local n=next(t)
+      local function iterator()
+        while n~=nil do
+          local k=n
+          n=next(t,k)
+          if find(k,pattern) then
+            return k,t[k]
+          end
+        end
+      end
+      return iterator,t
     end
-   end
-   return kv,s
   else
-   local n=next(t)
-   local function iterator()
-    while n~=nil do
-     local k=n
-     n=next(t,k)
-     if find(k,pattern) then
-      return k,t[k]
-     end
-    end
-   end
-   return iterator,t
+    return nothing
   end
- else
-  return nothing
- end
 end
 if not table.move then
- function table.move(a1,f,e,t,a2)
-  if a2 and a1~=a2 then
-   for i=f,e do
-    a2[t]=a1[i]
-    t=t+1
-   end
-   return a2
-  else
-   t=t+e-f
-   for i=e,f,-1 do
-    a1[t]=a1[i]
-    t=t-1
-   end
-   return a1
+  function table.move(a1,f,e,t,a2)
+    if a2 and a1~=a2 then
+      for i=f,e do
+        a2[t]=a1[i]
+        t=t+1
+      end
+      return a2
+    else
+      t=t+e-f
+      for i=e,f,-1 do
+        a1[t]=a1[i]
+        t=t-1
+      end
+      return a1
+    end
   end
- end
 end
 
 
@@ -3213,14 +3012,14 @@
 
 package.loaded["l-io"] = package.loaded["l-io"] or true
 
--- original size: 11823, stripped down to: 6325
+-- original size: 11823, stripped down to: 6945
 
 if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local io=io
 local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3228,334 +3027,334 @@
 local concat=table.concat
 local type=type
 if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+  io.fileseparator,io.pathseparator="\\",";"
 else
- io.fileseparator,io.pathseparator="/",":"
+  io.fileseparator,io.pathseparator="/",":"
 end
 local large=0x01000000 
 local medium=0x00100000 
 local small=0x00020000
 local function readall(f)
- local size=f:seek("end")
- if size>0 then
-  f:seek("set",0)
-  return f:read(size)
- else
-  return ""
- end
+  local size=f:seek("end")
+  if size>0 then
+    f:seek("set",0)
+    return f:read(size)
+  else
+    return ""
+  end
 end
 io.readall=readall
 function io.loaddata(filename,textmode) 
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
-  local size=f:seek("end")
-  local data=nil
-  if size>0 then
-   f:seek("set",0)
-   data=f:read(size)
+  local f=open(filename,(textmode and 'r') or 'rb')
+  if f then
+    local size=f:seek("end")
+    local data=nil
+    if size>0 then
+      f:seek("set",0)
+      data=f:read(size)
+    end
+    f:close()
+    return data
   end
-  f:close()
-  return data
- end
 end
 function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
-  local g=open(target,"wb")
-  if g then
-   local size=f:seek("end")
-   if size>0 then
-    f:seek("set",0)
-    local data=f:read(size)
-    if action then
-     data=action(data)
+  local f=open(source,"rb")
+  if f then
+    local g=open(target,"wb")
+    if g then
+      local size=f:seek("end")
+      if size>0 then
+        f:seek("set",0)
+        local data=f:read(size)
+        if action then
+          data=action(data)
+        end
+        if data then
+          g:write(data)
+        end
+      end
+      g:close()
     end
-    if data then
-     g:write(data)
-    end
-   end
-   g:close()
+    f:close()
+    flush()
   end
-  f:close()
-  flush()
- end
 end
 function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
-  if type(data)=="table" then
-   f:write(concat(data,joiner or ""))
-  elseif type(data)=="function" then
-   data(f)
+  local f=open(filename,"wb")
+  if f then
+    if type(data)=="table" then
+      f:write(concat(data,joiner or ""))
+    elseif type(data)=="function" then
+      data(f)
+    else
+      f:write(data or "")
+    end
+    f:close()
+    flush()
+    return true
   else
-   f:write(data or "")
+    return false
   end
-  f:close()
-  flush()
-  return true
- else
-  return false
- end
 end
 if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n) 
-  local f=open(filename,'r')
-  if not f then
-  elseif n then
-   local lines={}
-   for i=1,n do
-    local line=readline(f)
-    if line then
-     lines[i]=line
+  local readline=fio.readline
+  function io.loadlines(filename,n) 
+    local f=open(filename,'r')
+    if not f then
+    elseif n then
+      local lines={}
+      for i=1,n do
+        local line=readline(f)
+        if line then
+          lines[i]=line
+        else
+          break
+        end
+      end
+      f:close()
+      lines=concat(lines,"\n")
+      if #lines>0 then
+        return lines
+      end
     else
-     break
+      local line=readline(f)
+      f:close()
+      if line and #line>0 then
+        return line
+      end
     end
-   end
-   f:close()
-   lines=concat(lines,"\n")
-   if #lines>0 then
-    return lines
-   end
-  else
-   local line=readline(f)
-   f:close()
-   if line and #line>0 then
-    return line
-   end
   end
- end
 else
- function io.loadlines(filename,n) 
-  local f=open(filename,'r')
-  if not f then
-  elseif n then
-   local lines={}
-   for i=1,n do
-    local line=f:read("*lines")
-    if line then
-     lines[i]=line
+  function io.loadlines(filename,n) 
+    local f=open(filename,'r')
+    if not f then
+    elseif n then
+      local lines={}
+      for i=1,n do
+        local line=f:read("*lines")
+        if line then
+          lines[i]=line
+        else
+          break
+        end
+      end
+      f:close()
+      lines=concat(lines,"\n")
+      if #lines>0 then
+        return lines
+      end
     else
-     break
+      local line=f:read("*line") or ""
+      f:close()
+      if #line>0 then
+        return line
+      end
     end
-   end
-   f:close()
-   lines=concat(lines,"\n")
-   if #lines>0 then
-    return lines
-   end
-  else
-   local line=f:read("*line") or ""
-   f:close()
-   if #line>0 then
-    return line
-   end
   end
- end
 end
 function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
-  local data=f:read(n or 1024)
-  f:close()
-  if #data>0 then
-   return data
+  local f=open(filename,'rb')
+  if f then
+    local data=f:read(n or 1024)
+    f:close()
+    if #data>0 then
+      return data
+    end
   end
- end
 end
 function io.exists(filename)
- local f=open(filename)
- if f==nil then
-  return false
- else
-  f:close()
-  return true
- end
+  local f=open(filename)
+  if f==nil then
+    return false
+  else
+    f:close()
+    return true
+  end
 end
 function io.size(filename)
- local f=open(filename)
- if f==nil then
-  return 0
- else
-  local s=f:seek("end")
-  f:close()
-  return s
- end
+  local f=open(filename)
+  if f==nil then
+    return 0
+  else
+    local s=f:seek("end")
+    f:close()
+    return s
+  end
 end
 local function noflines(f)
- if type(f)=="string" then
-  local f=open(filename)
-  if f then
-   local n=f and noflines(f) or 0
-   f:close()
-   return n
+  if type(f)=="string" then
+    local f=open(filename)
+    if f then
+      local n=f and noflines(f) or 0
+      f:close()
+      return n
+    else
+      return 0
+    end
   else
-   return 0
+    local n=0
+    for _ in f:lines() do
+      n=n+1
+    end
+    f:seek('set',0)
+    return n
   end
- else
-  local n=0
-  for _ in f:lines() do
-   n=n+1
-  end
-  f:seek('set',0)
-  return n
- end
 end
 io.noflines=noflines
 local nextchar={
- [ 4]=function(f)
-  return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
-  return f:read(1,1)
- end,
- [ 1]=function(f)
-  return f:read(1)
- end,
- [-2]=function(f)
-  local a,b=f:read(1,1)
-  return b,a
- end,
- [-4]=function(f)
-  local a,b,c,d=f:read(1,1,1,1)
-  return d,c,b,a
- end
+  [ 4]=function(f)
+    return f:read(1,1,1,1)
+  end,
+  [ 2]=function(f)
+    return f:read(1,1)
+  end,
+  [ 1]=function(f)
+    return f:read(1)
+  end,
+  [-2]=function(f)
+    local a,b=f:read(1,1)
+    return b,a
+  end,
+  [-4]=function(f)
+    local a,b,c,d=f:read(1,1,1,1)
+    return d,c,b,a
+  end
 }
 function io.characters(f,n)
- if f then
-  return nextchar[n or 1],f
- end
+  if f then
+    return nextchar[n or 1],f
+  end
 end
 local nextbyte={
- [4]=function(f)
-  local a,b,c,d=f:read(1,1,1,1)
-  if d then
-   return byte(a),byte(b),byte(c),byte(d)
+  [4]=function(f)
+    local a,b,c,d=f:read(1,1,1,1)
+    if d then
+      return byte(a),byte(b),byte(c),byte(d)
+    end
+  end,
+  [3]=function(f)
+    local a,b,c=f:read(1,1,1)
+    if b then
+      return byte(a),byte(b),byte(c)
+    end
+  end,
+  [2]=function(f)
+    local a,b=f:read(1,1)
+    if b then
+      return byte(a),byte(b)
+    end
+  end,
+  [1]=function (f)
+    local a=f:read(1)
+    if a then
+      return byte(a)
+    end
+  end,
+  [-2]=function (f)
+    local a,b=f:read(1,1)
+    if b then
+      return byte(b),byte(a)
+    end
+  end,
+  [-3]=function(f)
+    local a,b,c=f:read(1,1,1)
+    if b then
+      return byte(c),byte(b),byte(a)
+    end
+  end,
+  [-4]=function(f)
+    local a,b,c,d=f:read(1,1,1,1)
+    if d then
+      return byte(d),byte(c),byte(b),byte(a)
+    end
   end
- end,
- [3]=function(f)
-  local a,b,c=f:read(1,1,1)
-  if b then
-   return byte(a),byte(b),byte(c)
-  end
- end,
- [2]=function(f)
-  local a,b=f:read(1,1)
-  if b then
-   return byte(a),byte(b)
-  end
- end,
- [1]=function (f)
-  local a=f:read(1)
-  if a then
-   return byte(a)
-  end
- end,
- [-2]=function (f)
-  local a,b=f:read(1,1)
-  if b then
-   return byte(b),byte(a)
-  end
- end,
- [-3]=function(f)
-  local a,b,c=f:read(1,1,1)
-  if b then
-   return byte(c),byte(b),byte(a)
-  end
- end,
- [-4]=function(f)
-  local a,b,c,d=f:read(1,1,1,1)
-  if d then
-   return byte(d),byte(c),byte(b),byte(a)
-  end
- end
 }
 function io.bytes(f,n)
- if f then
-  return nextbyte[n or 1],f
- else
-  return nil,nil
- end
+  if f then
+    return nextbyte[n or 1],f
+  else
+    return nil,nil
+  end
 end
 function io.ask(question,default,options)
- while true do
-  write(question)
-  if options then
-   write(format(" [%s]",concat(options,"|")))
-  end
-  if default then
-   write(format(" [%s]",default))
-  end
-  write(format(" "))
-  flush()
-  local answer=read()
-  answer=gsub(answer,"^%s*(.*)%s*$","%1")
-  if answer=="" and default then
-   return default
-  elseif not options then
-   return answer
-  else
-   for k=1,#options do
-    if options[k]==answer then
-     return answer
+  while true do
+    write(question)
+    if options then
+      write(format(" [%s]",concat(options,"|")))
     end
-   end
-   local pattern="^"..answer
-   for k=1,#options do
-    local v=options[k]
-    if find(v,pattern) then
-     return v
+    if default then
+      write(format(" [%s]",default))
     end
-   end
+    write(format(" "))
+    flush()
+    local answer=read()
+    answer=gsub(answer,"^%s*(.*)%s*$","%1")
+    if answer=="" and default then
+      return default
+    elseif not options then
+      return answer
+    else
+      for k=1,#options do
+        if options[k]==answer then
+          return answer
+        end
+      end
+      local pattern="^"..answer
+      for k=1,#options do
+        local v=options[k]
+        if find(v,pattern) then
+          return v
+        end
+      end
+    end
   end
- end
 end
 local function readnumber(f,n,m) 
- if m then
-  f:seek("set",n)
-  n=m
- end
- if n==1 then
-  return byte(f:read(1))
- elseif n==2 then
-  local a,b=byte(f:read(2),1,2)
-  return 0x100*a+b
- elseif n==3 then
-  local a,b,c=byte(f:read(3),1,3)
-  return 0x10000*a+0x100*b+c
- elseif n==4 then
-  local a,b,c,d=byte(f:read(4),1,4)
-  return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
-  local a,b=readnumber(f,4),readnumber(f,4)
-  return 0x100*a+b
- elseif n==12 then
-  local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
-  return 0x10000*a+0x100*b+c
- elseif n==-2 then
-  local b,a=byte(f:read(2),1,2)
-  return 0x100*a+b
- elseif n==-3 then
-  local c,b,a=byte(f:read(3),1,3)
-  return 0x10000*a+0x100*b+c
- elseif n==-4 then
-  local d,c,b,a=byte(f:read(4),1,4)
-  return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
-  local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
-  return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
-  return 0
- end
+  if m then
+    f:seek("set",n)
+    n=m
+  end
+  if n==1 then
+    return byte(f:read(1))
+  elseif n==2 then
+    local a,b=byte(f:read(2),1,2)
+    return 0x100*a+b
+  elseif n==3 then
+    local a,b,c=byte(f:read(3),1,3)
+    return 0x10000*a+0x100*b+c
+  elseif n==4 then
+    local a,b,c,d=byte(f:read(4),1,4)
+    return 0x1000000*a+0x10000*b+0x100*c+d
+  elseif n==8 then
+    local a,b=readnumber(f,4),readnumber(f,4)
+    return 0x100*a+b
+  elseif n==12 then
+    local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+    return 0x10000*a+0x100*b+c
+  elseif n==-2 then
+    local b,a=byte(f:read(2),1,2)
+    return 0x100*a+b
+  elseif n==-3 then
+    local c,b,a=byte(f:read(3),1,3)
+    return 0x10000*a+0x100*b+c
+  elseif n==-4 then
+    local d,c,b,a=byte(f:read(4),1,4)
+    return 0x1000000*a+0x10000*b+0x100*c+d
+  elseif n==-8 then
+    local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+    return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+  else
+    return 0
+  end
 end
 io.readnumber=readnumber
 function io.readstring(f,n,m)
- if m then
-  f:seek("set",n)
-  n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
+  if m then
+    f:seek("set",n)
+    n=m
+  end
+  local str=gsub(f:read(n),"\000","")
+  return str
 end
 
 
@@ -3565,14 +3364,14 @@
 
 package.loaded["l-number"] = package.loaded["l-number"] or true
 
--- original size: 5720, stripped down to: 2176
+-- original size: 5645, stripped down to: 2253
 
 if not modules then modules={} end modules ['l-number']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local tostring,tonumber=tostring,tonumber
 local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3582,108 +3381,100 @@
 number=number or {}
 local number=number
 if bit32 then
- local bextract=bit32.extract
- local t={
-  "0","0","0","0","0","0","0","0",
-  "0","0","0","0","0","0","0","0",
-  "0","0","0","0","0","0","0","0",
-  "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m,w)
-  if not w then
-   w=32
+  local bextract=bit32.extract
+  local t={
+    "0","0","0","0","0","0","0","0",
+    "0","0","0","0","0","0","0","0",
+    "0","0","0","0","0","0","0","0",
+    "0","0","0","0","0","0","0","0",
+  }
+  function number.tobitstring(b,m)
+    local n=32
+    for i=0,31 do
+      local v=bextract(b,i)
+      local k=32-i
+      if v==1 then
+        n=k
+        t[k]="1"
+      else
+        t[k]="0"
+      end
+    end
+    if m then
+      m=33-m*8
+      if m<1 then
+        m=1
+      end
+      return concat(t,"",m)
+    elseif n<8 then
+      return concat(t)
+    elseif n<16 then
+      return concat(t,"",9)
+    elseif n<24 then
+      return concat(t,"",17)
+    else
+      return concat(t,"",25)
+    end
   end
-  local n=w
-  for i=0,w-1 do
-   local v=bextract(b,i)
-   local k=w-i
-   if v==1 then
-    n=k
-    t[k]="1"
-   else
-    t[k]="0"
-   end
-  end
-  if w then
-   return concat(t,"",1,w)
-  elseif m then
-   m=33-m*8
-   if m<1 then
-    m=1
-   end
-   return concat(t,"",1,m)
-  elseif n<8 then
-   return concat(t)
-  elseif n<16 then
-   return concat(t,"",9)
-  elseif n<24 then
-   return concat(t,"",17)
-  else
-   return concat(t,"",25)
-  end
- end
 else
- function number.tobitstring(n,m)
-  if n>0 then
-   local t={}
-   while n>0 do
-    insert(t,1,n%2>0 and 1 or 0)
-    n=floor(n/2)
-   end
-   local nn=8-#t%8
-   if nn>0 and nn<8 then
-    for i=1,nn do
-     insert(t,1,0)
+  function number.tobitstring(n,m)
+    if n>0 then
+      local t={}
+      while n>0 do
+        insert(t,1,n%2>0 and 1 or 0)
+        n=floor(n/2)
+      end
+      local nn=8-#t%8
+      if nn>0 and nn<8 then
+        for i=1,nn do
+          insert(t,1,0)
+        end
+      end
+      if m then
+        m=m*8-#t
+        if m>0 then
+          insert(t,1,rep("0",m))
+        end
+      end
+      return concat(t)
+    elseif m then
+      rep("00000000",m)
+    else
+      return "00000000"
     end
-   end
-   if m then
-    m=m*8-#t
-    if m>0 then
-     insert(t,1,rep("0",m))
-    end
-   end
-   return concat(t)
-  elseif m then
-   rep("00000000",m)
-  else
-   return "00000000"
   end
- end
 end
 function number.valid(str,default)
- return tonumber(str) or default or nil
+  return tonumber(str) or default or nil
 end
 function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
-  return s
- else
-  return "0"..s
- end
+  local s=format("%X",n)
+  if #s%2==0 then
+    return s
+  else
+    return "0"..s
+  end
 end
 function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
-  return 100
- elseif d<-100 then
-  return -100
- else
-  return d
- end
+  local d=floor(b*100/255+0.5)
+  if d>100 then
+    return 100
+  elseif d<-100 then
+    return -100
+  else
+    return d
+  end
 end
 function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
-  return 255
- elseif b<-255 then
-  return -255
- else
-  return b
- end
+  local b=floor(d*255/100+0.5)
+  if b>255 then
+    return 255
+  elseif b<-255 then
+    return -255
+  else
+    return b
+  end
 end
-function number.idiv(i,d)
- return floor(i/d) 
-end
 
 
 end -- of closure
@@ -3692,14 +3483,14 @@
 
 package.loaded["l-set"] = package.loaded["l-set"] or true
 
--- original size: 1923, stripped down to: 1044
+-- original size: 1923, stripped down to: 1133
 
 if not modules then modules={} end modules ['l-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 set=set or {}
 local nums={}
@@ -3708,54 +3499,54 @@
 local next,type=next,type
 set.create=table.tohash
 function set.tonumber(t)
- if next(t) then
-  local s=""
-  for k,v in next,t do
-   if v then
-    s=s.." "..k
-   end
+  if next(t) then
+    local s=""
+    for k,v in next,t do
+      if v then
+        s=s.." "..k
+      end
+    end
+    local n=nums[s]
+    if not n then
+      n=#tabs+1
+      tabs[n]=t
+      nums[s]=n
+    end
+    return n
+  else
+    return 0
   end
-  local n=nums[s]
-  if not n then
-   n=#tabs+1
-   tabs[n]=t
-   nums[s]=n
-  end
-  return n
- else
-  return 0
- end
 end
 function set.totable(n)
- if n==0 then
-  return {}
- else
-  return tabs[n] or {}
- end
+  if n==0 then
+    return {}
+  else
+    return tabs[n] or {}
+  end
 end
 function set.tolist(n)
- if n==0 or not tabs[n] then
-  return ""
- else
-  local t,n={},0
-  for k,v in next,tabs[n] do
-   if v then
-    n=n+1
-    t[n]=k
-   end
+  if n==0 or not tabs[n] then
+    return ""
+  else
+    local t,n={},0
+    for k,v in next,tabs[n] do
+      if v then
+        n=n+1
+        t[n]=k
+      end
+    end
+    return concat(t," ")
   end
-  return concat(t," ")
- end
 end
 function set.contains(n,s)
- if type(n)=="table" then
-  return n[s]
- elseif n==0 then
-  return false
- else
-  local t=tabs[n]
-  return t and t[s]
- end
+  if type(n)=="table" then
+    return n[s]
+  elseif n==0 then
+    return false
+  else
+    local t=tabs[n]
+    return t and t[s]
+  end
 end
 
 
@@ -3765,14 +3556,14 @@
 
 package.loaded["l-os"] = package.loaded["l-os"] or true
 
--- original size: 19347, stripped down to: 10258
+-- original size: 16268, stripped down to: 9246
 
 if not modules then modules={} end modules ['l-os']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local os=os
 local date,time=os.date,os.time
@@ -3780,305 +3571,242 @@
 local concat=table.concat
 local random,ceil,randomseed=math.random,math.ceil,math.randomseed
 local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
-do
- local selfdir=os.selfdir
- if selfdir=="" then
-  selfdir=nil
- end
- if not selfdir then
-  if arg then
-   for i=1,#arg do
-    local a=arg[i]
-    if find(a,"^%-%-[c:]*texmfbinpath=") then
-     selfdir=gsub(a,"^.-=","")
-     break
+math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+randomseed(math.initialseed)
+if not os.__getenv__ then
+  os.__getenv__=os.getenv
+  os.__setenv__=os.setenv
+  if os.env then
+    local osgetenv=os.getenv
+    local ossetenv=os.setenv
+    local osenv=os.env   local _=osenv.PATH 
+    function os.setenv(k,v)
+      if v==nil then
+        v=""
+      end
+      local K=upper(k)
+      osenv[K]=v
+      if type(v)=="table" then
+        v=concat(v,";") 
+      end
+      ossetenv(K,v)
     end
-   end
-  end
-  if not selfdir then
-   selfdir=os.selfbin or "luatex"
-   if find(selfdir,"[/\\]") then
-    selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
-   elseif os.getenv then
-    local path=os.getenv("PATH")
-    local name=gsub(selfdir,"^.*[/\\][^/\\]","")
-    local patt="[^:]+"
-    if os.type=="windows" then
-     patt="[^;]+"
-     name=name..".exe"
+    function os.getenv(k)
+      local K=upper(k)
+      local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+      if v=="" then
+        return nil
+      else
+        return v
+      end
     end
-    local isfile
-    if lfs then
-     local attributes=lfs.attributes
-     isfile=function(name)
-      local a=attributes(name,"mode")
-      return a=="file" or a=="link" or nil
-     end
-    else
-     local open=io.open
-     isfile=function(name)
-      local f=open(name)
-      if f then
-       f:close()
-       return true
+  else
+    local ossetenv=os.setenv
+    local osgetenv=os.getenv
+    local osenv={}
+    function os.setenv(k,v)
+      if v==nil then
+        v=""
       end
-     end
+      local K=upper(k)
+      osenv[K]=v
     end
-    for p in gmatch(path,patt) do
-     if isfile(p.."/"..name) then
-      selfdir=p
-      break
-     end
+    function os.getenv(k)
+      local K=upper(k)
+      local v=osenv[K] or osgetenv(K) or osgetenv(k)
+      if v=="" then
+        return nil
+      else
+        return v
+      end
     end
-   end
+    local function __index(t,k)
+      return os.getenv(k)
+    end
+    local function __newindex(t,k,v)
+      os.setenv(k,v)
+    end
+    os.env={}
+    setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
   end
-  os.selfdir=selfdir or "."
- end
 end
-math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-randomseed(math.initialseed)
-if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
-  local osgetenv=os.getenv
-  local ossetenv=os.setenv
-  local osenv=os.env   local _=osenv.PATH 
-  function os.setenv(k,v)
-   if v==nil then
-    v=""
-   end
-   local K=upper(k)
-   osenv[K]=v
-   if type(v)=="table" then
-    v=concat(v,";") 
-   end
-   ossetenv(K,v)
-  end
-  function os.getenv(k)
-   local K=upper(k)
-   local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
-   if v=="" then
-    return nil
-   else
-    return v
-   end
-  end
- else
-  local ossetenv=os.setenv
-  local osgetenv=os.getenv
-  local osenv={}
-  function os.setenv(k,v)
-   if v==nil then
-    v=""
-   end
-   local K=upper(k)
-   osenv[K]=v
-  end
-  function os.getenv(k)
-   local K=upper(k)
-   local v=osenv[K] or osgetenv(K) or osgetenv(k)
-   if v=="" then
-    return nil
-   else
-    return v
-   end
-  end
-  local function __index(t,k)
-   return os.getenv(k)
-  end
-  local function __newindex(t,k,v)
-   os.setenv(k,v)
-  end
-  os.env={}
-  setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
- end
-end
 local execute=os.execute
 local iopopen=io.popen
 local function resultof(command)
- local handle=iopopen(command,"r") 
- if handle then
-  local result=handle:read("*all") or ""
-  handle:close()
-  return result
- else
-  return ""
- end
+  local handle=iopopen(command,"r") 
+  if handle then
+    local result=handle:read("*all") or ""
+    handle:close()
+    return result
+  else
+    return ""
+  end
 end
 os.resultof=resultof
 function os.pipeto(command)
- return iopopen(command,"w") 
+  return iopopen(command,"w") 
 end
 if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
-  io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
-  io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+  if find(os.getenv("PATH"),";",1,true) then
+    io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+  else
+    io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+  end
 end
 os.type=os.type or (io.pathseparator==";"    and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin"  ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
 if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+  os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
 else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+  os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
 end
 local launchers={
- windows="start %s",
- macosx="open %s",
- unix="xdg-open %s &> /dev/null &",
+  windows="start %s",
+  macosx="open %s",
+  unix="$BROWSER %s &> /dev/null &",
 }
 function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+  execute(format(launchers[os.name] or launchers.unix,str))
 end
 if not os.times then
- function os.times()
-  return {
-   utime=os.gettimeofday(),
-   stime=0,
-   cutime=0,
-   cstime=0,
-  }
- end
+  function os.times()
+    return {
+      utime=os.gettimeofday(),
+      stime=0,
+      cutime=0,
+      cstime=0,
+    }
+  end
 end
 local gettimeofday=os.gettimeofday or os.clock
 os.gettimeofday=gettimeofday
 local startuptime=gettimeofday()
 function os.runtime()
- return gettimeofday()-startuptime
+  return gettimeofday()-startuptime
 end
 local resolvers=os.resolvers or {}
 os.resolvers=resolvers
 setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil 
+  local r=resolvers[k]
+  return r and r(t,k) or nil 
 end })
 local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
 if platform~="" then
- os.platform=platform
+  os.platform=platform
 elseif os.type=="windows" then
- function resolvers.platform(t,k)
-  local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
-  local platform=""
-  if find(architecture,"AMD64",1,true) then
-   platform="win64"
-  else
-   platform="mswin"
+  function resolvers.platform(t,k)
+    local platform,architecture="",os.getenv("PROCESSOR_ARCHITECTURE") or ""
+    if find(architecture,"AMD64",1,true) then
+      platform="win64"
+    else
+      platform="mswin"
+    end
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
   end
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
 elseif name=="linux" then
- function resolvers.platform(t,k)
-  local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
-  local platform=os.getenv("MTX_PLATFORM") or ""
-  local musl=find(os.selfdir or "","linuxmusl")
-  if platform~="" then
-  elseif find(architecture,"x86_64",1,true) then
-   platform=musl and "linuxmusl" or "linux-64"
-  elseif find(architecture,"ppc",1,true) then
-   platform="linux-ppc"
-  else
-   platform=musl and "linuxmusl" or "linux"
+  function resolvers.platform(t,k)
+    local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+    if find(architecture,"x86_64",1,true) then
+      platform="linux-64"
+    elseif find(architecture,"ppc",1,true) then
+      platform="linux-ppc"
+    else
+      platform="linux"
+    end
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
   end
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
 elseif name=="macosx" then
- function resolvers.platform(t,k)
-  local architecture=resultof("echo $HOSTTYPE") or ""
-  local platform=""
-  if architecture=="" then
-   platform="osx-intel"
-  elseif find(architecture,"i386",1,true) then
-   platform="osx-intel"
-  elseif find(architecture,"x86_64",1,true) then
-   platform="osx-64"
-  else
-   platform="osx-ppc"
+  function resolvers.platform(t,k)
+    local platform,architecture="",resultof("echo $HOSTTYPE") or ""
+    if architecture=="" then
+      platform="osx-intel"
+    elseif find(architecture,"i386",1,true) then
+      platform="osx-intel"
+    elseif find(architecture,"x86_64",1,true) then
+      platform="osx-64"
+    else
+      platform="osx-ppc"
+    end
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
   end
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
 elseif name=="sunos" then
- function resolvers.platform(t,k)
-  local architecture=resultof("uname -m") or ""
-  local platform=""
-  if find(architecture,"sparc",1,true) then
-   platform="solaris-sparc"
-  else 
-   platform="solaris-intel"
+  function resolvers.platform(t,k)
+    local platform,architecture="",resultof("uname -m") or ""
+    if find(architecture,"sparc",1,true) then
+      platform="solaris-sparc"
+    else 
+      platform="solaris-intel"
+    end
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
   end
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
 elseif name=="freebsd" then
- function resolvers.platform(t,k)
-  local architecture=resultof("uname -m") or ""
-  local platform=""
-  if find(architecture,"amd64",1,true) then
-   platform="freebsd-amd64"
-  else
-   platform="freebsd"
+  function resolvers.platform(t,k)
+    local platform,architecture="",resultof("uname -m") or ""
+    if find(architecture,"amd64",1,true) then
+      platform="freebsd-amd64"
+    else
+      platform="freebsd"
+    end
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
   end
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
 elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
-  local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
-  local platform=""
-  if find(architecture,"x86_64",1,true) then
-   platform="kfreebsd-amd64"
-  else
-   platform="kfreebsd-i386"
+  function resolvers.platform(t,k)
+    local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+    if find(architecture,"x86_64",1,true) then
+      platform="kfreebsd-amd64"
+    else
+      platform="kfreebsd-i386"
+    end
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
   end
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
 else
- function resolvers.platform(t,k)
-  local platform="linux"
-  os.setenv("MTX_PLATFORM",platform)
-  os.platform=platform
-  return platform
- end
+  function resolvers.platform(t,k)
+    local platform="linux"
+    os.setenv("MTX_PLATFORM",platform)
+    os.platform=platform
+    return platform
+  end
 end
 os.newline=name=="windows" and "\013\010" or "\010" 
 function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+  local bits=find(os.platform,"64",1,true) and 64 or 32
+  os.bits=bits
+  return bits
 end
 local t={ 8,9,"a","b" }
 function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
-  random(0xFFFF),random(0xFFFF),
-  random(0x0FFF),
-  t[ceil(random(4))] or 8,random(0x0FFF),
-  random(0xFFFF),
-  random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+  return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+    random(0xFFFF),random(0xFFFF),
+    random(0x0FFF),
+    t[ceil(random(4))] or 8,random(0x0FFF),
+    random(0xFFFF),
+    random(0xFFFF),random(0xFFFF),random(0xFFFF)
+  )
 end
 local d
 function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
-  if d>0 then
-   return format("+%02i:00",d)
+  d=d or tonumber(tonumber(date("%H")-date("!%H")))
+  if delta then
+    if d>0 then
+      return format("+%02i:00",d)
+    else
+      return format("-%02i:00",-d)
+    end
   else
-   return format("-%02i:00",-d)
+    return 1
   end
- else
-  return 1
- end
 end
 local timeformat=format("%%s%s",os.timezone(true))
 local dateformat="!%Y-%m-%d %H:%M:%S"
@@ -4085,130 +3813,116 @@
 local lasttime=nil
 local lastdate=nil
 function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
-  return default
- else
-  t=time()
- end
- if t~=lasttime then
-  lasttime=t
-  lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+  t=t and tonumber(t) or 0
+  if t>0 then
+  elseif default then
+    return default
+  else
+    t=time()
+  end
+  if t~=lasttime then
+    lasttime=t
+    lastdate=format(timeformat,date(dateformat))
+  end
+  return lastdate
 end
 local dateformat="%Y-%m-%d %H:%M:%S"
 local lasttime=nil
 local lastdate=nil
 function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
-  return default
- else
-  t=time()
- end
- if t~=lasttime then
-  lasttime=t
-  lastdate=date(dateformat,t)
- end
- return lastdate
+  t=t and tonumber(t) or 0
+  if t>0 then
+  elseif default then
+    return default
+  else
+    t=time()
+  end
+  if t~=lasttime then
+    lasttime=t
+    lastdate=date(dateformat,t)
+  end
+  return lastdate
 end
 function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
-  return date(dateformat,t)
- else
-  return default or "-"
- end
+  local t=tonumber(t)
+  if t and t>0 then
+    return date(dateformat,t)
+  else
+    return default or "-"
+  end
 end
 local memory={}
 local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
-  local suffix=file.suffix(filename)
-  local suffixes=suffix=="" and os.binsuffixes or { suffix }
-  for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
-   local df=file.join(directory,filename)
-   for i=1,#suffixes do
-    local dfs=file.addsuffix(df,suffixes[i])
-    if io.exists(dfs) then
-     fullname=dfs
-     break
+  local fullname=memory[filename]
+  if fullname==nil then
+    local suffix=file.suffix(filename)
+    local suffixes=suffix=="" and os.binsuffixes or { suffix }
+    for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+      local df=file.join(directory,filename)
+      for i=1,#suffixes do
+        local dfs=file.addsuffix(df,suffixes[i])
+        if io.exists(dfs) then
+          fullname=dfs
+          break
+        end
+      end
     end
-   end
+    if not fullname then
+      fullname=false
+    end
+    memory[filename]=fullname
   end
-  if not fullname then
-   fullname=false
-  end
-  memory[filename]=fullname
- end
- return fullname
+  return fullname
 end
 os.which=which
 os.where=which
 function os.today()
- return date("!*t") 
+  return date("!*t") 
 end
 function os.now()
- return date("!%Y-%m-%d %H:%M:%S") 
+  return date("!%Y-%m-%d %H:%M:%S") 
 end
 if not os.sleep then
- local socket=socket
- function os.sleep(n)
-  if not socket then
-   socket=require("socket")
+  local socket=socket
+  function os.sleep(n)
+    if not socket then
+      socket=require("socket")
+    end
+    socket.sleep(n)
   end
-  socket.sleep(n)
- end
 end
 local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+  return (year%4==0) and (year%100~=0 or year%400==0)
 end
 os.isleapyear=isleapyear
 local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
 local function nofdays(year,month)
- if not month then
-  return isleapyear(year) and 365 or 364
- else
-  return month==2 and isleapyear(year) and 29 or days[month]
- end
+  if not month then
+    return isleapyear(year) and 365 or 364
+  else
+    return month==2 and isleapyear(year) and 29 or days[month]
+  end
 end
 os.nofdays=nofdays
 function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+  return date("%w",time { year=year,month=month,day=day })+1
 end
 function os.validdate(year,month,day)
- if month<1 then
-  month=1
- elseif month>12 then
-  month=12
- end
- if day<1 then
-  day=1
- else
-  local max=nofdays(year,month)
-  if day>max then
-   day=max
+  if month<1 then
+    month=1
+  elseif month>12 then
+    month=12
   end
- end
- return year,month,day
+  if day<1 then
+    day=1
+  else
+    local max=nofdays(year,month)
+    if day>max then
+      day=max
+    end
+  end
+  return year,month,day
 end
-local osexit=os.exit
-local exitcode=nil
-function os.setexitcode(code)
- exitcode=code
-end
-function os.exit(c)
- if exitcode~=nil then
-  return osexit(exitcode)
- end
- if c~=nil then
-  return osexit(c)
- end
- return osexit()
-end
 
 
 end -- of closure
@@ -4217,19 +3931,19 @@
 
 package.loaded["l-file"] = package.loaded["l-file"] or true
 
--- original size: 21804, stripped down to: 9980
+-- original size: 21616, stripped down to: 10359
 
 if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 file=file or {}
 local file=file
 if not lfs then
- lfs=optionalrequire("lfs")
+  lfs=optionalrequire("lfs")
 end
 local insert,concat=table.insert,table.concat
 local match,find,gmatch=string.match,string.find,string.gmatch
@@ -4237,23 +3951,25 @@
 local getcurrentdir,attributes=lfs.currentdir,lfs.attributes
 local checkedsplit=string.checkedsplit
 local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
+local tricky=S("/\\")*P(-1)
 local attributes=lfs.attributes
+if sandbox then
+  sandbox.redefine(lfs.isfile,"lfs.isfile")
+  sandbox.redefine(lfs.isdir,"lfs.isdir")
+end
 function lfs.isdir(name)
- return attributes(name,"mode")=="directory"
+  if lpegmatch(tricky,name) then
+    return attributes(name,"mode")=="directory"
+  else
+    return attributes(name.."/.","mode")=="directory"
+  end
 end
 function lfs.isfile(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
+  return attributes(name,"mode")=="file"
 end
 function lfs.isfound(name)
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
+  return attributes(name,"mode")=="file" and name or nil
 end
-if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
-end
 local colon=P(":")
 local period=P(".")
 local periods=P("..")
@@ -4266,27 +3982,27 @@
 local suffix=period/""*(1-period-slashes)^1*-1
 local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1) 
 local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
+  return name and lpegmatch(pattern,name) or default or ""
 end
 local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
 local function basename(name)
- return name and lpegmatch(pattern,name) or name
+  return name and lpegmatch(pattern,name) or name
 end
 local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
 local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
+  return name and lpegmatch(pattern,name) or name
 end
 local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
 local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
+  return name and lpegmatch(pattern,name) or ""
 end
 local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
 local function suffixesonly(name)
- if name then
-  return lpegmatch(pattern,name)
- else
-  return ""
- end
+  if name then
+    return lpegmatch(pattern,name)
+  else
+    return ""
+  end
 end
 file.pathpart=pathpart
 file.basename=basename
@@ -4295,7 +4011,7 @@
 file.suffix=suffixonly
 file.suffixesonly=suffixesonly
 file.suffixes=suffixesonly
-file.dirname=pathpart   
+file.dirname=pathpart  
 file.extname=suffixonly
 local drive=C(R("az","AZ"))*colon
 local path=C((noslashes^0*slashes)^0)
@@ -4311,142 +4027,142 @@
 local pattern_c=C(drive*path)*C(base*suffix) 
 local pattern_d=path*rest
 function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
-  return lpegmatch(pattern_a,str) 
- else
-  return lpegmatch(pattern_b,str) 
- end
+  if not str then
+  elseif splitdrive then
+    return lpegmatch(pattern_a,str) 
+  else
+    return lpegmatch(pattern_b,str) 
+  end
 end
 function file.splitbase(str)
- if str then
-  return lpegmatch(pattern_d,str) 
- else
-  return "",str 
- end
+  if str then
+    return lpegmatch(pattern_d,str) 
+  else
+    return "",str 
+  end
 end
 function file.nametotable(str,splitdrive)
- if str then
-  local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
-  if splitdrive then
-   return {
-    path=path,
-    drive=drive,
-    subpath=subpath,
-    name=name,
-    base=base,
-    suffix=suffix,
-   }
-  else
-   return {
-    path=path,
-    name=name,
-    base=base,
-    suffix=suffix,
-   }
+  if str then
+    local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+    if splitdrive then
+      return {
+        path=path,
+        drive=drive,
+        subpath=subpath,
+        name=name,
+        base=base,
+        suffix=suffix,
+      }
+    else
+      return {
+        path=path,
+        name=name,
+        base=base,
+        suffix=suffix,
+      }
+    end
   end
- end
 end
 local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
 function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
+  return name and lpegmatch(pattern,name)
 end
 local suffix=period/""*(1-period-slashes)^1*-1
 local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
 function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
-  return filename
- elseif criterium==true then
-  return filename.."."..suffix
- elseif not criterium then
-  local n,s=lpegmatch(pattern,filename)
-  if not s or s=="" then
-   return filename.."."..suffix
-  else
-   return filename
-  end
- else
-  local n,s=lpegmatch(pattern,filename)
-  if s and s~="" then
-   local t=type(criterium)
-   if t=="table" then
-    for i=1,#criterium do
-     if s==criterium[i] then
+  if not filename or not suffix or suffix=="" then
+    return filename
+  elseif criterium==true then
+    return filename.."."..suffix
+  elseif not criterium then
+    local n,s=lpegmatch(pattern,filename)
+    if not s or s=="" then
+      return filename.."."..suffix
+    else
       return filename
-     end
     end
-   elseif t=="string" then
-    if s==criterium then
-     return filename
+  else
+    local n,s=lpegmatch(pattern,filename)
+    if s and s~="" then
+      local t=type(criterium)
+      if t=="table" then
+        for i=1,#criterium do
+          if s==criterium[i] then
+            return filename
+          end
+        end
+      elseif t=="string" then
+        if s==criterium then
+          return filename
+        end
+      end
     end
-   end
+    return (n or filename).."."..suffix
   end
-  return (n or filename).."."..suffix
- end
 end
 local suffix=period*(1-period-slashes)^1*-1
 local pattern=Cs((1-suffix)^0)
 function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
-  return lpegmatch(pattern,name).."."..suffix
- else
-  return name
- end
+  if name and suffix and suffix~="" then
+    return lpegmatch(pattern,name).."."..suffix
+  else
+    return name
+  end
 end
 local reslasher=lpeg.replacer(P("\\"),"/")
 function file.reslash(str)
- return str and lpegmatch(reslasher,str)
+  return str and lpegmatch(reslasher,str)
 end
 function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
-  name=name.."/m_t_x_t_e_s_t.tmp"
-  local f=io.open(name,"wb")
-  if f then
-   f:close()
-   os.remove(name)
-   return true
+  if not name then
+  elseif lfs.isdir(name) then
+    name=name.."/m_t_x_t_e_s_t.tmp"
+    local f=io.open(name,"wb")
+    if f then
+      f:close()
+      os.remove(name)
+      return true
+    end
+  elseif lfs.isfile(name) then
+    local f=io.open(name,"ab")
+    if f then
+      f:close()
+      return true
+    end
+  else
+    local f=io.open(name,"ab")
+    if f then
+      f:close()
+      os.remove(name)
+      return true
+    end
   end
- elseif lfs.isfile(name) then
-  local f=io.open(name,"ab")
-  if f then
-   f:close()
-   return true
-  end
- else
-  local f=io.open(name,"ab")
-  if f then
-   f:close()
-   os.remove(name)
-   return true
-  end
- end
- return false
+  return false
 end
 local readable=P("r")*Cc(true)
 function file.is_readable(name)
- if name then
-  local a=attributes(name)
-  return a and lpegmatch(readable,a.permissions) or false
- else
-  return false
- end
+  if name then
+    local a=attributes(name)
+    return a and lpegmatch(readable,a.permissions) or false
+  else
+    return false
+  end
 end
 file.isreadable=file.is_readable 
 file.iswritable=file.is_writable 
 function file.size(name)
- if name then
-  local a=attributes(name)
-  return a and a.size or 0
- else
-  return 0
- end
+  if name then
+    local a=attributes(name)
+    return a and a.size or 0
+  else
+    return 0
+  end
 end
 function file.splitpath(str,separator) 
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+  return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
 end
 function file.joinpath(tab,separator) 
- return tab and concat(tab,separator or io.pathseparator) 
+  return tab and concat(tab,separator or io.pathseparator) 
 end
 local someslash=S("\\/")
 local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -4456,30 +4172,30 @@
 local reslasher=lpeg.replacer(S("\\/"),"/")
 local deslasher=lpeg.replacer(S("\\/")^1,"/")
 function file.join(one,two,three,...)
- if not two then
-  return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
-  return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
- end
- if lpegmatch(isnetwork,one) then
-  local one=lpegmatch(reslasher,one)
-  local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
-  if lpegmatch(hasroot,two) then
-   return one..two
-  else
-   return one.."/"..two
+  if not two then
+    return one=="" and one or lpegmatch(reslasher,one)
   end
- elseif lpegmatch(isroot,one) then
-  local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
-  if lpegmatch(hasroot,two) then
-   return two
+  if one=="" then
+    return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+  end
+  if lpegmatch(isnetwork,one) then
+    local one=lpegmatch(reslasher,one)
+    local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+    if lpegmatch(hasroot,two) then
+      return one..two
+    else
+      return one.."/"..two
+    end
+  elseif lpegmatch(isroot,one) then
+    local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+    if lpegmatch(hasroot,two) then
+      return two
+    else
+      return "/"..two
+    end
   else
-   return "/"..two
+    return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
   end
- else
-  return lpegmatch(deslasher,concat({  one,two,three,... },"/"))
- end
 end
 local drivespec=R("az","AZ")^1*colon
 local anchors=fwslash+drivespec
@@ -4489,56 +4205,56 @@
 local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
 local absolute=fwslash
 function file.collapsepath(str,anchor) 
- if not str then
-  return
- end
- if anchor==true and not lpegmatch(anchors,str) then
-  str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
-  return "."
- elseif lpegmatch(untouched,str) then
-  return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
-  local element=oldelements[i]
-  if element=='.' then
-  elseif element=='..' then
-   local n=i-1
-   while n>0 do
-    local element=oldelements[n]
-    if element~='..' and element~='.' then
-     oldelements[n]='.'
-     break
-    else
-     n=n-1
+  if not str then
+    return
+  end
+  if anchor==true and not lpegmatch(anchors,str) then
+    str=getcurrentdir().."/"..str
+  end
+  if str=="" or str=="." then
+    return "."
+  elseif lpegmatch(untouched,str) then
+    return lpegmatch(reslasher,str)
+  end
+  local starter,oldelements=lpegmatch(splitstarter,str)
+  local newelements={}
+  local i=#oldelements
+  while i>0 do
+    local element=oldelements[i]
+    if element=='.' then
+    elseif element=='..' then
+      local n=i-1
+      while n>0 do
+        local element=oldelements[n]
+        if element~='..' and element~='.' then
+          oldelements[n]='.'
+          break
+        else
+          n=n-1
+        end
+       end
+      if n<1 then
+        insert(newelements,1,'..')
+      end
+    elseif element~="" then
+      insert(newelements,1,element)
     end
-    end
-   if n<1 then
-      insert(newelements,1,'..')
-   end
-  elseif element~="" then
-   insert(newelements,1,element)
+    i=i-1
   end
-  i=i-1
- end
- if #newelements==0 then
-  return starter or "."
- elseif starter then
-  return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
-  return "/"..concat(newelements,'/')
- else
-  newelements=concat(newelements,'/')
-  if anchor=="." and find(str,"^%./") then
-   return "./"..newelements
+  if #newelements==0 then
+    return starter or "."
+  elseif starter then
+    return starter..concat(newelements,'/')
+  elseif lpegmatch(absolute,str) then
+    return "/"..concat(newelements,'/')
   else
-   return newelements
+    newelements=concat(newelements,'/')
+    if anchor=="." and find(str,"^%./") then
+      return "./"..newelements
+    else
+      return newelements
+    end
   end
- end
 end
 local validchars=R("az","09","AZ","--","..")
 local pattern_a=lpeg.replacer(1-validchars)
@@ -4546,14 +4262,14 @@
 local whatever=P("-")^0/""
 local pattern_b=Cs(whatever*(1-whatever*-1)^1)
 function file.robustname(str,strict)
- if str then
-  str=lpegmatch(pattern_a,str) or str
-  if strict then
-   return lpegmatch(pattern_b,str) or str 
-  else
-   return str
+  if str then
+    str=lpegmatch(pattern_a,str) or str
+    if strict then
+      return lpegmatch(pattern_b,str) or str 
+    else
+      return str
+    end
   end
- end
 end
 local loaddata=io.loaddata
 local savedata=io.savedata
@@ -4560,12 +4276,12 @@
 file.readdata=loaddata
 file.savedata=savedata
 function file.copy(oldname,newname)
- if oldname and newname then
-  local data=loaddata(oldname)
-  if data and data~="" then
-   savedata(newname,data)
+  if oldname and newname then
+    local data=loaddata(oldname)
+    if data and data~="" then
+      savedata(newname,data)
+    end
   end
- end
 end
 local letter=R("az","AZ")+S("_-+")
 local separator=P("://")
@@ -4574,45 +4290,41 @@
 lpeg.patterns.qualified=qualified
 lpeg.patterns.rootbased=rootbased
 function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
+  return filename and lpegmatch(qualified,filename)~=nil
 end
 function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
+  return filename and lpegmatch(rootbased,filename)~=nil
 end
 function file.strip(name,dir)
- if name then
-  local b,a=match(name,"^(.-)"..dir.."(.*)$")
-  return a~="" and a or name
- end
+  if name then
+    local b,a=match(name,"^(.-)"..dir.."(.*)$")
+    return a~="" and a or name
+  end
 end
 function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do 
-  full=full..sub
-  lfs.mkdir(full)
- end
+  local full=""
+  for sub in gmatch(path,"(/*[^\\/]+)") do 
+    full=full..sub
+    lfs.mkdir(full)
+  end
 end
 function file.withinbase(path) 
- local l=0
- if not find(path,"^/") then
-  path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
-  if dir==".." then
-   l=l-1
-  elseif dir~="." then
-   l=l+1
+  local l=0
+  if not find(path,"^/") then
+    path="/"..path
   end
-  if l<0 then
-   return false
+  for dir in gmatch(path,"/([^/]+)") do
+    if dir==".." then
+      l=l-1
+    elseif dir~="." then
+      l=l+1
+    end
+    if l<0 then
+      return false
+    end
   end
- end
- return true
+  return true
 end
-local symlinkattributes=lfs.symlinkattributes
-function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
-end
 
 
 end -- of closure
@@ -4621,51 +4333,51 @@
 
 package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
 
--- original size: 1211, stripped down to: 951
+-- original size: 1211, stripped down to: 1002
 
 if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 if not gzip then
- return
+  return
 end
 local suffix,suffixes=file.suffix,file.suffixes
 function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
-  f:close()
-  local g=gzip.open(filename,"rb")
-  if g then
-   local str=g:read("*all")
-   g:close()
-   return str
+  local f=io.open(filename,"rb")
+  if not f then
+  elseif suffix(filename)=="gz" then
+    f:close()
+    local g=gzip.open(filename,"rb")
+    if g then
+      local str=g:read("*all")
+      g:close()
+      return str
+    end
+  else
+    local str=f:read("*all")
+    f:close()
+    return str
   end
- else
-  local str=f:read("*all")
-  f:close()
-  return str
- end
 end
 function gzip.save(filename,data)
- if suffix(filename)~="gz" then
-  filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
-  local s=zlib.compress(data or "",9,nil,15+16)
-  f:write(s)
-  f:close()
-  return #s
- end
+  if suffix(filename)~="gz" then
+    filename=filename..".gz"
+  end
+  local f=io.open(filename,"wb")
+  if f then
+    local s=zlib.compress(data or "",9,nil,15+16)
+    f:write(s)
+    f:close()
+    return #s
+  end
 end
 function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+  local suffix,extra=suffixes(filename)
+  local gzipped=extra=="gz"
+  return suffix,gzipped
 end
 
 
@@ -4675,87 +4387,87 @@
 
 package.loaded["l-md5"] = package.loaded["l-md5"] or true
 
--- original size: 3309, stripped down to: 2218
+-- original size: 3309, stripped down to: 2314
 
 if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 if not md5 then
- md5=optionalrequire("md5")
+  md5=optionalrequire("md5")
 end
 if not md5 then
- md5={
-  sum=function(str) print("error: md5 is not loaded (sum     ignored)") return str end,
-  sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+  md5={
+    sum=function(str) print("error: md5 is not loaded (sum     ignored)") return str end,
+    sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+  }
 end
 local md5,file=md5,file
 local gsub=string.gsub
 do
- local patterns=lpeg and lpeg.patterns
- if patterns then
-  local bytestoHEX=patterns.bytestoHEX
-  local bytestohex=patterns.bytestohex
-  local bytestodec=patterns.bytestodec
-  local lpegmatch=lpeg.match
-  local md5sum=md5.sum
-  if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
-  if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
-  if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
-  md5.sumhexa=md5.hex
-  md5.sumHEXA=md5.HEX
- end
+  local patterns=lpeg and lpeg.patterns
+  if patterns then
+    local bytestoHEX=patterns.bytestoHEX
+    local bytestohex=patterns.bytestohex
+    local bytestodec=patterns.bytestodec
+    local lpegmatch=lpeg.match
+    local md5sum=md5.sum
+    if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+    if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+    if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+    md5.sumhexa=md5.hex
+    md5.sumHEXA=md5.HEX
+  end
 end
 function file.needsupdating(oldname,newname,threshold) 
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
-  local newtime=lfs.attributes(newname,"modification")
-  if not newtime then
-   return true 
-  elseif newtime>=oldtime then
-   return false 
-  elseif oldtime-newtime<(threshold or 1) then
-   return false 
+  local oldtime=lfs.attributes(oldname,"modification")
+  if oldtime then
+    local newtime=lfs.attributes(newname,"modification")
+    if not newtime then
+      return true 
+    elseif newtime>=oldtime then
+      return false 
+    elseif oldtime-newtime<(threshold or 1) then
+      return false 
+    else
+      return true 
+    end
   else
-   return true 
+    return false 
   end
- else
-  return false 
- end
 end
 file.needs_updating=file.needsupdating
 function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
-  lfs.touch(newname,oldtime,oldtime)
- end
+  local oldtime=lfs.attributes(oldname,"modification")
+  if oldtime and lfs.isfile(newname) then
+    lfs.touch(newname,oldtime,oldtime)
+  end
 end
 function file.checksum(name)
- if md5 then
-  local data=io.loaddata(name)
-  if data then
-   return md5.HEX(data)
+  if md5 then
+    local data=io.loaddata(name)
+    if data then
+      return md5.HEX(data)
+    end
   end
- end
- return nil
+  return nil
 end
 function file.loadchecksum(name)
- if md5 then
-  local data=io.loaddata(name..".md5")
-  return data and (gsub(data,"%s",""))
- end
- return nil
+  if md5 then
+    local data=io.loaddata(name..".md5")
+    return data and (gsub(data,"%s",""))
+  end
+  return nil
 end
 function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
-  io.savedata(name..".md5",checksum)
-  return checksum
- end
- return nil
+  if not checksum then checksum=file.checksum(name) end
+  if checksum then
+    io.savedata(name..".md5",checksum)
+    return checksum
+  end
+  return nil
 end
 
 
@@ -4763,48 +4475,16 @@
 
 do -- create closure to overcome 200 locals limit
 
-package.loaded["l-sha"] = package.loaded["l-sha"] or true
-
--- original size: 1085, stripped down to: 969
-
-if not modules then modules={} end modules ['l-sha']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-if sha2 then
- local lpegmatch=lpeg.match
- local lpegpatterns=lpeg.patterns
- local bytestohex=lpegpatterns.bytestohex
- local bytestoHEX=lpegpatterns.bytestoHEX
- local digest256=sha2.digest256
- local digest384=sha2.digest384
- local digest512=sha2.digest512
- sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
- sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
- sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
- sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
- sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
- sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
 package.loaded["l-url"] = package.loaded["l-url"] or true
 
--- original size: 14755, stripped down to: 6981
+-- original size: 14755, stripped down to: 7236
 
 if not modules then modules={} end modules ['l-url']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local char,format,byte=string.char,string.format,string.byte
 local concat=table.concat
@@ -4817,14 +4497,14 @@
 local unescapes={}
 local escapes={}
 setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+  local v=char(tonumber(k,16))
+  t[k]=v
+  return v
 end })
 setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+  local v=format("%%%02X",byte(k))
+  t[k]=v
+  return v
 end })
 local colon=P(":")
 local qmark=P("?")
@@ -4843,21 +4523,21 @@
 local noslash=P("/")/""
 local plustospace=P("+")/" "
 local decoder=Cs((
-     plustospace+escapedchar+P("\r\n")/"\n"+P(1)
-    )^0 )
+          plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+        )^0 )
 local encoder=Cs((
-     R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
-    )^0 )
+          R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+        )^0 )
 lpegpatterns.urldecoder=decoder
 lpegpatterns.urlencoder=encoder
-function url.decode  (str) return str and lpegmatch(decoder,str) or str end
-function url.encode  (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
 function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
 local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
 local authoritystr=Cs((escaped+(1-   slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1-   qmark-hash))^0)
-local querystr=Cs(((1-      hash))^0)
-local fragmentstr=Cs((escaped+(1-     endofstring))^0)
+local pathstr=Cs((escaped+(1-      qmark-hash))^0)
+local querystr=Cs(((1-         hash))^0)
+local fragmentstr=Cs((escaped+(1-      endofstring))^0)
 local scheme=schemestr*colon+nothing
 local authority=slash*slash*authoritystr+nothing
 local path=slash*pathstr+nothing
@@ -4875,19 +4555,19 @@
 lpegpatterns.urlunescaper=unescaper
 lpegpatterns.urlgetcleaner=getcleaner
 function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+  return lpegmatch(getcleaner,str)
 end
 local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+  return (type(str)=="string" and lpegmatch(parser,str)) or str
 end
 local isscheme=schemestr*colon*slash*slash 
 local function hasscheme(str)
- if str then
-  local scheme=lpegmatch(isscheme,str) 
-  return scheme~="" and scheme or false
- else
-  return false
- end
+  if str then
+    local scheme=lpegmatch(isscheme,str) 
+    return scheme~="" and scheme or false
+  else
+    return false
+  end
 end
 local rootletter=R("az","AZ")+S("_-+")
 local separator=P("://")
@@ -4897,161 +4577,161 @@
 local backslashswapper=replacer("\\","/")
 local equal=P("=")
 local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal     )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal       )^0)
 local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
 local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+  sequence=V("pair")*(amp*V("pair"))^0,
+  pair=Cg(key*equal*value),
 },rawset)
 local userpart=(1-atsign-colon)^1
 local serverpart=(1-colon)^1
 local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
 local function hashed(str) 
- if not str or str=="" then
+  if not str or str=="" then
+    return {
+      scheme="invalid",
+      original=str,
+    }
+  end
+  local detailed=split(str)
+  local rawscheme=""
+  local rawquery=""
+  local somescheme=false
+  local somequery=false
+  if detailed then
+    rawscheme=detailed[1]
+    rawquery=detailed[4]
+    somescheme=rawscheme~=""
+    somequery=rawquery~=""
+  end
+  if not somescheme and not somequery then
+    return {
+      scheme="file",
+      authority="",
+      path=str,
+      query="",
+      fragment="",
+      original=str,
+      noscheme=true,
+      filename=str,
+    }
+  end
+  local authority=detailed[2]
+  local path=detailed[3]
+  local filename 
+  local username 
+  local password 
+  local host   
+  local port   
+  if authority~="" then
+    username,password,host,port=lpegmatch(splitauthority,authority)
+  end
+  if authority=="" then
+    filename=path
+  elseif path=="" then
+    filename=""
+  else
+    filename=authority.."/"..path
+  end
   return {
-   scheme="invalid",
-   original=str,
+    scheme=rawscheme,
+    authority=authority,
+    path=path,
+    query=lpegmatch(unescaper,rawquery),
+    queries=lpegmatch(splitquery,rawquery),
+    fragment=detailed[5],
+    original=str,
+    noscheme=false,
+    filename=filename,
+    host=host,
+    port=port,
   }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
-  rawscheme=detailed[1]
-  rawquery=detailed[4]
-  somescheme=rawscheme~=""
-  somequery=rawquery~=""
- end
- if not somescheme and not somequery then
-  return {
-   scheme="file",
-   authority="",
-   path=str,
-   query="",
-   fragment="",
-   original=str,
-   noscheme=true,
-   filename=str,
-  }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename  
- local username  
- local password  
- local host   
- local port   
- if authority~="" then
-  username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
-  filename=path
- elseif path=="" then
-  filename=""
- else
-  filename=authority.."/"..path
- end
- return {
-  scheme=rawscheme,
-  authority=authority,
-  path=path,
-  query=lpegmatch(unescaper,rawquery),
-  queries=lpegmatch(splitquery,rawquery),
-  fragment=detailed[5],
-  original=str,
-  noscheme=false,
-  filename=filename,
-  host=host,
-  port=port,
- }
 end
 url.split=split
 url.hasscheme=hasscheme
 url.hashed=hashed
 function url.addscheme(str,scheme) 
- if hasscheme(str) then
-  return str
- elseif not scheme then
-  return "file:///"..str
- else
-  return scheme..":///"..str
- end
+  if hasscheme(str) then
+    return str
+  elseif not scheme then
+    return "file:///"..str
+  else
+    return scheme..":///"..str
+  end
 end
 function url.construct(hash) 
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
-  r=r+1;result[r]=lpegmatch(escaper,scheme)
-  r=r+1;result[r]="://"
- end
- if authority and authority~="" then
-  r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
-  r=r+1;result[r]="/"
-  r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
-  local done=false
-  for k,v in sortedhash(queries) do
-   r=r+1;result[r]=done and "&" or "?"
-   r=r+1;result[r]=lpegmatch(escaper,k) 
-   r=r+1;result[r]="="
-   r=r+1;result[r]=lpegmatch(escaper,v) 
-   done=true
+  local result,r={},0
+  local scheme=hash.scheme
+  local authority=hash.authority
+  local path=hash.path
+  local queries=hash.queries
+  local fragment=hash.fragment
+  if scheme and scheme~="" then
+    r=r+1;result[r]=lpegmatch(escaper,scheme)
+    r=r+1;result[r]="://"
   end
- end
- if fragment and fragment~="" then
-  r=r+1;result[r]="#"
-  r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+  if authority and authority~="" then
+    r=r+1;result[r]=lpegmatch(escaper,authority)
+  end
+  if path and path~="" then
+    r=r+1;result[r]="/"
+    r=r+1;result[r]=lpegmatch(escaper,path)
+  end
+  if queries then
+    local done=false
+    for k,v in sortedhash(queries) do
+      r=r+1;result[r]=done and "&" or "?"
+      r=r+1;result[r]=lpegmatch(escaper,k) 
+      r=r+1;result[r]="="
+      r=r+1;result[r]=lpegmatch(escaper,v) 
+      done=true
+    end
+  end
+  if fragment and fragment~="" then
+    r=r+1;result[r]="#"
+    r=r+1;result[r]=lpegmatch(escaper,fragment)
+  end
+  return concat(result)
 end
 local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
 function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+  local spec=hashed(filename)
+  local path=spec.path
+  return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
 end
 local function escapestring(str)
- return lpegmatch(escaper,str)
+  return lpegmatch(escaper,str)
 end
 url.escape=escapestring
 function url.query(str)
- if type(str)=="string" then
-  return lpegmatch(splitquery,str) or ""
- else
-  return str
- end
+  if type(str)=="string" then
+    return lpegmatch(splitquery,str) or ""
+  else
+    return str
+  end
 end
 function url.toquery(data)
- local td=type(data)
- if td=="string" then
-  return #str and escape(data) or nil 
- elseif td=="table" then
-  if next(data) then
-   local t={}
-   for k,v in next,data do
-    t[#t+1]=format("%s=%s",k,escapestring(v))
-   end
-   return concat(t,"&")
+  local td=type(data)
+  if td=="string" then
+    return #str and escape(data) or nil 
+  elseif td=="table" then
+    if next(data) then
+      local t={}
+      for k,v in next,data do
+        t[#t+1]=format("%s=%s",k,escapestring(v))
+      end
+      return concat(t,"&")
+    end
+  else
   end
- else
- end
 end
 local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
 function url.barepath(path)
- if not path or path=="" then
-  return ""
- else
-  return lpegmatch(pattern,path)
- end
+  if not path or path=="" then
+    return ""
+  else
+    return lpegmatch(pattern,path)
+  end
 end
 
 
@@ -5061,14 +4741,14 @@
 
 package.loaded["l-dir"] = package.loaded["l-dir"] or true
 
--- original size: 18002, stripped down to: 10681
+-- original size: 17703, stripped down to: 11691
 
 if not modules then modules={} end modules ['l-dir']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type,select=type,select
 local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -5080,7 +4760,7 @@
 local lfs=lfs
 local attributes=lfs.attributes
 local walkdir=lfs.dir
-local isdir=lfs.isdir  
+local isdir=lfs.isdir 
 local isfile=lfs.isfile 
 local currentdir=lfs.currentdir
 local chdir=lfs.chdir
@@ -5087,471 +4767,464 @@
 local mkdir=lfs.mkdir
 local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
 if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
-  if lpegmatch(tricky,name) then
-   return attributes(name,"mode")=="directory"
-  else
-   return attributes(name.."/.","mode")=="directory"
+  local tricky=S("/\\")*P(-1)
+  isdir=function(name)
+    if lpegmatch(tricky,name) then
+      return attributes(name,"mode")=="directory"
+    else
+      return attributes(name.."/.","mode")=="directory"
+    end
   end
- end
- isfile=function(name)
-  return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+  isfile=function(name)
+    return attributes(name,"mode")=="file"
+  end
+  lfs.isdir=isdir
+  lfs.isfile=isfile
 else
- isdir=function(name)
-  return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
-  return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+  isdir=function(name)
+    return attributes(name,"mode")=="directory"
+  end
+  isfile=function(name)
+    return attributes(name,"mode")=="file"
+  end
+  lfs.isdir=isdir
+  lfs.isfile=isfile
 end
 function dir.current()
- return (gsub(currentdir(),"\\","/"))
+  return (gsub(currentdir(),"\\","/"))
 end
 local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
-  local usedpath
-  if path=="/" then
-   usedpath="/."
-  elseif not find(path,"/$") then
-   usedpath=path.."/."
-   path=path.."/"
-  else
-   usedpath=path
-  end
-  local dirs
-  local nofdirs=0
-  for name in walkdir(usedpath) do
-   if name~="." and name~=".." then
-    local full=path..name
-    local mode=attributes(full,'mode')
-    if mode=='file' then
-     if not patt or find(full,patt) then
-      action(full)
-     end
-    elseif recurse and mode=="directory" then
-     if dirs then
-      nofdirs=nofdirs+1
-      dirs[nofdirs]=full
-     else
-      nofdirs=1
-      dirs={ full }
-     end
+  if isdir(path) then
+    local usedpath
+    if path=="/" then
+      usedpath="/."
+    elseif not find(path,"/$") then
+      usedpath=path.."/."
+      path=path.."/"
+    else
+      usedpath=path
     end
-   end
+    local dirs
+    for name in walkdir(usedpath) do
+      if name~="." and name~=".." then
+        local full=path..name
+        local mode=attributes(full,'mode')
+        if mode=='file' then
+          if not patt or find(full,patt) then
+            action(full)
+          end
+        elseif recurse and mode=="directory" then
+          if not dirs then
+            dirs={ full }
+          else
+            dirs[#dirs+1]=full
+          end
+        end
+      end
+    end
+    if dirs then
+      for i=1,#dirs do
+        glob_pattern_function(dirs[i],patt,recurse,action)
+      end
+    end
   end
-  if dirs then
-   for i=1,nofdirs do
-    glob_pattern_function(dirs[i],patt,recurse,action)
-   end
-  end
- end
 end
 local function glob_pattern_table(path,patt,recurse,result)
- if not result then
-  result={}
- end
- local usedpath
- if path=="/" then
-  usedpath="/."
- elseif not find(path,"/$") then
-  usedpath=path.."/."
-  path=path.."/"
- else
-  usedpath=path
- end
- local dirs
- local nofdirs=0
- local noffiles=#result
- for name,a in walkdir(usedpath) do
-  if name~="." and name~=".." then
-   local full=path..name
-   local mode=attributes(full,'mode')
-   if mode=='file' then
-    if not patt or find(full,patt) then
-     noffiles=noffiles+1
-     result[noffiles]=full
+  if not result then
+    result={}
+  end
+  if isdir(path) then
+    local usedpath
+    if path=="/" then
+      usedpath="/."
+    elseif not find(path,"/$") then
+      usedpath=path.."/."
+      path=path.."/"
+    else
+      usedpath=path
     end
-   elseif recurse and mode=="directory" then
+    local dirs
+    for name in walkdir(usedpath) do
+      if name~="." and name~=".." then
+        local full=path..name
+        local mode=attributes(full,'mode')
+        if mode=='file' then
+          if not patt or find(full,patt) then
+            result[#result+1]=full
+          end
+        elseif recurse and mode=="directory" then
+          if not dirs then
+            dirs={ full }
+          else
+            dirs[#dirs+1]=full
+          end
+        end
+      end
+    end
     if dirs then
-     nofdirs=nofdirs+1
-     dirs[nofdirs]=full
-    else
-     nofdirs=1
-     dirs={ full }
+      for i=1,#dirs do
+        glob_pattern_table(dirs[i],patt,recurse,result)
+      end
     end
-   end
   end
- end
- if dirs then
-  for i=1,nofdirs do
-   glob_pattern_table(dirs[i],patt,recurse,result)
-  end
- end
- return result
+  return result
 end
 local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
-  patt=false
- end
- local okay=isdir(path)
- if kind=="function" then
-  return okay and glob_pattern_function(path,patt,recurse,method) or {}
- elseif kind=="table" then
-  return okay and glob_pattern_table(path,patt,recurse,method) or method
- else
-  return okay and glob_pattern_table(path,patt,recurse,{}) or {}
- end
+  local kind=type(method)
+  if patt and sub(patt,1,-3)==path then
+    patt=false
+  end
+  if kind=="function" then
+    return glob_pattern_function(path,patt,recurse,method)
+  elseif kind=="table" then
+    return glob_pattern_table(path,patt,recurse,method)
+  else
+    return glob_pattern_table(path,patt,recurse,{})
+  end
 end
 dir.globpattern=globpattern
 local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
-  ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end) 
- else
-  ok,scanner,first=xpcall(function() return walkdir(path)   end,function() end) 
- end
- if ok and type(scanner)=="function" then
-  if not find(path,"/$") then
-   path=path..'/'
+  local ok,scanner
+  result=result or {}
+  if path=="/" then
+    ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end) 
+  else
+    ok,scanner,first=xpcall(function() return walkdir(path)   end,function() end) 
   end
-  for name in scanner,first do
-   if name=="." then
-   elseif name==".." then
-   else
-    local full=path..name
-    local attr=attributes(full)
-    local mode=attr.mode
-    if mode=='file' then
-     if find(full,patt) then
-      result[name]=attr
-     end
-    elseif recurse and mode=="directory" then
-     attr.list=collectpattern(full,patt,recurse)
-     result[name]=attr
+  if ok and type(scanner)=="function" then
+    if not find(path,"/$") then
+      path=path..'/'
     end
-   end
+    for name in scanner,first do
+      if name=="." then
+      elseif name==".." then
+      else
+        local full=path..name
+        local attr=attributes(full)
+        local mode=attr.mode
+        if mode=='file' then
+          if find(full,patt) then
+            result[name]=attr
+          end
+        elseif recurse and mode=="directory" then
+          attr.list=collectpattern(full,patt,recurse)
+          result[name]=attr
+        end
+      end
+    end
   end
- end
- return result
+  return result
 end
 dir.collectpattern=collectpattern
 local separator,pattern
 if onwindows then 
- local slash=S("/\\")/"/"
- pattern={
-  [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
-  [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
-  [3]=Cs(P(1)^0)
- }
+  local slash=S("/\\")/"/"
+  pattern={
+    [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+    [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+    [3]=Cs(P(1)^0)
+  }
 else
- pattern={
-  [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
-  [2]=C(((1-S("*?/"))^0*P("/"))^0),
-  [3]=C(P(1)^0)
- }
+  pattern={
+    [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+    [2]=C(((1-S("*?/"))^0*P("/"))^0),
+    [3]=C(P(1)^0)
+  }
 end
 local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+  P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
 )^0 )
 local function glob(str,t)
- if type(t)=="function" then
-  if type(str)=="table" then
-   for s=1,#str do
-    glob(str[s],t)
-   end
-  elseif isfile(str) then
-   t(str)
+  if type(t)=="function" then
+    if type(str)=="table" then
+      for s=1,#str do
+        glob(str[s],t)
+      end
+    elseif isfile(str) then
+      t(str)
+    else
+      local root,path,base=lpegmatch(pattern,str) 
+      if root and path and base then
+        local recurse=find(base,"**",1,true) 
+        local start=root..path
+        local result=lpegmatch(filter,start..base)
+        globpattern(start,result,recurse,t)
+      end
+    end
   else
-   local root,path,base=lpegmatch(pattern,str) 
-   if root and path and base then
-    local recurse=find(base,"**",1,true) 
-    local start=root..path
-    local result=lpegmatch(filter,start..base)
-    globpattern(start,result,recurse,t)
-   end
+    if type(str)=="table" then
+      local t=t or {}
+      for s=1,#str do
+        glob(str[s],t)
+      end
+      return t
+    elseif isfile(str) then
+      if t then
+        t[#t+1]=str
+        return t
+      else
+        return { str }
+      end
+    else
+      local root,path,base=lpegmatch(pattern,str) 
+      if root and path and base then
+        local recurse=find(base,"**",1,true) 
+        local start=root..path
+        local result=lpegmatch(filter,start..base)
+        return globpattern(start,result,recurse,t)
+      else
+        return {}
+      end
+    end
   end
- else
-  if type(str)=="table" then
-   local t=t or {}
-   for s=1,#str do
-    glob(str[s],t)
-   end
-   return t
-  elseif isfile(str) then
-   if t then
-    t[#t+1]=str
-    return t
-   else
-    return { str }
-   end
-  else
-   local root,path,base=lpegmatch(pattern,str) 
-   if root and path and base then
-    local recurse=find(base,"**",1,true) 
-    local start=root..path
-    local result=lpegmatch(filter,start..base)
-    return globpattern(start,result,recurse,t)
-   else
-    return {}
-   end
-  end
- end
 end
 dir.glob=glob
 local function globfiles(path,recurse,func,files) 
- if type(func)=="string" then
-  local s=func
-  func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
-  if find(name,"^%.") then
-  else
-   local mode=attributes(name,'mode')
-   if mode=="directory" then
-    if recurse then
-     globfiles(path.."/"..name,recurse,func,files)
+  if type(func)=="string" then
+    local s=func
+    func=function(name) return find(name,s) end
+  end
+  files=files or {}
+  local noffiles=#files
+  for name in walkdir(path) do
+    if find(name,"^%.") then
+    else
+      local mode=attributes(name,'mode')
+      if mode=="directory" then
+        if recurse then
+          globfiles(path.."/"..name,recurse,func,files)
+        end
+      elseif mode=="file" then
+        if not func or func(name) then
+          noffiles=noffiles+1
+          files[noffiles]=path.."/"..name
+        end
+      end
     end
-   elseif mode=="file" then
-    if not func or func(name) then
-     noffiles=noffiles+1
-     files[noffiles]=path.."/"..name
-    end
-   end
   end
- end
- return files
+  return files
 end
 dir.globfiles=globfiles
 local function globdirs(path,recurse,func,files) 
- if type(func)=="string" then
-  local s=func
-  func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
-  if find(name,"^%.") then
-  else
-   local mode=attributes(name,'mode')
-   if mode=="directory" then
-    if not func or func(name) then
-     noffiles=noffiles+1
-     files[noffiles]=path.."/"..name
-     if recurse then
-      globdirs(path.."/"..name,recurse,func,files)
-     end
+  if type(func)=="string" then
+    local s=func
+    func=function(name) return find(name,s) end
+  end
+  files=files or {}
+  local noffiles=#files
+  for name in walkdir(path) do
+    if find(name,"^%.") then
+    else
+      local mode=attributes(name,'mode')
+      if mode=="directory" then
+        if not func or func(name) then
+          noffiles=noffiles+1
+          files[noffiles]=path.."/"..name
+          if recurse then
+            globdirs(path.."/"..name,recurse,func,files)
+          end
+        end
+      end
     end
-   end
   end
- end
- return files
+  return files
 end
 dir.globdirs=globdirs
 function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+  return concat(glob(pattern),"\n")
 end
 local make_indeed=true 
 if onwindows then
- function dir.mkdirs(...)
-  local n=select("#",...)
-  local str
-  if n==1 then
-   str=select(1,...)
-   if isdir(str) then
-    return str,true
-   end
-  else
-   str=""
-   for i=1,n do
-    local s=select(i,...)
-    if s=="" then
-    elseif str=="" then
-     str=s
+  function dir.mkdirs(...)
+    local n=select("#",...)
+    local str
+    if n==1 then
+      str=select(1,...)
+      if isdir(str) then
+        return str,true
+      end
     else
-     str=str.."/"..s
+      str=""
+      for i=1,n do
+        local s=select(i,...)
+        if s=="" then
+        elseif str=="" then
+          str=s
+        else
+          str=str.."/"..s
+        end
+      end
     end
-   end
-  end
-  local pth=""
-  local drive=false
-  local first,middle,last=match(str,"^(//)(//*)(.*)$")
-  if first then
-  else
-   first,last=match(str,"^(//)/*(.-)$")
-   if first then
-    middle,last=match(str,"([^/]+)/+(.-)$")
-    if middle then
-     pth="//"..middle
-    else
-     pth="//"..last
-     last=""
-    end
-   else
-    first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+    local pth=""
+    local drive=false
+    local first,middle,last=match(str,"^(//)(//*)(.*)$")
     if first then
-     pth,drive=first..middle,true
     else
-     middle,last=match(str,"^(/*)(.-)$")
-     if not middle then
-      last=str
-     end
+      first,last=match(str,"^(//)/*(.-)$")
+      if first then
+        middle,last=match(str,"([^/]+)/+(.-)$")
+        if middle then
+          pth="//"..middle
+        else
+          pth="//"..last
+          last=""
+        end
+      else
+        first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+        if first then
+          pth,drive=first..middle,true
+        else
+          middle,last=match(str,"^(/*)(.-)$")
+          if not middle then
+            last=str
+          end
+        end
+      end
     end
-   end
+    for s in gmatch(last,"[^/]+") do
+      if pth=="" then
+        pth=s
+      elseif drive then
+        pth,drive=pth..s,false
+      else
+        pth=pth.."/"..s
+      end
+      if make_indeed and not isdir(pth) then
+        mkdir(pth)
+      end
+    end
+    return pth,(isdir(pth)==true)
   end
-  for s in gmatch(last,"[^/]+") do
-   if pth=="" then
-    pth=s
-   elseif drive then
-    pth,drive=pth..s,false
-   else
-    pth=pth.."/"..s
-   end
-   if make_indeed and not isdir(pth) then
-    mkdir(pth)
-   end
-  end
-  return pth,(isdir(pth)==true)
- end
 else
- function dir.mkdirs(...)
-  local n=select("#",...)
-  local str,pth
-  if n==1 then
-   str=select(1,...)
-   if isdir(str) then
-    return str,true
-   end
-  else
-   str=""
-   for i=1,n do
-    local s=select(i,...)
-    if s and s~="" then 
-     if str~="" then
-      str=str.."/"..s
-     else
-      str=s
-     end
+  function dir.mkdirs(...)
+    local n=select("#",...)
+    local str,pth
+    if n==1 then
+      str=select(1,...)
+      if isdir(str) then
+        return str,true
+      end
+    else
+      str=""
+      for i=1,n do
+        local s=select(i,...)
+        if s and s~="" then 
+          if str~="" then
+            str=str.."/"..s
+          else
+            str=s
+          end
+        end
+      end
     end
-   end
-  end
-  str=gsub(str,"/+","/")
-  if find(str,"^/") then
-   pth="/"
-   for s in gmatch(str,"[^/]+") do
-    local first=(pth=="/")
-    if first then
-     pth=pth..s
+    str=gsub(str,"/+","/")
+    if find(str,"^/") then
+      pth="/"
+      for s in gmatch(str,"[^/]+") do
+        local first=(pth=="/")
+        if first then
+          pth=pth..s
+        else
+          pth=pth.."/"..s
+        end
+        if make_indeed and not first and not isdir(pth) then
+          mkdir(pth)
+        end
+      end
     else
-     pth=pth.."/"..s
+      pth="."
+      for s in gmatch(str,"[^/]+") do
+        pth=pth.."/"..s
+        if make_indeed and not isdir(pth) then
+          mkdir(pth)
+        end
+      end
     end
-    if make_indeed and not first and not isdir(pth) then
-     mkdir(pth)
-    end
-   end
-  else
-   pth="."
-   for s in gmatch(str,"[^/]+") do
-    pth=pth.."/"..s
-    if make_indeed and not isdir(pth) then
-     mkdir(pth)
-    end
-   end
+    return pth,(isdir(pth)==true)
   end
-  return pth,(isdir(pth)==true)
- end
 end
 dir.makedirs=dir.mkdirs
 do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
-  local xcurrentdir=dir.current
-  function dir.expandname(str) 
-   local first,nothing,last=match(str,"^(//)(//*)(.*)$")
-   if first then
-    first=xcurrentdir().."/" 
-   end
-   if not first then
-    first,last=match(str,"^(//)/*(.*)$")
-   end
-   if not first then
-    first,last=match(str,"^([a-zA-Z]:)(.*)$")
-    if first and not find(last,"^/") then
-     local d=currentdir() 
-     if chdir(first) then
-      first=xcurrentdir() 
-     end
-     chdir(d)
+  local chdir=sandbox and sandbox.original(chdir) or chdir
+  if onwindows then
+    local xcurrentdir=dir.current
+    function dir.expandname(str) 
+      local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+      if first then
+        first=xcurrentdir().."/" 
+      end
+      if not first then
+        first,last=match(str,"^(//)/*(.*)$")
+      end
+      if not first then
+        first,last=match(str,"^([a-zA-Z]:)(.*)$")
+        if first and not find(last,"^/") then
+          local d=currentdir() 
+          if chdir(first) then
+            first=xcurrentdir() 
+          end
+          chdir(d)
+        end
+      end
+      if not first then
+        first,last=xcurrentdir(),str
+      end
+      last=gsub(last,"//","/")
+      last=gsub(last,"/%./","/")
+      last=gsub(last,"^/*","")
+      first=gsub(first,"/*$","")
+      if last=="" or last=="." then
+        return first
+      else
+        return first.."/"..last
+      end
     end
-   end
-   if not first then
-    first,last=xcurrentdir(),str
-   end
-   last=gsub(last,"//","/")
-   last=gsub(last,"/%./","/")
-   last=gsub(last,"^/*","")
-   first=gsub(first,"/*$","")
-   if last=="" or last=="." then
-    return first
-   else
-    return first.."/"..last
-   end
+  else
+    function dir.expandname(str) 
+      if not find(str,"^/") then
+        str=currentdir().."/"..str
+      end
+      str=gsub(str,"//","/")
+      str=gsub(str,"/%./","/")
+      str=gsub(str,"(.)/%.$","%1")
+      return str
+    end
   end
- else
-  function dir.expandname(str) 
-   if not find(str,"^/") then
-    str=currentdir().."/"..str
-   end
-   str=gsub(str,"//","/")
-   str=gsub(str,"/%./","/")
-   str=gsub(str,"(.)/%.$","%1")
-   return str
-  end
- end
 end
 file.expandname=dir.expandname 
 local stack={}
 function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
-  chdir(newdir)
-  return newdir
- else
-  return curdir
- end
+  local curdir=currentdir()
+  insert(stack,curdir)
+  if newdir and newdir~="" then
+    chdir(newdir)
+    return newdir
+  else
+    return curdir
+  end
 end
 function dir.pop()
- local d=remove(stack)
- if d then
-  chdir(d)
- end
- return d
+  local d=remove(stack)
+  if d then
+    chdir(d)
+  end
+  return d
 end
 local function found(...) 
- for i=1,select("#",...) do
-  local path=select(i,...)
-  local kind=type(path)
-  if kind=="string" then
-   if isdir(path) then
-    return path
-   end
-  elseif kind=="table" then
-   local path=found(unpack(path))
-   if path then
-    return path
-   end
+  for i=1,select("#",...) do
+    local path=select(i,...)
+    local kind=type(path)
+    if kind=="string" then
+      if isdir(path) then
+        return path
+      end
+    elseif kind=="table" then
+      local path=found(unpack(path))
+      if path then
+        return path
+      end
+    end
   end
- end
 end
 dir.found=found
 
@@ -5562,69 +5235,69 @@
 
 package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
 
--- original size: 1850, stripped down to: 1498
+-- original size: 1850, stripped down to: 1568
 
 if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type,tonumber=type,tonumber
 boolean=boolean or {}
 local boolean=boolean
 function boolean.tonumber(b)
- if b then return 1 else return 0 end 
+  if b then return 1 else return 0 end 
 end
 function toboolean(str,tolerant) 
- if  str==nil then
-  return false
- elseif str==false then
-  return false
- elseif str==true then
-  return true
- elseif str=="true" then
-  return true
- elseif str=="false" then
-  return false
- elseif not tolerant then
-  return false
- elseif str==0 then
-  return false
- elseif (tonumber(str) or 0)>0 then
-  return true
- else
-  return str=="yes" or str=="on" or str=="t"
- end
+  if str==nil then
+    return false
+  elseif str==false then
+    return false
+  elseif str==true then
+    return true
+  elseif str=="true" then
+    return true
+  elseif str=="false" then
+    return false
+  elseif not tolerant then
+    return false
+  elseif str==0 then
+    return false
+  elseif (tonumber(str) or 0)>0 then
+    return true
+  else
+    return str=="yes" or str=="on" or str=="t"
+  end
 end
 string.toboolean=toboolean
 function string.booleanstring(str)
- if str=="0" then
-  return false
- elseif str=="1" then
-  return true
- elseif str=="" then
-  return false
- elseif str=="false" then
-  return false
- elseif str=="true" then
-  return true
- elseif (tonumber(str) or 0)>0 then
-  return true
- else
-  return str=="yes" or str=="on" or str=="t"
- end
+  if str=="0" then
+    return false
+  elseif str=="1" then
+    return true
+  elseif str=="" then
+    return false
+  elseif str=="false" then
+    return false
+  elseif str=="true" then
+    return true
+  elseif (tonumber(str) or 0)>0 then
+    return true
+  else
+    return str=="yes" or str=="on" or str=="t"
+  end
 end
 function string.is_boolean(str,default,strict)
- if type(str)=="string" then
-  if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
-   return true
-  elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
-   return false
+  if type(str)=="string" then
+    if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+      return true
+    elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+      return false
+    end
   end
- end
- return default
+  return default
 end
 
 
@@ -5634,24 +5307,18 @@
 
 package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
 
--- original size: 41047, stripped down to: 17171
+-- original size: 40036, stripped down to: 17837
 
 if not modules then modules={} end modules ['l-unicode']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
-utf=utf or {}
-unicode=nil
-if not string.utfcharacters then
- local gmatch=string.gmatch
- function string.characters(str)
-  return gmatch(str,".[\128-\191]*")
- end
-end
-utf.characters=string.utfcharacters
+utf=utf or (unicode and unicode.utf8) or {}
+utf.characters=utf.characters or string.utfcharacters
+utf.values=utf.values   or string.utfvalues
 local type=type
 local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
 local concat=table.concat
@@ -5662,340 +5329,345 @@
 local bytepairs=string.bytepairs
 local finder=lpeg.finder
 local replacer=lpeg.replacer
+local utfvalues=utf.values
+local utfgmatch=utf.gmatch 
 local p_utftype=patterns.utftype
 local p_utfstricttype=patterns.utfstricttype
 local p_utfoffset=patterns.utfoffset
-local p_utf8character=patterns.utf8character
-local p_utf8char=patterns.utf8char
+local p_utf8char=patterns.utf8character
 local p_utf8byte=patterns.utf8byte
 local p_utfbom=patterns.utfbom
 local p_newline=patterns.newline
 local p_whitespace=patterns.whitespace
+if not unicode then
+  unicode={ utf=utf } 
+end
 if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
-  local char=string.char
-  if bit32 then
-   local rshift=bit32.rshift
-   function utf.char(n)
-    if n<0x80 then
-     return char(n)
-    elseif n<0x800 then
-     return char(
-      0xC0+rshift(n,6),
-      0x80+(n%0x40)
-     )
-    elseif n<0x10000 then
-     return char(
-      0xE0+rshift(n,12),
-      0x80+(rshift(n,6)%0x40),
-      0x80+(n%0x40)
-     )
-    elseif n<0x200000 then
-     return char(
-      0xF0+rshift(n,18),
-      0x80+(rshift(n,12)%0x40),
-      0x80+(rshift(n,6)%0x40),
-      0x80+(n%0x40)
-     )
+  utf.char=string.utfcharacter or (utf8 and utf8.char)
+  if not utf.char then
+    local char=string.char
+    if bit32 then
+      local rshift=bit32.rshift
+      function utf.char(n)
+        if n<0x80 then
+          return char(n)
+        elseif n<0x800 then
+          return char(
+            0xC0+rshift(n,6),
+            0x80+(n%0x40)
+          )
+        elseif n<0x10000 then
+          return char(
+            0xE0+rshift(n,12),
+            0x80+(rshift(n,6)%0x40),
+            0x80+(n%0x40)
+          )
+        elseif n<0x200000 then
+          return char(
+            0xF0+rshift(n,18),
+            0x80+(rshift(n,12)%0x40),
+            0x80+(rshift(n,6)%0x40),
+            0x80+(n%0x40)
+          )
+        else
+          return ""
+        end
+      end
     else
-     return ""
+      local floor=math.floor
+      function utf.char(n)
+        if n<0x80 then
+          return char(n)
+        elseif n<0x800 then
+          return char(
+            0xC0+floor(n/0x40),
+            0x80+(n%0x40)
+          )
+        elseif n<0x10000 then
+          return char(
+            0xE0+floor(n/0x1000),
+            0x80+(floor(n/0x40)%0x40),
+            0x80+(n%0x40)
+          )
+        elseif n<0x200000 then
+          return char(
+            0xF0+floor(n/0x40000),
+            0x80+(floor(n/0x1000)%0x40),
+            0x80+(floor(n/0x40)%0x40),
+            0x80+(n%0x40)
+          )
+        else
+          return ""
+        end
+      end
     end
-   end
-  else
-   local floor=math.floor
-   function utf.char(n)
-    if n<0x80 then
-     return char(n)
-    elseif n<0x800 then
-     return char(
-      0xC0+floor(n/0x40),
-      0x80+(n%0x40)
-     )
-    elseif n<0x10000 then
-     return char(
-      0xE0+floor(n/0x1000),
-      0x80+(floor(n/0x40)%0x40),
-      0x80+(n%0x40)
-     )
-    elseif n<0x200000 then
-     return char(
-      0xF0+floor(n/0x40000),
-      0x80+(floor(n/0x1000)%0x40),
-      0x80+(floor(n/0x40)%0x40),
-      0x80+(n%0x40)
-     )
-    else
-     return ""
-    end
-   end
   end
- end
 end
 if not utf.byte then
- utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
- if not utf.byte then
-  function utf.byte(c)
-   return lpegmatch(p_utf8byte,c)
+  utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+  if not utf.byte then
+    local utf8byte=patterns.utf8byte
+    function utf.byte(c)
+      return lpegmatch(utf8byte,c)
+    end
   end
- end
 end
 local utfchar,utfbyte=utf.char,utf.byte
 function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+  return data and lpegmatch(p_utftype,data) or "unknown"
 end
 local toentities=Cs (
- (
-  patterns.utf8one+(
-    patterns.utf8two+patterns.utf8three+patterns.utf8four
-   )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+  (
+    patterns.utf8one+(
+        patterns.utf8two+patterns.utf8three+patterns.utf8four
+      )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+  )^0
 )
 patterns.toentities=toentities
 function utf.toentities(str)
- return lpegmatch(toentities,str)
+  return lpegmatch(toentities,str)
 end
 local one=P(1)
 local two=C(1)*C(1)
 local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
 local pattern=P("\254\255")*Cs((
-     four/function(a,b,c,d)
-        local ab=0xFF*byte(a)+byte(b)
-        local cd=0xFF*byte(c)+byte(d)
-        return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
-       end+two/function(a,b)
-        return utfchar(byte(a)*256+byte(b))
-       end+one
-    )^1 )+P("\255\254")*Cs((
-     four/function(b,a,d,c)
-        local ab=0xFF*byte(a)+byte(b)
-        local cd=0xFF*byte(c)+byte(d)
-        return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
-       end+two/function(b,a)
-        return utfchar(byte(a)*256+byte(b))
-       end+one
-    )^1 )
+          four/function(a,b,c,d)
+                local ab=0xFF*byte(a)+byte(b)
+                local cd=0xFF*byte(c)+byte(d)
+                return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+              end+two/function(a,b)
+                return utfchar(byte(a)*256+byte(b))
+              end+one
+        )^1 )+P("\255\254")*Cs((
+          four/function(b,a,d,c)
+                local ab=0xFF*byte(a)+byte(b)
+                local cd=0xFF*byte(c)+byte(d)
+                return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+              end+two/function(b,a)
+                return utfchar(byte(a)*256+byte(b))
+              end+one
+        )^1 )
 function string.toutf(s) 
- return lpegmatch(pattern,s) or s 
+  return lpegmatch(pattern,s) or s 
 end
 local validatedutf=Cs (
- (
-  patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+  (
+    patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+  )^0
 )
 patterns.validatedutf=validatedutf
 function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+  return type(str)=="string" and lpegmatch(validatedutf,str) or false
 end
 if not utf.len then
- utf.len=string.utflength or (utf8 and utf8.len)
- if not utf.len then
-  local n,f=0,1
-  local utfcharcounter=patterns.utfbom^-1*Cmt (
-   Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
-   function(_,t,d) 
-    n=n+(t-f)/d
-    f=t
-    return true
-   end
-  )^0
-  function utf.len(str)
-   n,f=0,1
-   lpegmatch(utfcharcounter,str or "")
-   return n
+  utf.len=string.utflength or (utf8 and utf8.len)
+  if not utf.len then
+    local n,f=0,1
+    local utfcharcounter=patterns.utfbom^-1*Cmt (
+      Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+      function(_,t,d) 
+        n=n+(t-f)/d
+        f=t
+        return true
+      end
+    )^0
+    function utf.len(str)
+      n,f=0,1
+      lpegmatch(utfcharcounter,str or "")
+      return n
+    end
   end
- end
 end
 utf.length=utf.len
 if not utf.sub then
- local utflength=utf.length
- local b,e,n,first,last=0,0,0,0,0
- local function slide_zero(s,p)
-  n=n+1
-  if n>=last then
-   e=p-1
-  else
-   return p
+  local utflength=utf.length
+  local b,e,n,first,last=0,0,0,0,0
+  local function slide_zero(s,p)
+    n=n+1
+    if n>=last then
+      e=p-1
+    else
+      return p
+    end
   end
- end
- local function slide_one(s,p)
-  n=n+1
-  if n==first then
-   b=p
+  local function slide_one(s,p)
+    n=n+1
+    if n==first then
+      b=p
+    end
+    if n>=last then
+      e=p-1
+    else
+      return p
+    end
   end
-  if n>=last then
-   e=p-1
-  else
-   return p
-  end
- end
- local function slide_two(s,p)
-  n=n+1
-  if n==first then
-   b=p
-  else
-   return true
-  end
- end
- local pattern_zero=Cmt(p_utf8character,slide_zero)^0
- local pattern_one=Cmt(p_utf8character,slide_one )^0
- local pattern_two=Cmt(p_utf8character,slide_two )^0
- local pattern_first=C(p_utf8character)
- function utf.sub(str,start,stop)
-  if not start then
-   return str
-  end
-  if start==0 then
-   start=1
-  end
-  if not stop then
-   if start<0 then
-    local l=utflength(str) 
-    start=l+start
-   else
-    start=start-1
-   end
-   b,n,first=0,0,start
-   lpegmatch(pattern_two,str)
-   if n>=first then
-    return sub(str,b)
-   else
-    return ""
-   end
-  end
-  if start<0 or stop<0 then
-   local l=utf.length(str)
-   if start<0 then
-    start=l+start
-    if start<=0 then
-     start=1
+  local function slide_two(s,p)
+    n=n+1
+    if n==first then
+      b=p
     else
-     start=start+1
+      return true
     end
-   end
-   if stop<0 then
-    stop=l+stop
-    if stop==0 then
-     stop=1
+  end
+  local pattern_zero=Cmt(p_utf8char,slide_zero)^0
+  local pattern_one=Cmt(p_utf8char,slide_one )^0
+  local pattern_two=Cmt(p_utf8char,slide_two )^0
+  local pattern_first=C(patterns.utf8character)
+  function utf.sub(str,start,stop)
+    if not start then
+      return str
+    end
+    if start==0 then
+      start=1
+    end
+    if not stop then
+      if start<0 then
+        local l=utflength(str) 
+        start=l+start
+      else
+        start=start-1
+      end
+      b,n,first=0,0,start
+      lpegmatch(pattern_two,str)
+      if n>=first then
+        return sub(str,b)
+      else
+        return ""
+      end
+    end
+    if start<0 or stop<0 then
+      local l=utf.length(str)
+      if start<0 then
+        start=l+start
+        if start<=0 then
+          start=1
+        else
+          start=start+1
+        end
+      end
+      if stop<0 then
+        stop=l+stop
+        if stop==0 then
+          stop=1
+        else
+          stop=stop+1
+        end
+      end
+    end
+    if start==1 and stop==1 then
+      return lpegmatch(pattern_first,str) or ""
+    elseif start>stop then
+      return ""
+    elseif start>1 then
+      b,e,n,first,last=0,0,0,start-1,stop
+      lpegmatch(pattern_one,str)
+      if n>=first and e==0 then
+        e=#str
+      end
+      return sub(str,b,e)
     else
-     stop=stop+1
+      b,e,n,last=1,0,0,stop
+      lpegmatch(pattern_zero,str)
+      if e==0 then
+        e=#str
+      end
+      return sub(str,b,e)
     end
-   end
   end
-  if start==1 and stop==1 then
-   return lpegmatch(pattern_first,str) or ""
-  elseif start>stop then
-   return ""
-  elseif start>1 then
-   b,e,n,first,last=0,0,0,start-1,stop
-   lpegmatch(pattern_one,str)
-   if n>=first and e==0 then
-    e=#str
-   end
-   return sub(str,b,e)
-  else
-   b,e,n,last=1,0,0,stop
-   lpegmatch(pattern_zero,str)
-   if e==0 then
-    e=#str
-   end
-   return sub(str,b,e)
-  end
- end
 end
 function utf.remapper(mapping,option,action) 
- local variant=type(mapping)
- if variant=="table" then
-  action=action or mapping
-  if option=="dynamic" then
-   local pattern=false
-   table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
-   return function(str)
-    if not str or str=="" then
-     return ""
+  local variant=type(mapping)
+  if variant=="table" then
+    action=action or mapping
+    if option=="dynamic" then
+      local pattern=false
+      table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+      return function(str)
+        if not str or str=="" then
+          return ""
+        else
+          if not pattern then
+            pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0)
+          end
+          return lpegmatch(pattern,str)
+        end
+      end
+    elseif option=="pattern" then
+      return Cs((tabletopattern(mapping)/action+p_utf8char)^0)
     else
-     if not pattern then
-      pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
-     end
-     return lpegmatch(pattern,str)
+      local pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0)
+      return function(str)
+        if not str or str=="" then
+          return ""
+        else
+          return lpegmatch(pattern,str)
+        end
+      end,pattern
     end
-   end
-  elseif option=="pattern" then
-   return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
-  else
-   local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
-   return function(str)
-    if not str or str=="" then
-     return ""
+  elseif variant=="function" then
+    if option=="pattern" then
+      return Cs((p_utf8char/mapping+p_utf8char)^0)
     else
-     return lpegmatch(pattern,str)
+      local pattern=Cs((p_utf8char/mapping+p_utf8char)^0)
+      return function(str)
+        if not str or str=="" then
+          return ""
+        else
+          return lpegmatch(pattern,str)
+        end
+      end,pattern
     end
-   end,pattern
-  end
- elseif variant=="function" then
-  if option=="pattern" then
-   return Cs((p_utf8character/mapping+p_utf8character)^0)
   else
-   local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
-   return function(str)
-    if not str or str=="" then
-     return ""
-    else
-     return lpegmatch(pattern,str)
+    return function(str)
+      return str or ""
     end
-   end,pattern
   end
- else
+end
+function utf.replacer(t) 
+  local r=replacer(t,false,false,true)
   return function(str)
-   return str or ""
+    return lpegmatch(r,str)
   end
- end
 end
-function utf.replacer(t) 
- local r=replacer(t,false,false,true)
- return function(str)
-  return lpegmatch(r,str)
- end
-end
 function utf.subtituter(t) 
- local f=finder  (t)
- local r=replacer(t,false,false,true)
- return function(str)
-  local i=lpegmatch(f,str)
-  if not i then
-   return str
-  elseif i>#str then
-   return str
-  else
-   return lpegmatch(r,str)
+  local f=finder (t)
+  local r=replacer(t,false,false,true)
+  return function(str)
+    local i=lpegmatch(f,str)
+    if not i then
+      return str
+    elseif i>#str then
+      return str
+    else
+      return lpegmatch(r,str)
+    end
   end
- end
 end
 local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
-local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
-local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
-local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
+local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8char)^0)
+local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8char))^0)
+local utfcharsplitter_raw=Ct(C(p_utf8char)^0)
 patterns.utflinesplitter=utflinesplitter
 function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+  return lpegmatch(utflinesplitter,str or "")
 end
 function utf.split(str,ignorewhitespace) 
- if ignorewhitespace then
-  return lpegmatch(utfcharsplitter_iws,str or "")
- else
-  return lpegmatch(utfcharsplitter_ows,str or "")
- end
+  if ignorewhitespace then
+    return lpegmatch(utfcharsplitter_iws,str or "")
+  else
+    return lpegmatch(utfcharsplitter_ows,str or "")
+  end
 end
 function utf.totable(str) 
- return lpegmatch(utfcharsplitter_raw,str)
+  return lpegmatch(utfcharsplitter_raw,str)
 end
 function utf.magic(f) 
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
-  f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+  local str=f:read(4) or ""
+  local off=lpegmatch(p_utfoffset,str)
+  if off<4 then
+    f:seek('set',off)
+  end
+  return lpegmatch(p_utftype,str)
 end
 local utf16_to_utf8_be,utf16_to_utf8_le
 local utf32_to_utf8_be,utf32_to_utf8_le
@@ -6009,36 +5681,36 @@
 local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
 local more=0
 local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
- local now=256*byte(left)+byte(right)
- if more>0 then
-  now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
-  more=0
-  return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
-  more=now
-  return "" 
- else
-  return utfchar(now)
- end
+  local now=256*byte(left)+byte(right)
+  if more>0 then
+    now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 
+    more=0
+    return utfchar(now)
+  elseif now>=0xD800 and now<=0xDBFF then
+    more=now
+    return "" 
+  else
+    return utfchar(now)
+  end
 end
 local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
- local now=256*byte(left)+byte(right)
- if more>0 then
-  now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
-  more=0
-  return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
-  more=now
-  return "" 
- else
-  return utfchar(now)
- end
+  local now=256*byte(left)+byte(right)
+  if more>0 then
+    now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 
+    more=0
+    return utfchar(now)
+  elseif now>=0xD800 and now<=0xDBFF then
+    more=now
+    return "" 
+  else
+    return utfchar(now)
+  end
 end
 local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+  return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
 end
 local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+  return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
 end
 p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
 p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
@@ -6049,88 +5721,88 @@
 patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
 patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
 utf16_to_utf8_be=function(s)
- if s and s~="" then
-  return lpegmatch(p_utf16_to_utf8_be,s)
- else
-  return s
- end
+  if s and s~="" then
+    return lpegmatch(p_utf16_to_utf8_be,s)
+  else
+    return s
+  end
 end
 local utf16_to_utf8_be_t=function(t)
- if not t then
-  return nil
- elseif type(t)=="string" then
-  t=lpegmatch(utf_16_be_linesplitter,t)
- end
- for i=1,#t do
-  local s=t[i]
-  if s~="" then
-   t[i]=lpegmatch(p_utf16_to_utf8_be,s)
+  if not t then
+    return nil
+  elseif type(t)=="string" then
+    t=lpegmatch(utf_16_be_linesplitter,t)
   end
- end
- return t
+  for i=1,#t do
+    local s=t[i]
+    if s~="" then
+      t[i]=lpegmatch(p_utf16_to_utf8_be,s)
+    end
+  end
+  return t
 end
 utf16_to_utf8_le=function(s)
- if s and s~="" then
-  return lpegmatch(p_utf16_to_utf8_le,s)
- else
-  return s
- end
+  if s and s~="" then
+    return lpegmatch(p_utf16_to_utf8_le,s)
+  else
+    return s
+  end
 end
 local utf16_to_utf8_le_t=function(t)
- if not t then
-  return nil
- elseif type(t)=="string" then
-  t=lpegmatch(utf_16_le_linesplitter,t)
- end
- for i=1,#t do
-  local s=t[i]
-  if s~="" then
-   t[i]=lpegmatch(p_utf16_to_utf8_le,s)
+  if not t then
+    return nil
+  elseif type(t)=="string" then
+    t=lpegmatch(utf_16_le_linesplitter,t)
   end
- end
- return t
+  for i=1,#t do
+    local s=t[i]
+    if s~="" then
+      t[i]=lpegmatch(p_utf16_to_utf8_le,s)
+    end
+  end
+  return t
 end
 utf32_to_utf8_be=function(s)
- if s and s~="" then
-  return lpegmatch(p_utf32_to_utf8_be,s)
- else
-  return s
- end
+  if s and s~="" then
+    return lpegmatch(p_utf32_to_utf8_be,s)
+  else
+    return s
+  end
 end
 local utf32_to_utf8_be_t=function(t)
- if not t then
-  return nil
- elseif type(t)=="string" then
-  t=lpegmatch(utf_32_be_linesplitter,t)
- end
- for i=1,#t do
-  local s=t[i]
-  if s~="" then
-   t[i]=lpegmatch(p_utf32_to_utf8_be,s)
+  if not t then
+    return nil
+  elseif type(t)=="string" then
+    t=lpegmatch(utf_32_be_linesplitter,t)
   end
- end
- return t
+  for i=1,#t do
+    local s=t[i]
+    if s~="" then
+      t[i]=lpegmatch(p_utf32_to_utf8_be,s)
+    end
+  end
+  return t
 end
 utf32_to_utf8_le=function(s)
- if s and s~="" then
-  return lpegmatch(p_utf32_to_utf8_le,s)
- else
-  return s
- end
+  if s and s~="" then
+    return lpegmatch(p_utf32_to_utf8_le,s)
+  else
+    return s
+  end
 end
 local utf32_to_utf8_le_t=function(t)
- if not t then
-  return nil
- elseif type(t)=="string" then
-  t=lpegmatch(utf_32_le_linesplitter,t)
- end
- for i=1,#t do
-  local s=t[i]
-  if s~="" then
-   t[i]=lpegmatch(p_utf32_to_utf8_le,s)
+  if not t then
+    return nil
+  elseif type(t)=="string" then
+    t=lpegmatch(utf_32_le_linesplitter,t)
   end
- end
- return t
+  for i=1,#t do
+    local s=t[i]
+    if s~="" then
+      t[i]=lpegmatch(p_utf32_to_utf8_le,s)
+    end
+  end
+  return t
 end
 utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
 utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -6141,226 +5813,190 @@
 utf.utf32_to_utf8_le=utf32_to_utf8_le
 utf.utf32_to_utf8_be=utf32_to_utf8_be
 function utf.utf8_to_utf8_t(t)
- return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+  return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
 end
 function utf.utf16_to_utf8_t(t,endian)
- return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+  return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
 end
 function utf.utf32_to_utf8_t(t,endian)
- return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+  return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
 end
 local function little(b)
- if b<0x10000 then
-  return char(b%256,rshift(b,8))
- else
-  b=b-0x10000
-  local b1=rshift(b,10)+0xD800
-  local b2=b%1024+0xDC00
-  return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
- end
+  if b<0x10000 then
+    return char(b%256,rshift(b,8))
+  else
+    b=b-0x10000
+    local b1=rshift(b,10)+0xD800
+    local b2=b%1024+0xDC00
+    return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+  end
 end
 local function big(b)
- if b<0x10000 then
-  return char(rshift(b,8),b%256)
- else
-  b=b-0x10000
-  local b1=rshift(b,10)+0xD800
-  local b2=b%1024+0xDC00
-  return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
- end
+  if b<0x10000 then
+    return char(rshift(b,8),b%256)
+  else
+    b=b-0x10000
+    local b1=rshift(b,10)+0xD800
+    local b2=b%1024+0xDC00
+    return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+  end
 end
 local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
 local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
 local function utf8_to_utf16_be(str,nobom)
- if nobom then
-  return lpegmatch(b_remap,str)
- else
-  return char(254,255)..lpegmatch(b_remap,str)
- end
+  if nobom then
+    return lpegmatch(b_remap,str)
+  else
+    return char(254,255)..lpegmatch(b_remap,str)
+  end
 end
 local function utf8_to_utf16_le(str,nobom)
- if nobom then
-  return lpegmatch(l_remap,str)
- else
-  return char(255,254)..lpegmatch(l_remap,str)
- end
+  if nobom then
+    return lpegmatch(l_remap,str)
+  else
+    return char(255,254)..lpegmatch(l_remap,str)
+  end
 end
 utf.utf8_to_utf16_be=utf8_to_utf16_be
 utf.utf8_to_utf16_le=utf8_to_utf16_le
 function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
-  return utf8_to_utf16_le(str,nobom)
- else
-  return utf8_to_utf16_be(str,nobom)
- end
+  if littleendian then
+    return utf8_to_utf16_le(str,nobom)
+  else
+    return utf8_to_utf16_be(str,nobom)
+  end
 end
 local pattern=Cs (
- (p_utf8byte/function(unicode    ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+  (p_utf8byte/function(unicode     ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
 )
 function utf.tocodes(str,separator)
- return lpegmatch(pattern,str,1,separator or " ")
+  return lpegmatch(pattern,str,1,separator or " ")
 end
 function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+  return format("U+%05X",type(s)=="number" and s or utfbyte(s))
 end
 function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+  return format("0x%05X",type(s)=="number" and s or utfbyte(s))
 end
 function utf.toeight(str)
- if not str or str=="" then
-  return nil
- end
- local utftype=lpegmatch(p_utfstricttype,str)
- if utftype=="utf-8" then
-  return sub(str,4)      
- elseif utftype=="utf-16-be" then
-  return utf16_to_utf8_be(str) 
- elseif utftype=="utf-16-le" then
-  return utf16_to_utf8_le(str) 
- else
-  return str
- end
+  if not str or str=="" then
+    return nil
+  end
+  local utftype=lpegmatch(p_utfstricttype,str)
+  if utftype=="utf-8" then
+    return sub(str,4)        
+  elseif utftype=="utf-16-be" then
+    return utf16_to_utf8_be(str)  
+  elseif utftype=="utf-16-le" then
+    return utf16_to_utf8_le(str)  
+  else
+    return str
+  end
 end
-do
- local p_nany=p_utf8character/""
- local cache={}
- function utf.count(str,what)
-  if type(what)=="string" then
-   local p=cache[what]
-   if not p then
-    p=Cs((P(what)/" "+p_nany)^0)
-    cache[p]=p
-   end
-   return #lpegmatch(p,str)
-  else 
-   return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
+local p_nany=p_utf8char/""
+if utfgmatch then
+  function utf.count(str,what)
+    if type(what)=="string" then
+      local n=0
+      for _ in utfgmatch(str,what) do
+        n=n+1
+      end
+      return n
+    else 
+      return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
+    end
   end
- end
+else
+  local cache={}
+  function utf.count(str,what)
+    if type(what)=="string" then
+      local p=cache[what]
+      if not p then
+        p=Cs((P(what)/" "+p_nany)^0)
+        cache[p]=p
+      end
+      return #lpegmatch(p,str)
+    else 
+      return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
+    end
+  end
 end
-if not string.utfvalues then
- local find=string.find
- local dummy=function()
- end
- function string.utfvalues(str)
-  local n=#str
-  if n==0 then
-   return dummy
-  elseif n==1 then
-   return function() return utfbyte(str) end
-  else
-   local p=1
-   return function()
-     local b,e=find(str,".[\128-\191]*",p)
-     if b then
-      p=e+1
-      return utfbyte(sub(str,b,e))
-     end
-   end
+if not utf.characters then
+  function utf.characters(str)
+    return gmatch(str,".[\128-\191]*")
   end
- end
+  string.utfcharacters=utf.characters
 end
-utf.values=string.utfvalues
+if not utf.values then
+  local find=string.find
+  local dummy=function()
+  end
+  function utf.values(str)
+    local n=#str
+    if n==0 then
+      return dummy
+    elseif n==1 then
+      return function() return utfbyte(str) end
+    else
+      local p=1
+      return function()
+          local b,e=find(str,".[\128-\191]*",p)
+          if b then
+            p=e+1
+            return utfbyte(sub(str,b,e))
+          end
+      end
+    end
+  end
+  string.utfvalues=utf.values
+end
 function utf.chrlen(u) 
- return
-  (u<0x80 and 1) or
-  (u<0xE0 and 2) or
-  (u<0xF0 and 3) or
-  (u<0xF8 and 4) or
-  (u<0xFC and 5) or
-  (u<0xFE and 6) or 0
+  return
+    (u<0x80 and 1) or
+    (u<0xE0 and 2) or
+    (u<0xF0 and 3) or
+    (u<0xF8 and 4) or
+    (u<0xFC and 5) or
+    (u<0xFE and 6) or 0
 end
 if bit32 then
- local extract=bit32.extract
- local char=string.char
- function utf.toutf32string(n)
-  if n<=0xFF then
-   return
-    char(n).."\000\000\000"
-  elseif n<=0xFFFF then
-   return
-    char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
-  elseif n<=0xFFFFFF then
-   return
-    char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
-  else
-   return
-    char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+  local extract=bit32.extract
+  local char=string.char
+  function unicode.toutf32string(n)
+    if n<=0xFF then
+      return
+        char(n).."\000\000\000"
+    elseif n<=0xFFFF then
+      return
+        char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+    elseif n<=0xFFFFFF then
+      return
+        char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+    else
+      return
+        char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+    end
   end
- end
 end
 local len=utf.len
 local rep=rep
 function string.utfpadd(s,n)
- if n and n~=0 then
-  local l=len(s)
-  if n>0 then
-   local d=n-l
-   if d>0 then
-    return rep(c or " ",d)..s
-   end
-  else
-   local d=- n-l
-   if d>0 then
-    return s..rep(c or " ",d)
-   end
+  if n and n~=0 then
+    local l=len(s)
+    if n>0 then
+      local d=n-l
+      if d>0 then
+        return rep(c or " ",d)..s
+      end
+    else
+      local d=- n-l
+      if d>0 then
+        return s..rep(c or " ",d)
+      end
+    end
   end
- end
- return s
+  return s
 end
-do
- local utfcharacters=utf.characters or string.utfcharacters
- local utfchar=utf.char    or string.utfcharacter
- lpeg.UP=P
- if utfcharacters then
-  function lpeg.US(str)
-   local p=P(false)
-   for uc in utfcharacters(str) do
-    p=p+P(uc)
-   end
-   return p
-  end
- else
-  function lpeg.US(str)
-   local p=P(false)
-   local f=function(uc)
-    p=p+P(uc)
-   end
-   lpegmatch((p_utf8char/f)^0,str)
-   return p
-  end
- end
- local range=p_utf8byte*p_utf8byte+Cc(false) 
- function lpeg.UR(str,more)
-  local first,last
-  if type(str)=="number" then
-   first=str
-   last=more or first
-  else
-   first,last=lpegmatch(range,str)
-   if not last then
-    return P(str)
-   end
-  end
-  if first==last then
-   return P(str)
-  end
-  if not utfchar then
-   utfchar=utf.char 
-  end
-  if utfchar and (last-first<8) then 
-   local p=P(false)
-   for i=first,last do
-    p=p+P(utfchar(i))
-   end
-   return p 
-  else
-   local f=function(b)
-    return b>=first and b<=last
-   end
-   return p_utf8byte/f 
-  end
- end
-end
 
 
 end -- of closure
@@ -6369,93 +6005,93 @@
 
 package.loaded["l-math"] = package.loaded["l-math"] or true
 
--- original size: 2555, stripped down to: 1831
+-- original size: 2555, stripped down to: 1900
 
 if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 if not math.ceiling then
- math.ceiling=math.ceil
+  math.ceiling=math.ceil
 end
 if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
+  local floor=math.floor
+  function math.round(x) return floor(x+0.5) end
 end
 if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
+  local floor=math.floor
+  function math.div(n,m) return floor(n/m) end
 end
 if not math.mod then
- function math.mod(n,m) return n%m end
+  function math.mod(n,m) return n%m end
 end
 if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
+  local sin,cos,tan=math.sin,math.cos,math.tan
+  local pipi=2*math.pi/360
+  function math.sind(d) return sin(d*pipi) end
+  function math.cosd(d) return cos(d*pipi) end
+  function math.tand(d) return tan(d*pipi) end
 end
 if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
+  function math.odd (n) return n%2~=0 end
+  function math.even(n) return n%2==0 end
 end
 if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
-  local xx=exp(x)
-  return (xx+1/xx)/2
- end
- function math.sinh(x)
-  local xx=exp(x)
-  return (xx-1/xx)/2
- end
- function math.tanh(x)
-  local xx=exp(x)
-  return (xx-1/xx)/(xx+1/xx)
- end
+  local exp=math.exp
+  function math.cosh(x)
+    local xx=exp(x)
+    return (xx+1/xx)/2
+  end
+  function math.sinh(x)
+    local xx=exp(x)
+    return (xx-1/xx)/2
+  end
+  function math.tanh(x)
+    local xx=exp(x)
+    return (xx-1/xx)/(xx+1/xx)
+  end
 end
 if not math.pow then
- function math.pow(x,y)
-  return x^y
- end
+  function math.pow(x,y)
+    return x^y
+  end
 end
 if not math.atan2 then
- math.atan2=math.atan
+  math.atan2=math.atan
 end
 if not math.ldexp then
- function math.ldexp(x,e)
-  return x*2.0^e
- end
+  function math.ldexp(x,e)
+    return x*2.0^e
+  end
 end
 if not math.log10 then
- local log=math.log
- function math.log10(x)
-  return log(x,10)
- end
+  local log=math.log
+  function math.log10(x)
+    return log(x,10)
+  end
 end
 if not math.type then
- function math.type()
-  return "float"
- end
+  function math.type()
+    return "float"
+  end
 end
 if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
-  local f=floor(n)
-  return f==n and f or nil
- end
+  math.mininteger=-0x4FFFFFFFFFFF
+  math.maxinteger=0x4FFFFFFFFFFF
+  local floor=math.floor
+  function math.tointeger(n)
+    local f=floor(n)
+    return f==n and f or nil
+  end
 end
 if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
-  return floor(m)<floor(n) 
- end
+  local floor=math.floor
+  function math.tointeger(m,n)
+    return floor(m)<floor(n) 
+  end
 end
 
 
@@ -6465,14 +6101,14 @@
 
 package.loaded["util-str"] = package.loaded["util-str"] or true
 
--- original size: 43539, stripped down to: 21641
+-- original size: 38734, stripped down to: 22142
 
 if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 utilities=utilities or {}
 utilities.strings=utilities.strings or {}
@@ -6485,60 +6121,41 @@
 local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc
 local patterns,lpegmatch=lpeg.patterns,lpeg.match
 local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
-local loadstripped=function(str,shortcuts)
- if shortcuts then
-  return load(dump(load(str),true),nil,nil,shortcuts)
- else
-  return load(dump(load(str),true))
- end
+local loadstripped=nil
+local oldfashioned=LUAVERSION<5.2
+if oldfashioned then
+  loadstripped=function(str,shortcuts)
+    return load(str)
+  end
+else
+  loadstripped=function(str,shortcuts)
+    if shortcuts then
+      return load(dump(load(str),true),nil,nil,shortcuts)
+    else
+      return load(dump(load(str),true))
+    end
+  end
 end
 if not number then number={} end 
-local stripzero=patterns.stripzero
-local stripzeros=patterns.stripzeros
+local stripper=patterns.stripzeros
 local newline=patterns.newline
 local endofstring=patterns.endofstring
-local anything=patterns.anything
 local whitespace=patterns.whitespace
-local space=patterns.space
 local spacer=patterns.spacer
 local spaceortab=patterns.spaceortab
-local digit=patterns.digit
-local sign=patterns.sign
-local period=patterns.period
-local ptf=1/65536
-local bpf=(7200/7227)/65536
 local function points(n)
- if n==0 then
-  return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
-  return "0pt"
- end
- n=n*ptf
- if n%1==0 then
-  return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n)) 
+  n=tonumber(n)
+  return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
 end
 local function basepoints(n)
- if n==0 then
-  return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
-  return "0pt"
- end
- n=n*bpf
- if n%1==0 then
-  return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n)) 
+  n=tonumber(n)
+  return (not n or n==0) and "0bp" or lpegmatch(stripper,format("%.5fbp",n*(7200/7227)/65536))
 end
 number.points=points
 number.basepoints=basepoints
 local rubish=spaceortab^0*newline
 local anyrubish=spaceortab+newline
+local anything=patterns.anything
 local stripped=(spaceortab^1/"")*newline
 local leading=rubish^0/""
 local trailing=(anyrubish^1*endofstring)/""
@@ -6545,251 +6162,232 @@
 local redundant=rubish^3/"\n"
 local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
 function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
+  return lpegmatch(pattern,str)
 end
 local repeaters={} 
 function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
-  s={}
-  repeaters[str]=s
- end
- local t=s[offset]
- if t then
+  offset=offset or 0
+  local s=repeaters[str]
+  if not s then
+    s={}
+    repeaters[str]=s
+  end
+  local t=s[offset]
+  if t then
+    return t
+  end
+  t={}
+  setmetatable(t,{ __index=function(t,k)
+    if not k then
+      return ""
+    end
+    local n=k+offset
+    local s=n>0 and rep(str,n) or ""
+    t[k]=s
+    return s
+  end })
+  s[offset]=t
   return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
-  if not k then
-   return ""
-  end
-  local n=k+offset
-  local s=n>0 and rep(str,n) or ""
-  t[k]=s
-  return s
- end })
- s[offset]=t
- return t
 end
 local extra,tab,start=0,0,4,0
 local nspaces=strings.newrepeater(" ")
 string.nspaces=nspaces
 local pattern=Carg(1)/function(t)
-  extra,tab,start=0,t or 7,1
- end*Cs((
+    extra,tab,start=0,t or 7,1
+  end*Cs((
    Cp()*patterns.tab/function(position)
-    local current=(position-start+1)+extra
-    local spaces=tab-(current-1)%tab
-    if spaces>0 then
-     extra=extra+spaces-1
-     return nspaces[spaces] 
-    else
-     return ""
-    end
+     local current=(position-start+1)+extra
+     local spaces=tab-(current-1)%tab
+     if spaces>0 then
+       extra=extra+spaces-1
+       return nspaces[spaces] 
+     else
+       return ""
+     end
    end+newline*Cp()/function(position)
-    extra,start=0,position
-   end+anything
-  )^1)
+     extra,start=0,position
+   end+patterns.anything
+ )^1)
 function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+  return lpegmatch(pattern,str,1,tab or 7)
 end
 function string.utfpadding(s,n)
- if not n or n==0 then
-  return ""
- end
- local l=utflen(s)
- if n>0 then
-  return nspaces[n-l]
- else
-  return nspaces[-n-l]
- end
+  if not n or n==0 then
+    return ""
+  end
+  local l=utflen(s)
+  if n>0 then
+    return nspaces[n-l]
+  else
+    return nspaces[-n-l]
+  end
 end
-local optionalspace=spacer^0
-local nospace=optionalspace/""
+local space=spacer^0
+local nospace=space/""
 local endofline=nospace*newline
 local stripend=(whitespace^1*endofstring)/""
-local normalline=(nospace*((1-optionalspace*(newline+endofstring))^1)*nospace)
+local normalline=(nospace*((1-space*(newline+endofstring))^1)*nospace)
 local stripempty=endofline^1/""
 local normalempty=endofline^1
 local singleempty=endofline*(endofline^0/"")
 local doubleempty=endofline*endofline^-1*(endofline^0/"")
 local stripstart=stripempty^0
-local intospace=whitespace^1/" "
-local noleading=whitespace^1/""
-local notrailing=noleading*endofstring
 local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
 local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
 local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1     )^0 )
 local p_retain_normal=Cs ((normalline+normalempty )^0 )
 local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
 local p_retain_noempty=Cs ((normalline+singleempty )^0 )
 local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+  ["prune"]=p_prune_normal,
+  ["prune and collapse"]=p_prune_collapse,
+  ["prune and no empty"]=p_prune_noempty,
+  ["retain"]=p_retain_normal,
+  ["retain and collapse"]=p_retain_collapse,
+  ["retain and no empty"]=p_retain_noempty,
+  ["collapse"]=patterns.collapser,
 }
 setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
 strings.striplinepatterns=striplinepatterns
 function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
+  return str and lpegmatch(striplinepatterns[how],str) or str
 end
-function strings.collapse(str) 
- return str and lpegmatch(p_prune_intospace,str) or str
-end
 strings.striplong=strings.striplines
 function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ") 
- return str
+  str=gsub(str,"[:%-+_]+"," ") 
+  return str
 end
 local n=0
 local sequenced=table.sequenced
 function string.autodouble(s,sep)
- if s==nil then
-  return '""'
- end
- local t=type(s)
- if t=="number" then
-  return tostring(s) 
- end
- if t=="table" then
-  return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
+  if s==nil then
+    return '""'
+  end
+  local t=type(s)
+  if t=="number" then
+    return tostring(s) 
+  end
+  if t=="table" then
+    return ('"'..sequenced(s,sep or ",")..'"')
+  end
+  return ('"'..tostring(s)..'"')
 end
 function string.autosingle(s,sep)
- if s==nil then
-  return "''"
- end
- local t=type(s)
- if t=="number" then
-  return tostring(s) 
- end
- if t=="table" then
-  return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
+  if s==nil then
+    return "''"
+  end
+  local t=type(s)
+  if t=="number" then
+    return tostring(s) 
+  end
+  if t=="table" then
+    return ("'"..sequenced(s,sep or ",").."'")
+  end
+  return ("'"..tostring(s).."'")
 end
 local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
+  "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+  "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+  "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+  "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+  "[space]",
 }
 string.tracedchars=tracedchars
 strings.tracers=tracedchars
 function string.tracedchar(b)
- if type(b)=="number" then
-  return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
-  local c=utfbyte(b)
-  return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
+  if type(b)=="number" then
+    return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+  else
+    local c=utfbyte(b)
+    return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+  end
 end
 function number.signed(i)
- if i>0 then
-  return "+",i
- else
-  return "-",-i
- end
+  if i>0 then
+    return "+",i
+  else
+    return "-",-i
+  end
 end
-local two=digit*digit
-local three=two*digit
-local prefix=(Carg(1)*three)^1
+local digit=patterns.digit
+local period=patterns.period
+local three=digit*digit*digit
 local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+  (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2)
 )
-local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
-)
 patterns.formattednumber=splitter
 function number.formatted(n,sep1,sep2)
- if sep1==false then
-  if type(n)=="number" then
-   n=tostring(n)
-  end
-  return lpegmatch(splitter3,n,1,sep2 or ".")
- else
-  if type(n)=="number" then
-   n=format("%0.2f",n)
-  end
+  local s=type(s)=="string" and n or format("%0.2f",n)
   if sep1==true then
-   return lpegmatch(splitter,n,1,".",",")
+    return lpegmatch(splitter,s,1,".",",")
   elseif sep1=="." then
-   return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+    return lpegmatch(splitter,s,1,sep1,sep2 or ",")
   elseif sep1=="," then
-   return lpegmatch(splitter,n,1,sep1,sep2 or ".")
+    return lpegmatch(splitter,s,1,sep1,sep2 or ".")
   else
-   return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
+    return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
   end
- end
 end
 local p=Cs(
-  P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
+    P("-")^0*(P("0")^1/"")^0*(1-P("."))^0*(P(".")*P("0")^1*P(-1)/""+P(".")^0)*P(1-P("0")^1*P(-1))^0
+  )
 function number.compactfloat(n,fmt)
- if n==0 then
-  return "0"
- elseif n==1 then
-  return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
-  return "0"
- end
- return n
+  if n==0 then
+    return "0"
+  elseif n==1 then
+    return "1"
+  end
+  n=lpegmatch(p,format(fmt or "%0.3f",n))
+  if n=="." or n=="" or n=="-" then
+    return "0"
+  end
+  return n
 end
 local zero=P("0")^1/""
 local plus=P("+")/""
 local minus=P("-")
-local separator=period
+local separator=S(".")
+local digit=R("09")
 local trailing=zero^1*#S("eE")
-local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(endofstring*Cc("0")+anything^1))
+local exponent=(S("eE")*(plus+Cs((minus*zero^0*P(-1))/"")+minus)*zero^0*(P(-1)*Cc("0")+P(1)^1))
 local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
-local pattern_b=Cs((exponent+anything)^0)
+local pattern_b=Cs((exponent+P(1))^0)
 function number.sparseexponent(f,n)
- if not n then
-  n=f
-  f="%e"
- end
- local tn=type(n)
- if tn=="string" then 
-  local m=tonumber(n)
-  if m then
-   return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
+  if not n then
+    n=f
+    f="%e"
   end
- elseif tn=="number" then
-  return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
- end
- return tostring(n)
+  local tn=type(n)
+  if tn=="string" then 
+    local m=tonumber(n)
+    if m then
+      return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
+    end
+  elseif tn=="number" then
+    return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+  end
+  return tostring(n)
 end
 local hf={}
 local hs={}
 setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
+  local v="%."..k.."f"
+  t[k]=v
+  return v
 end } )
 setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
+  local v="%"..k.."s"
+  t[k]=v
+  return v
 end } )
 function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
-  return format(hs[l],s)
- else
-  return s
- end
+  local s=format(hf[a],n)
+  local l=(b or 0)+(a or 0)+1
+  if #s<l then
+    return format(hs[l],s)
+  else
+    return s
+  end
 end
 local template=[[
 %s
@@ -6796,346 +6394,351 @@
 %s
 return function(%s) return %s end
 ]]
-local preamble=""
-local environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=lpeg.patterns.stripzero,
- stripzeros=lpeg.patterns.stripzeros,
- FORMAT=string.f9,
-}
+local preamble,environment="",{}
+if oldfashioned then
+  preamble=[[
+local lpeg=lpeg
+local type=type
+local tostring=tostring
+local tonumber=tonumber
+local format=string.format
+local concat=table.concat
+local signed=number.signed
+local points=number.points
+local basepoints= number.basepoints
+local utfchar=utf.char
+local utfbyte=utf.byte
+local lpegmatch=lpeg.match
+local nspaces=string.nspaces
+local utfpadding=string.utfpadding
+local tracedchar=string.tracedchar
+local autosingle=string.autosingle
+local autodouble=string.autodouble
+local sequenced=table.sequenced
+local formattednumber=number.formatted
+local sparseexponent=number.sparseexponent
+local formattedfloat=number.formattedfloat
+    ]]
+else
+  environment={
+    global=global or _G,
+    lpeg=lpeg,
+    type=type,
+    tostring=tostring,
+    tonumber=tonumber,
+    format=string.format,
+    concat=table.concat,
+    signed=number.signed,
+    points=number.points,
+    basepoints=number.basepoints,
+    utfchar=utf.char,
+    utfbyte=utf.byte,
+    lpegmatch=lpeg.match,
+    nspaces=string.nspaces,
+    utfpadding=string.utfpadding,
+    tracedchar=string.tracedchar,
+    autosingle=string.autosingle,
+    autodouble=string.autodouble,
+    sequenced=table.sequenced,
+    formattednumber=number.formatted,
+    sparseexponent=number.sparseexponent,
+    formattedfloat=number.formattedfloat,
+  }
+end
 local arguments={ "a1" } 
 setmetatable(arguments,{ __index=function(t,k)
-  local v=t[k-1]..",a"..k
-  t[k]=v
-  return v
- end
+    local v=t[k-1]..",a"..k
+    t[k]=v
+    return v
+  end
 })
-local prefix_any=C((sign+space+period+digit)^0)
-local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
+local prefix_any=C((S("+- .")+R("09"))^0)
+local prefix_sub=(C((S("+-")+R("09"))^0)+Cc(0))*P(".")*(C((S("+-")+R("09"))^0)+Cc(0))
 local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
 local format_s=function(f)
- n=n+1
- if f and f~="" then
-  return format("format('%%%ss',a%s)",f,n)
- else 
-  return format("(a%s or '')",n) 
- end
+  n=n+1
+  if f and f~="" then
+    return format("format('%%%ss',a%s)",f,n)
+  else 
+    return format("(a%s or '')",n) 
+  end
 end
 local format_S=function(f) 
- n=n+1
- if f and f~="" then
-  return format("format('%%%ss',tostring(a%s))",f,n)
- else
-  return format("tostring(a%s)",n)
- end
+  n=n+1
+  if f and f~="" then
+    return format("format('%%%ss',tostring(a%s))",f,n)
+  else
+    return format("tostring(a%s)",n)
+  end
 end
 local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
-  return format("(a%s or '')",n)
- elseif f>0 then
-  return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
-  return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
+  n=n+1
+  f=tonumber(f)
+  if not f or f==0 then
+    return format("(a%s or '')",n)
+  elseif f>0 then
+    return format("utfpadding(a%s,%i)..a%s",n,f,n)
+  else
+    return format("a%s..utfpadding(a%s,%i)",n,n,f)
+  end
 end
 local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
-  return format("(a%s or '')",n)
- end
- if f<0 then
-  return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
-  return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
+  n=n+1
+  f=tonumber(f)
+  if not f or f==0 then
+    return format("(a%s or '')",n)
+  end
+  if f<0 then
+    return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+  else
+    return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+  end
 end
 local format_q=function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+  n=n+1
+  return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
 end
 local format_Q=function() 
- n=n+1
- return format("format('%%q',tostring(a%s))",n)
+  n=n+1
+  return format("format('%%q',tostring(a%s))",n)
 end
 local format_i=function(f)
- n=n+1
- if f and f~="" then
-  return format("format('%%%si',a%s)",f,n)
- else
-  return format("format('%%i',a%s)",n) 
- end
+  n=n+1
+  if f and f~="" then
+    return format("format('%%%si',a%s)",f,n)
+  else
+    return format("format('%%i',a%s)",n) 
+  end
 end
 local format_d=format_i
 local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
+  n=n+1
+  return format("format('%%s%%%si',signed(a%s))",f,n)
 end
 local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
+  n=n+1
+  return format("format('%%%sf',a%s)",f,n)
 end
 local format_F=function(f) 
- n=n+1
- if not f or f=="" then
-  return format("(((a%s > -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
+  n=n+1
+  if not f or f=="" then
+    return format("(((a%s > -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_k=function(b,a) 
- n=n+1
- return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+  n=n+1
+  return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
 end
 local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
+  n=n+1
+  return format("format('%%%sg',a%s)",f,n)
 end
 local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
+  n=n+1
+  return format("format('%%%sG',a%s)",f,n)
 end
 local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
+  n=n+1
+  return format("format('%%%se',a%s)",f,n)
 end
 local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
+  n=n+1
+  return format("format('%%%sE',a%s)",f,n)
 end
 local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
+  n=n+1
+  return format("sparseexponent('%%%se',a%s)",f,n)
 end
 local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
+  n=n+1
+  return format("sparseexponent('%%%sE',a%s)",f,n)
 end
 local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
+  n=n+1
+  return format("format('%%%sx',a%s)",f,n)
 end
 local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
+  n=n+1
+  return format("format('%%%sX',a%s)",f,n)
 end
 local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
+  n=n+1
+  return format("format('%%%so',a%s)",f,n)
 end
 local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
+  n=n+1
+  return format("utfchar(a%s)",n)
 end
 local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+  n=n+1
+  return format("tracedchar(a%s)",n)
 end
 local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
+  n=n+1
+  return format("format('%%%s.0f',a%s)",f,n)
 end
 local format_h=function(f)
- n=n+1
- if f=="-" then
-  f=sub(f,2)
-  return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
-  return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+  n=n+1
+  if f=="-" then
+    f=sub(f,2)
+    return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  else
+    return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  end
 end
 local format_H=function(f)
- n=n+1
- if f=="-" then
-  f=sub(f,2)
-  return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
-  return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+  n=n+1
+  if f=="-" then
+    f=sub(f,2)
+    return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  else
+    return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  end
 end
 local format_u=function(f)
- n=n+1
- if f=="-" then
-  f=sub(f,2)
-  return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
-  return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+  n=n+1
+  if f=="-" then
+    f=sub(f,2)
+    return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  else
+    return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  end
 end
 local format_U=function(f)
- n=n+1
- if f=="-" then
-  f=sub(f,2)
-  return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
-  return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+  n=n+1
+  if f=="-" then
+    f=sub(f,2)
+    return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  else
+    return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+  end
 end
 local format_p=function()
- n=n+1
- return format("points(a%s)",n)
+  n=n+1
+  return format("points(a%s)",n)
 end
 local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+  n=n+1
+  return format("basepoints(a%s)",n)
 end
 local format_t=function(f)
- n=n+1
- if f and f~="" then
-  return format("concat(a%s,%q)",n,f)
- else
-  return format("concat(a%s)",n)
- end
+  n=n+1
+  if f and f~="" then
+    return format("concat(a%s,%q)",n,f)
+  else
+    return format("concat(a%s)",n)
+  end
 end
 local format_T=function(f)
- n=n+1
- if f and f~="" then
-  return format("sequenced(a%s,%q)",n,f)
- else
-  return format("sequenced(a%s)",n)
- end
+  n=n+1
+  if f and f~="" then
+    return format("sequenced(a%s,%q)",n,f)
+  else
+    return format("sequenced(a%s)",n)
+  end
 end
 local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
+  n=n+1
+  return format("(a%s and 'true' or 'false')",n)
 end
 local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
+  n=n+1
+  return format("(a%s and 'TRUE' or 'FALSE')",n)
 end
-local format_n=function() 
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+local format_N=function() 
+  n=n+1
+  return format("tostring(tonumber(a%s) or a%s)",n,n)
 end
-local format_N=function(f) 
- n=n+1
- if not f or f=="" then
-  f=".9"
- end 
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
-end
 local format_a=function(f)
- n=n+1
- if f and f~="" then
-  return format("autosingle(a%s,%q)",n,f)
- else
-  return format("autosingle(a%s)",n)
- end
+  n=n+1
+  if f and f~="" then
+    return format("autosingle(a%s,%q)",n,f)
+  else
+    return format("autosingle(a%s)",n)
+  end
 end
 local format_A=function(f)
- n=n+1
- if f and f~="" then
-  return format("autodouble(a%s,%q)",n,f)
- else
-  return format("autodouble(a%s)",n)
- end
+  n=n+1
+  if f and f~="" then
+    return format("autodouble(a%s,%q)",n,f)
+  else
+    return format("autodouble(a%s)",n)
+  end
 end
 local format_w=function(f) 
- n=n+1
- f=tonumber(f)
- if f then 
-  return format("nspaces[%s+a%s]",f,n) 
- else
-  return format("nspaces[a%s]",n) 
- end
+  n=n+1
+  f=tonumber(f)
+  if f then 
+    return format("nspaces[%s+a%s]",f,n) 
+  else
+    return format("nspaces[a%s]",n) 
+  end
 end
 local format_W=function(f) 
- return format("nspaces[%s]",tonumber(f) or 0)
+  return format("nspaces[%s]",tonumber(f) or 0)
 end
 local format_m=function(f)
- n=n+1
- if not f or f=="" then
-  f=","
- end
- if f=="0" then
-  return format([[formattednumber(a%s,false)]],n)
- else
+  n=n+1
+  if not f or f=="" then
+    f=","
+  end
   return format([[formattednumber(a%s,%q,".")]],n,f)
- end
 end
 local format_M=function(f)
- n=n+1
- if not f or f=="" then
-  f="."
- end
- if f=="0" then
-  return format([[formattednumber(a%s,false)]],n)
- else
+  n=n+1
+  if not f or f=="" then
+    f="."
+  end
   return format([[formattednumber(a%s,%q,",")]],n,f)
- end
 end
 local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''" 
+  n=n+(tonumber(f) or 1)
+  return "''" 
 end
 local format_rest=function(s)
- return format("%q",s) 
+  return format("%q",s) 
 end
 local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if w then
+  local extension=extensions[name] or "tostring(%s)"
+  local f=tonumber(f) or 1
+  local w=find(extension,"%.%.%.")
   if f==0 then
-   extension=gsub(extension,"%.%.%.","")
-   return extension
+    if w then
+      extension=gsub(extension,"%.%.%.","")
+    end
+    return extension
   elseif f==1 then
-   extension=gsub(extension,"%.%.%.","%%s")
-   n=n+1
-   local a="a"..n
-   return format(extension,a,a) 
+    if w then
+      extension=gsub(extension,"%.%.%.","%%s")
+    end
+    n=n+1
+    local a="a"..n
+    return format(extension,a,a) 
   elseif f<0 then
-   local a="a"..(n+f+1)
-   return format(extension,a,a)
+    local a="a"..(n+f+1)
+    return format(extension,a,a)
   else
-   extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
-   local t={}
-   for i=1,f do
-    n=n+1
-    t[i]="a"..n
-   end
-   return format(extension,unpack(t))
+    if w then
+      extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+    end
+    local t={}
+    for i=1,f do
+      n=n+1
+      t[i]="a"..n
+    end
+    return format(extension,unpack(t))
   end
- else
-  extension=gsub(extension,"%%s",function()
-   n=n+1
-   return "a"..n
-  end)
-  return extension
- end
 end
 local builder=Cs { "start",
- start=(
-  (
-   P("%")/""*(
-    V("!") 
+  start=(
+    (
+      P("%")/""*(
+        V("!") 
 +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") 
 +V("N") 
 +V("k")
 +V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w") 
@@ -7147,157 +6750,161 @@
 +V("z")
 +V(">") 
 +V("<")
-   )+V("*")
-  )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["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,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1      )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+      )+V("*")
+    )*(P(-1)+Carg(1))
+  )^0,
+  ["s"]=(prefix_any*P("s"))/format_s,
+  ["q"]=(prefix_any*P("q"))/format_q,
+  ["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,
+  ["E"]=(prefix_any*P("E"))/format_E,
+  ["x"]=(prefix_any*P("x"))/format_x,
+  ["X"]=(prefix_any*P("X"))/format_X,
+  ["o"]=(prefix_any*P("o"))/format_o,
+  ["S"]=(prefix_any*P("S"))/format_S,
+  ["Q"]=(prefix_any*P("Q"))/format_Q,
+  ["N"]=(prefix_any*P("N"))/format_N,
+  ["k"]=(prefix_sub*P("k"))/format_k,
+  ["c"]=(prefix_any*P("c"))/format_c,
+  ["C"]=(prefix_any*P("C"))/format_C,
+  ["r"]=(prefix_any*P("r"))/format_r,
+  ["h"]=(prefix_any*P("h"))/format_h,
+  ["H"]=(prefix_any*P("H"))/format_H,
+  ["u"]=(prefix_any*P("u"))/format_u,
+  ["U"]=(prefix_any*P("U"))/format_U,
+  ["p"]=(prefix_any*P("p"))/format_p,
+  ["b"]=(prefix_any*P("b"))/format_b,
+  ["t"]=(prefix_tab*P("t"))/format_t,
+  ["T"]=(prefix_tab*P("T"))/format_T,
+  ["l"]=(prefix_any*P("l"))/format_l,
+  ["L"]=(prefix_any*P("L"))/format_L,
+  ["I"]=(prefix_any*P("I"))/format_I,
+  ["w"]=(prefix_any*P("w"))/format_w,
+  ["W"]=(prefix_any*P("W"))/format_W,
+  ["j"]=(prefix_any*P("j"))/format_j,
+  ["J"]=(prefix_any*P("J"))/format_J,
+  ["m"]=(prefix_tab*P("m"))/format_m,
+  ["M"]=(prefix_tab*P("M"))/format_M,
+  ["z"]=(prefix_any*P("z"))/format_z,
+  ["a"]=(prefix_any*P("a"))/format_a,
+  ["A"]=(prefix_any*P("A"))/format_A,
+  ["<"]=(prefix_any*P("<"))/format_left,
+  [">"]=(prefix_any*P(">"))/format_right,
+  ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+  ["?"]=Cs(((1-P("%"))^1        )^1)/format_rest,
+  ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
 }
 local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
 local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
 local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
+  ["%02x"]=function(n) return xx[n] end,
+  ["%02X"]=function(n) return XX[n] end,
 }
-local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
+local direct=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=preset[str]
- if f then
-  return f
- end
- local p=lpegmatch(direct,str)
- if p then
-  f=loadstripped(p)()
- else
-  n=0
-  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,t._environment_)() 
+  local f=preset[str]
+  if f then
+    return f
+  end
+  local p=lpegmatch(direct,str)
+  if p then
+    f=loadstripped(p)()
   else
-   f=function() return str end
+    n=0
+    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,t._environment_)() 
+    else
+      f=function() return str end
+    end
   end
- end
- t[str]=f
- return f
+  t[str]=f
+  return f
 end
 local function use(t,fmt,...)
- return t[fmt](...)
+  return t[fmt](...)
 end
 strings.formatters={}
-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
+if oldfashioned 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 
 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 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
+  if type(t)=="table" and t._type_=="formatter" then
+    t._extensions_[name]=template or "%s"
+    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
 end
 strings.formatters.add=add
-patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+anything)^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
+patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0)
+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)]],{ xmlescape=lpeg.patterns.xmlescape })
-add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
-add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
+if oldfashioned 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)     
+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
+  return lpegmatch(pattern,str) or str
 end
 local pattern=Cs((newline/(os.newline or "\r")+1)^0)
 function string.replacenewlines(str)
- return lpegmatch(pattern,str)
+  return lpegmatch(pattern,str)
 end
 function strings.newcollector()
- local result,r={},0
- return
-  function(fmt,str,...) 
-   r=r+1
-   result[r]=str==nil and fmt or formatters[fmt](str,...)
-  end,
-  function(connector) 
-   if result then
-    local str=concat(result,connector)
-    result,r={},0
-    return str
-   end
-  end
+  local result,r={},0
+  return
+    function(fmt,str,...) 
+      r=r+1
+      result[r]=str==nil and fmt or formatters[fmt](str,...)
+    end,
+    function(connector) 
+      if result then
+        local str=concat(result,connector)
+        result,r={},0
+        return str
+      end
+    end
 end
-local f_16_16=formatters["%0.5N"]
-function number.to16dot16(n)
- return f_16_16(n/65536.0)
-end
 
 
 end -- of closure
@@ -7306,14 +6913,14 @@
 
 package.loaded["util-tab"] = package.loaded["util-tab"] or true
 
--- original size: 28772, stripped down to: 16111
+-- original size: 27741, stripped down to: 17085
 
 if not modules then modules={} end modules ['util-tab']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 utilities=utilities or {}
 utilities.tables=utilities.tables or {}
@@ -7328,220 +6935,219 @@
 local utftoeight=utf.toeight
 local splitter=lpeg.tsplitat(".")
 function utilities.tables.definetable(target,nofirst,nolast) 
- local composed=nil
- local t={}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
-  local name=snippets[i]
+  local composed,t=nil,{}
+  local snippets=lpegmatch(splitter,target)
+  for i=1,#snippets-(nolast and 1 or 0) do
+    local name=snippets[i]
+    if composed then
+      composed=composed.."."..name
+        t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
+    else
+      composed=name
+      if not nofirst then
+        t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+      end
+    end
+  end
   if composed then
-   composed=composed.."."..name
-    t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
+    if nolast then
+      composed=composed.."."..snippets[#snippets]
+    end
+    return concat(t,"\n"),composed 
   else
-   composed=name
-   if not nofirst then
-    t[#t+1]=formatters["%s = %s or { }"](composed,composed)
-   end
+    return "",target
   end
- end
- if composed then
-  if nolast then
-   composed=composed.."."..snippets[#snippets]
-  end
-  return concat(t,"\n"),composed 
- else
-  return "",target
- end
 end
 function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
-  local li=select(i,...)
-  local tl=t[li]
-  if not tl then
-   tl={}
-   t[li]=tl
+  local t=_G
+  for i=1,select("#",...) do
+    local li=select(i,...)
+    local tl=t[li]
+    if not tl then
+      tl={}
+      t[li]=tl
+    end
+    t=tl
   end
-  t=tl
- end
- return t
+  return t
 end
 function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
-  t=t[name]
-  if not t then
-   return
+  local t=root or _G
+  for name in gmatch(target,"([^%.]+)") do
+    t=t[name]
+    if not t then
+      return
+    end
   end
- end
- return t
+  return t
 end
 function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
-  local name=names[i]
-  t[name]=t[name] or {}
-  t=t[name]
-  if not t then
-   return
+  local t=root or _G
+  local names=lpegmatch(splitter,target)
+  for i=1,#names-1 do
+    local name=names[i]
+    t[name]=t[name] or {}
+    t=t[name]
+    if not t then
+      return
+    end
   end
- end
- t[names[#names]]=v
+  t[names[#names]]=v
 end
 function tables.removevalue(t,value) 
- if value then
-  for i=1,#t do
-   if t[i]==value then
-    remove(t,i)
-   end
+  if value then
+    for i=1,#t do
+      if t[i]==value then
+        remove(t,i)
+      end
+    end
   end
- end
 end
 function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
-  for i=1,#t do
-   if t[i]==oldvalue then
-    t[i]=newvalue
-   end
+  if oldvalue and newvalue then
+    for i=1,#t do
+      if t[i]==oldvalue then
+        t[i]=newvalue
+      end
+    end
   end
- end
 end
 function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
-  if t[i]==extra then
-   remove(t,i)
+  for i=1,#t do
+    if t[i]==extra then
+      remove(t,i)
+    end
   end
- end
- for i=1,#t do
-  if t[i]==value then
-   insert(t,i,extra)
-   return
+  for i=1,#t do
+    if t[i]==value then
+      insert(t,i,extra)
+      return
+    end
   end
- end
- insert(t,1,extra)
+  insert(t,1,extra)
 end
 function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
-  if t[i]==extra then
-   remove(t,i)
+  for i=1,#t do
+    if t[i]==extra then
+      remove(t,i)
+    end
   end
- end
- for i=1,#t do
-  if t[i]==value then
-   insert(t,i+1,extra)
-   return
+  for i=1,#t do
+    if t[i]==value then
+      insert(t,i+1,extra)
+      return
+    end
   end
- end
- insert(t,#t+1,extra)
+  insert(t,#t+1,extra)
 end
 local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
 function table.tocsv(t,specification)
- if t and #t>0 then
-  local result={}
-  local r={}
-  specification=specification or {}
-  local fields=specification.fields
-  if type(fields)~="string" then
-   fields=sortedkeys(t[1])
-  end
-  local separator=specification.separator or ","
-  local noffields=#fields
-  if specification.preamble==true then
-   for f=1,noffields do
-    r[f]=lpegmatch(escape,tostring(fields[f]))
-   end
-   result[1]=concat(r,separator)
-  end
-  for i=1,#t do
-   local ti=t[i]
-   for f=1,noffields do
-    local field=ti[fields[f]]
-    if type(field)=="string" then
-     r[f]=lpegmatch(escape,field)
-    else
-     r[f]=tostring(field)
+  if t and #t>0 then
+    local result={}
+    local r={}
+    specification=specification or {}
+    local fields=specification.fields
+    if type(fields)~="string" then
+      fields=sortedkeys(t[1])
     end
-   end
-   result[i+1]=concat(r,separator)
+    local separator=specification.separator or ","
+    local noffields=#fields
+    if specification.preamble==true then
+      for f=1,noffields do
+        r[f]=lpegmatch(escape,tostring(fields[f]))
+      end
+      result[1]=concat(r,separator)
+    end
+    for i=1,#t do
+      local ti=t[i]
+      for f=1,noffields do
+        local field=ti[fields[f]]
+        if type(field)=="string" then
+          r[f]=lpegmatch(escape,field)
+        else
+          r[f]=tostring(field)
+        end
+      end
+      result[i+1]=concat(r,separator)
+    end
+    return concat(result,"\n")
+  else
+    return ""
   end
-  return concat(result,"\n")
- else
-  return ""
- end
 end
 local nspaces=utilities.strings.newrepeater(" ")
 local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
-  local s=nspaces[d] 
-  local tk=type(k)
-  local tv=type(v)
-  if tv=="table" then
-   if tk=="number" then
-    r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
-    toxml(v,d+step,result,step)
-    r=r+1 result[r]=formatters["%s</entry>"](s,k)
-   else
-    r=r+1 result[r]=formatters["%s<%s>"](s,k)
-    toxml(v,d+step,result,step)
-    r=r+1 result[r]=formatters["%s</%s>"](s,k)
-   end
-  elseif tv=="string" then
-   if tk=="number" then
-    r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
-   else
-    r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
-   end
-  elseif tk=="number" then
-   r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
-  else
-   r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
+  local r=#result
+  for k,v in sortedpairs(t) do
+    local s=nspaces[d] 
+    local tk=type(k)
+    local tv=type(v)
+    if tv=="table" then
+      if tk=="number" then
+        r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+        toxml(v,d+step,result,step)
+        r=r+1 result[r]=formatters["%s</entry>"](s,k)
+      else
+        r=r+1 result[r]=formatters["%s<%s>"](s,k)
+        toxml(v,d+step,result,step)
+        r=r+1 result[r]=formatters["%s</%s>"](s,k)
+      end
+    elseif tv=="string" then
+      if tk=="number" then
+        r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+      else
+        r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+      end
+    elseif tk=="number" then
+      r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+    else
+      r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
+    end
   end
- end
 end
 function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
-  toxml(t,indent,result,spaces)
- else
-  toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+  specification=specification or {}
+  local name=specification.name
+  local noroot=name==false
+  local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+  local indent=specification.indent or 0
+  local spaces=specification.spaces or 1
+  if noroot then
+    toxml(t,indent,result,spaces)
+  else
+    toxml({ [name or "data"]=t },indent,result,spaces)
+  end
+  return concat(result,"\n")
 end
 function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
-  protect=true
-  capsule={}
- end
- for key,value in next,core do
-  if capsule[key] then
-   print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
-   os.exit()
-  else
-   capsule[key]=value
+  if type(capsule)~="table" then
+    protect=true
+    capsule={}
   end
- end
- if protect then
   for key,value in next,core do
-   core[key]=nil
-  end
-  setmetatable(core,{
-   __index=capsule,
-   __newindex=function(t,key,value)
     if capsule[key] then
-     print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
-     os.exit()
+      print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+      os.exit()
     else
-     rawset(t,key,value)
+      capsule[key]=value
     end
-   end
-  } )
- end
+  end
+  if protect then
+    for key,value in next,core do
+      core[key]=nil
+    end
+    setmetatable(core,{
+      __index=capsule,
+      __newindex=function(t,key,value)
+        if capsule[key] then
+          print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+          os.exit()
+        else
+          rawset(t,key,value)
+        end
+      end
+    } )
+  end
 end
 local f_hashed_string=formatters["[%q]=%q,"]
 local f_hashed_number=formatters["[%q]=%s,"]
@@ -7555,157 +7161,157 @@
 local f_ordered_number=formatters["%s,"]
 local f_ordered_boolean=formatters["%l,"]
 function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer) 
-  local n=#t
-  m=m+1
-  r[m]="{"
-  if n>0 then
-   for i=0,n do
-    local v=t[i]
-    local tv=type(v)
-    if tv=="string" then
-     m=m+1 r[m]=f_ordered_string(v)
-    elseif tv=="number" then
-     m=m+1 r[m]=f_ordered_number(v)
-    elseif tv=="table" then
-     fastserialize(v)
-    elseif tv=="boolean" then
-     m=m+1 r[m]=f_ordered_boolean(v)
+  local r={ type(prefix)=="string" and prefix or "return" }
+  local m=1
+  local function fastserialize(t,outer) 
+    local n=#t
+    m=m+1
+    r[m]="{"
+    if n>0 then
+      for i=0,n do
+        local v=t[i]
+        local tv=type(v)
+        if tv=="string" then
+          m=m+1 r[m]=f_ordered_string(v)
+        elseif tv=="number" then
+          m=m+1 r[m]=f_ordered_number(v)
+        elseif tv=="table" then
+          fastserialize(v)
+        elseif tv=="boolean" then
+          m=m+1 r[m]=f_ordered_boolean(v)
+        end
+      end
     end
-   end
-  end
-  for k,v in next,t do
-   local tk=type(k)
-   if tk=="number" then
-    if k>n or k<0 then
-     local tv=type(v)
-     if tv=="string" then
-      m=m+1 r[m]=f_indexed_string(k,v)
-     elseif tv=="number" then
-      m=m+1 r[m]=f_indexed_number(k,v)
-     elseif tv=="table" then
-      m=m+1 r[m]=f_indexed_table(k)
-      fastserialize(v)
-     elseif tv=="boolean" then
-      m=m+1 r[m]=f_indexed_boolean(k,v)
-     end
+    for k,v in next,t do
+      local tk=type(k)
+      if tk=="number" then
+        if k>n or k<0 then
+          local tv=type(v)
+          if tv=="string" then
+            m=m+1 r[m]=f_indexed_string(k,v)
+          elseif tv=="number" then
+            m=m+1 r[m]=f_indexed_number(k,v)
+          elseif tv=="table" then
+            m=m+1 r[m]=f_indexed_table(k)
+            fastserialize(v)
+          elseif tv=="boolean" then
+            m=m+1 r[m]=f_indexed_boolean(k,v)
+          end
+        end
+      else
+        local tv=type(v)
+        if tv=="string" then
+          m=m+1 r[m]=f_hashed_string(k,v)
+        elseif tv=="number" then
+          m=m+1 r[m]=f_hashed_number(k,v)
+        elseif tv=="table" then
+          m=m+1 r[m]=f_hashed_table(k)
+          fastserialize(v)
+        elseif tv=="boolean" then
+          m=m+1 r[m]=f_hashed_boolean(k,v)
+        end
+      end
     end
-   else
-    local tv=type(v)
-    if tv=="string" then
-     m=m+1 r[m]=f_hashed_string(k,v)
-    elseif tv=="number" then
-     m=m+1 r[m]=f_hashed_number(k,v)
-    elseif tv=="table" then
-     m=m+1 r[m]=f_hashed_table(k)
-     fastserialize(v)
-    elseif tv=="boolean" then
-     m=m+1 r[m]=f_hashed_boolean(k,v)
+    m=m+1
+    if outer then
+      r[m]="}"
+    else
+      r[m]="},"
     end
-   end
+    return r
   end
-  m=m+1
-  if outer then
-   r[m]="}"
-  else
-   r[m]="},"
-  end
-  return r
- end
- return concat(fastserialize(t,true))
+  return concat(fastserialize(t,true))
 end
 function table.deserialize(str)
- if not str or str=="" then
-  return
- end
- local code=load(str)
- if not code then
-  return
- end
- code=code()
- if not code then
-  return
- end
- return code
+  if not str or str=="" then
+    return
+  end
+  local code=load(str)
+  if not code then
+    return
+  end
+  code=code()
+  if not code then
+    return
+  end
+  return code
 end
 function table.load(filename,loader)
- if filename then
-  local t=(loader or io.loaddata)(filename)
-  if t and t~="" then
-   local t=utftoeight(t)
-   t=load(t)
-   if type(t)=="function" then
-    t=t()
-    if type(t)=="table" then
-     return t
+  if filename then
+    local t=(loader or io.loaddata)(filename)
+    if t and t~="" then
+      local t=utftoeight(t)
+      t=load(t)
+      if type(t)=="function" then
+        t=t()
+        if type(t)=="table" then
+          return t
+        end
+      end
     end
-   end
   end
- end
 end
 function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...)) 
+  io.savedata(filename,table.serialize(t,n==nil and true or n,...)) 
 end
 local f_key_value=formatters["%s=%q"]
 local f_add_table=formatters[" {%t},\n"]
 local f_return_table=formatters["return {\n%t}"]
 local function slowdrop(t) 
- local r={}
- local l={}
- for i=1,#t do
-  local ti=t[i]
-  local j=0
-  for k,v in next,ti do
-   j=j+1
-   l[j]=f_key_value(k,v)
+  local r={}
+  local l={}
+  for i=1,#t do
+    local ti=t[i]
+    local j=0
+    for k,v in next,ti do
+      j=j+1
+      l[j]=f_key_value(k,v)
+    end
+    r[i]=f_add_table(l)
   end
-  r[i]=f_add_table(l)
- end
- return f_return_table(r)
+  return f_return_table(r)
 end
 local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
-  local ti=t[i]
-  m=m+1 r[m]=" {"
-  for k,v in next,ti do
-   m=m+1 r[m]=f_key_value(k,v)
+  local r={ "return {\n" }
+  local m=1
+  for i=1,#t do
+    local ti=t[i]
+    m=m+1 r[m]=" {"
+    for k,v in next,ti do
+      m=m+1 r[m]=f_key_value(k,v)
+    end
+    m=m+1 r[m]="},\n"
   end
-  m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+  m=m+1
+  r[m]="}"
+  return concat(r)
 end
 function table.drop(t,slow) 
- if #t==0 then
-  return "return { }"
- elseif slow==true then
-  return slowdrop(t) 
- else
-  return fastdrop(t) 
- end
+  if #t==0 then
+    return "return { }"
+  elseif slow==true then
+    return slowdrop(t) 
+  else
+    return fastdrop(t) 
+  end
 end
 local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t) 
- if not t then     
-  t={}       
- else        
-  local zero=rawget(t,0)  
-  for i=zero and 0 or 1,#t do
-   local ti=t[i]    
-   if ti then
-    local i=tostring(i)
-    t[i]=ti   
-    t[ti]=i    
-   end
+function table.twowaymapper(t)  
+  if not t then         
+    t={}          
+  else             
+    local zero=rawget(t,0) 
+    for i=zero and 0 or 1,#t do
+      local ti=t[i]    
+      if ti then
+        local i=tostring(i)
+        t[i]=ti   
+        t[ti]=i    
+      end
+    end
   end
- end
- setmetatable(t,selfmapper)
- return t
+  setmetatable(t,selfmapper)
+  return t
 end
 local f_start_key_idx=formatters["%w{"]
 local f_start_key_num=formatters["%w[%s]={"]
@@ -7743,224 +7349,188 @@
 local original_serialize=table.serialize
 local is_simple_table=table.is_simple_table
 local function serialize(root,name,specification)
- if type(specification)=="table" then
-  return original_serialize(root,name,specification) 
- end
- local t 
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
-  if level>0 then
-   n=n+1
-   if indexed then
-    t[n]=f_start_key_idx(depth)
-   else
-    local tn=type(name)
-    if tn=="number" then
-     t[n]=f_start_key_num(depth,name)
-    elseif tn=="string" then
-     t[n]=f_start_key_str(depth,name)
-    elseif tn=="boolean" then
-     t[n]=f_start_key_boo(depth,name)
-    else
-     t[n]=f_start_key_nop(depth)
-    end
-   end
-   depth=depth+1
+  if type(specification)=="table" then
+    return original_serialize(root,name,specification) 
   end
-  if root and next(root)~=nil then
-   local first=nil
-   local last=0
-   last=#root
-   for k=1,last do
-    if rawget(root,k)==nil then
-     last=k-1
-     break
-    end
-   end
-   if last>0 then
-    first=1
-   end
-   local sk=sortedkeys(root) 
-   for i=1,#sk do
-    local k=sk[i]
-    local v=root[k]
-    local tv=type(v)
-    local tk=type(k)
-    if first and tk=="number" and k<=last and k>=first then
-     if tv=="number" then
-      n=n+1 t[n]=f_val_num(depth,v)
-     elseif tv=="string" then
-      n=n+1 t[n]=f_val_str(depth,v)
-     elseif tv=="table" then
-      if next(v)==nil then 
-       n=n+1 t[n]=f_val_not(depth)
+  local t  
+  local n=1
+  local unknown=false
+  local function do_serialize(root,name,depth,level,indexed)
+    if level>0 then
+      n=n+1
+      if indexed then
+        t[n]=f_start_key_idx(depth)
       else
-       local st=is_simple_table(v)
-       if st then
-        n=n+1 t[n]=f_val_seq(depth,st)
-       else
-        do_serialize(v,k,depth,level+1,true)
-       end
+        local tn=type(name)
+        if tn=="number" then
+          t[n]=f_start_key_num(depth,name)
+        elseif tn=="string" then
+          t[n]=f_start_key_str(depth,name)
+        elseif tn=="boolean" then
+          t[n]=f_start_key_boo(depth,name)
+        else
+          t[n]=f_start_key_nop(depth)
+        end
       end
-     elseif tv=="boolean" then
-      n=n+1 t[n]=f_val_boo(depth,v)
-     elseif unknown then
-      n=n+1 t[n]=f_val_str(depth,tostring(v))
-     end
-    elseif tv=="number" then
-     if tk=="number" then
-      n=n+1 t[n]=f_key_num_value_num(depth,k,v)
-     elseif tk=="string" then
-      n=n+1 t[n]=f_key_str_value_num(depth,k,v)
-     elseif tk=="boolean" then
-      n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
-     elseif unknown then
-      n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
-     end
-    elseif tv=="string" then
-     if tk=="number" then
-      n=n+1 t[n]=f_key_num_value_str(depth,k,v)
-     elseif tk=="string" then
-      n=n+1 t[n]=f_key_str_value_str(depth,k,v)
-     elseif tk=="boolean" then
-      n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
-     elseif unknown then
-      n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
-     end
-    elseif tv=="table" then
-     if next(v)==nil then
-      if tk=="number" then
-       n=n+1 t[n]=f_key_num_value_not(depth,k)
-      elseif tk=="string" then
-       n=n+1 t[n]=f_key_str_value_not(depth,k)
-      elseif tk=="boolean" then
-       n=n+1 t[n]=f_key_boo_value_not(depth,k)
-      elseif unknown then
-       n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
+      depth=depth+1
+    end
+    if root and next(root)~=nil then
+      local first=nil
+      local last=0
+      last=#root
+      for k=1,last do
+        if rawget(root,k)==nil then
+          last=k-1
+          break
+        end
       end
-     else
-      local st=is_simple_table(v)
-      if not st then
-       do_serialize(v,k,depth,level+1)
-      elseif tk=="number" then
-       n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
-      elseif tk=="string" then
-       n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
-      elseif tk=="boolean" then
-       n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
-      elseif unknown then
-       n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
+      if last>0 then
+        first=1
       end
-     end
-    elseif tv=="boolean" then
-     if tk=="number" then
-      n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
-     elseif tk=="string" then
-      n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
-     elseif tk=="boolean" then
-      n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
-     elseif unknown then
-      n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
-     end
+      local sk=sortedkeys(root) 
+      for i=1,#sk do
+        local k=sk[i]
+        local v=root[k]
+        local tv=type(v)
+        local tk=type(k)
+        if first and tk=="number" and k<=last and k>=first then
+          if tv=="number" then
+            n=n+1 t[n]=f_val_num(depth,v)
+          elseif tv=="string" then
+            n=n+1 t[n]=f_val_str(depth,v)
+          elseif tv=="table" then
+            if next(v)==nil then 
+              n=n+1 t[n]=f_val_not(depth)
+            else
+              local st=is_simple_table(v)
+              if st then
+                n=n+1 t[n]=f_val_seq(depth,st)
+              else
+                do_serialize(v,k,depth,level+1,true)
+              end
+            end
+          elseif tv=="boolean" then
+            n=n+1 t[n]=f_val_boo(depth,v)
+          elseif unknown then
+            n=n+1 t[n]=f_val_str(depth,tostring(v))
+          end
+        elseif tv=="number" then
+          if tk=="number" then
+            n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+          elseif tk=="string" then
+            n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+          elseif tk=="boolean" then
+            n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+          elseif unknown then
+            n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+          end
+        elseif tv=="string" then
+          if tk=="number" then
+            n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+          elseif tk=="string" then
+            n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+          elseif tk=="boolean" then
+            n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+          elseif unknown then
+            n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+          end
+        elseif tv=="table" then
+          if next(v)==nil then
+            if tk=="number" then
+              n=n+1 t[n]=f_key_num_value_not(depth,k)
+            elseif tk=="string" then
+              n=n+1 t[n]=f_key_str_value_not(depth,k)
+            elseif tk=="boolean" then
+              n=n+1 t[n]=f_key_boo_value_not(depth,k)
+            elseif unknown then
+              n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
+            end
+          else
+            local st=is_simple_table(v)
+            if not st then
+              do_serialize(v,k,depth,level+1)
+            elseif tk=="number" then
+              n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+            elseif tk=="string" then
+              n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+            elseif tk=="boolean" then
+              n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+            elseif unknown then
+              n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
+            end
+          end
+        elseif tv=="boolean" then
+          if tk=="number" then
+            n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+          elseif tk=="string" then
+            n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+          elseif tk=="boolean" then
+            n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+          elseif unknown then
+            n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+          end
+        else
+          if tk=="number" then
+            n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+          elseif tk=="string" then
+            n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+          elseif tk=="boolean" then
+            n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+          elseif unknown then
+            n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+          end
+        end
+      end
+    end
+    if level>0 then
+      n=n+1 t[n]=f_stop(depth-1)
+    end
+  end
+  local tname=type(name)
+  if tname=="string" then
+    if name=="return" then
+      t={ f_table_return() }
     else
-     if tk=="number" then
-      n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
-     elseif tk=="string" then
-      n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
-     elseif tk=="boolean" then
-      n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
-     elseif unknown then
-      n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
-     end
+      t={ f_table_name(name) }
     end
-   end
-  end
-  if level>0 then
-   n=n+1 t[n]=f_stop(depth-1)
-  end
- end
- local tname=type(name)
- if tname=="string" then
-  if name=="return" then
-   t={ f_table_return() }
+  elseif tname=="number" then
+    t={ f_table_entry(name) }
+  elseif tname=="boolean" then
+    if name then
+      t={ f_table_return() }
+    else
+      t={ f_table_direct() }
+    end
   else
-   t={ f_table_name(name) }
+    t={ f_table_name("t") }
   end
- elseif tname=="number" then
-  t={ f_table_entry(name) }
- elseif tname=="boolean" then
-  if name then
-   t={ f_table_return() }
-  else
-   t={ f_table_direct() }
+  if root then
+    if getmetatable(root) then 
+      local dummy=root._w_h_a_t_e_v_e_r_ 
+      root._w_h_a_t_e_v_e_r_=nil
+    end
+    if next(root)~=nil then
+      local st=is_simple_table(root)
+      if st then
+        return t[1]..f_fin_seq(st) 
+      else
+        do_serialize(root,name,1,0)
+      end
+    end
   end
- else
-  t={ f_table_name("t") }
- end
- if root then
-  if getmetatable(root) then 
-   local dummy=root._w_h_a_t_e_v_e_r_ 
-   root._w_h_a_t_e_v_e_r_=nil
-  end
-  if next(root)~=nil then
-   local st=is_simple_table(root)
-   if st then
-    return t[1]..f_fin_seq(st) 
-   else
-    do_serialize(root,name,1,0)
-   end
-  end
- end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+  n=n+1
+  t[n]=f_table_finish()
+  return concat(t,"\n")
 end
 table.serialize=serialize
 if setinspector then
- setinspector("table",function(v)
-  if type(v)=="table" then
-   print(serialize(v,"table",{ metacheck=false }))
-   return true
-  end
- end)
+  setinspector("table",function(v)
+    if type(v)=="table" then
+      print(serialize(v,"table",{ metacheck=false }))
+      return true
+    end
+  end)
 end
-local mt={
- __newindex=function(t,k,v)
-  local n=t.last+1
-  t.last=n
-  t.list[n]=k
-  t.hash[k]=v
- end,
- __index=function(t,k)
-  return t.hash[k]
- end,
- __len=function(t)
-  return t.last
- end,
-}
-function table.orderedhash()
- return setmetatable({ list={},hash={},last=0 },mt)
-end
-function table.ordered(t)
- local n=t.last
- if n>0 then
-  local l=t.list
-  local i=1
-  local h=t.hash
-  local f=function()
-   if i<=n then
-    local k=i
-    local v=h[l[k]]
-    i=i+1
-    return k,v
-   end
-  end
-  return f,1,h[l[1]]
- else
-  return function() end
- end
-end
 
 
 end -- of closure
@@ -7969,16 +7539,15 @@
 
 package.loaded["util-fil"] = package.loaded["util-fil"] or true
 
--- original size: 8607, stripped down to: 6727
+-- original size: 7787, stripped down to: 5858
 
 if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
-local tonumber=tonumber
 local byte=string.byte
 local char=string.char
 utilities=utilities or {}
@@ -7986,281 +7555,252 @@
 utilities.files=files
 local zerobased={}
 function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
-  zerobased[f]=zb or false
- end
- return f
+  local f=io.open(filename,"rb")
+  if f then
+    zerobased[f]=zb or false
+  end
+  return f
 end
 function files.close(f)
- zerobased[f]=nil
- f:close()
+  zerobased[f]=nil
+  f:close()
 end
 function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
+  local current=f:seek()
+  local size=f:seek("end")
+  f:seek("set",current)
+  return size
 end
 files.getsize=files.size
 function files.setposition(f,n)
- if zerobased[f] then
-  f:seek("set",n)
- else
-  f:seek("set",n-1)
- end
+  if zerobased[f] then
+    f:seek("set",n)
+  else
+    f:seek("set",n-1)
+  end
 end
 function files.getposition(f)
- if zerobased[f] then
-  return f:seek()
- else
-  return f:seek()+1
- end
+  if zerobased[f] then
+    return f:seek()
+  else
+    return f:seek()+1
+  end
 end
 function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
-  return s
- else
-  return byte(s,1,#s)
- end
+  local p=f:seek()
+  local s=f:read(n)
+  f:seek("set",p)
+  if chars then
+    return s
+  else
+    return byte(s,1,#s)
+  end
 end
 function files.skip(f,n)
- if n==1 then
-  f:read(n)
- else
-  f:seek("set",f:seek()+n)
- end
+  if n==1 then
+    f:read(n)
+  else
+    f:seek("set",f:seek()+n)
+  end
 end
 function files.readbyte(f)
- return byte(f:read(1))
+  return byte(f:read(1))
 end
 function files.readbytes(f,n)
- return byte(f:read(n),1,n)
+  return byte(f:read(n),1,n)
 end
 function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) } 
+  local s=f:read(n or 1)
+  return { byte(s,1,#s) } 
 end
 function files.readchar(f)
- return f:read(1)
+  return f:read(1)
 end
 function files.readstring(f,n)
- return f:read(n or 1)
+  return f:read(n or 1)
 end
-function files.readinteger1(f)  
- local n=byte(f:read(1))
- if n>=0x80 then
-  return n-0x100
- else
-  return n
- end
+function files.readinteger1(f) 
+  local n=byte(f:read(1))
+  if n>=0x80 then
+    return n-0x100
+  else
+    return n
+  end
 end
-files.readcardinal1=files.readbyte  
+files.readcardinal1=files.readbyte 
 files.readcardinal=files.readcardinal1
 files.readinteger=files.readinteger1
 files.readsignedbyte=files.readinteger1
 function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
+  local a,b=byte(f:read(2),1,2)
+  return 0x100*a+b
 end
 function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
+  local b,a=byte(f:read(2),1,2)
+  return 0x100*a+b
 end
 function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
-  return 0x100*a+b-0x10000
- else
-  return 0x100*a+b
- end
+  local a,b=byte(f:read(2),1,2)
+  if a>=0x80 then
+    return 0x100*a+b-0x10000
+  else
+    return 0x100*a+b
+  end
 end
 function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
-  return 0x100*a+b-0x10000
- else
-  return 0x100*a+b
- end
+  local b,a=byte(f:read(2),1,2)
+  if a>=0x80 then
+    return 0x100*a+b-0x10000
+  else
+    return 0x100*a+b
+  end
 end
 function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+  local a,b,c=byte(f:read(3),1,3)
+  return 0x10000*a+0x100*b+c
 end
 function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+  local c,b,a=byte(f:read(3),1,3)
+  return 0x10000*a+0x100*b+c
 end
 function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
-  return 0x10000*a+0x100*b+c-0x1000000
- else
-  return 0x10000*a+0x100*b+c
- end
+  local a,b,c=byte(f:read(3),1,3)
+  if a>=0x80 then
+    return 0x10000*a+0x100*b+c-0x1000000
+  else
+    return 0x10000*a+0x100*b+c
+  end
 end
 function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
-  return 0x10000*a+0x100*b+c-0x1000000
- else
-  return 0x10000*a+0x100*b+c
- end
+  local c,b,a=byte(f:read(3),1,3)
+  if a>=0x80 then
+    return 0x10000*a+0x100*b+c-0x1000000
+  else
+    return 0x10000*a+0x100*b+c
+  end
 end
 function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+  local a,b,c,d=byte(f:read(4),1,4)
+  return 0x1000000*a+0x10000*b+0x100*c+d
 end
 function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+  local d,c,b,a=byte(f:read(4),1,4)
+  return 0x1000000*a+0x10000*b+0x100*c+d
 end
 function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
-  return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
-  return 0x1000000*a+0x10000*b+0x100*c+d
- end
+  local a,b,c,d=byte(f:read(4),1,4)
+  if a>=0x80 then
+    return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+  else
+    return 0x1000000*a+0x10000*b+0x100*c+d
+  end
 end
 function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
-  return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
-  return 0x1000000*a+0x10000*b+0x100*c+d
- end
+  local d,c,b,a=byte(f:read(4),1,4)
+  if a>=0x80 then
+    return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+  else
+    return 0x1000000*a+0x10000*b+0x100*c+d
+  end
 end
 function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
-  tonumber((a-0x100).."."..b)
- else
-  tonumber((a    ).."."..b)
- end
+  local a,b=byte(f:read(2),1,2)
+  if a>=0x80 then
+    return (a-0x100)+b/0x100
+  else
+    return (a    )+b/0x100
+  end
 end
 function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
-  tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
-  tonumber((0x100*a+b    ).."."..(0x100*c+d))
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
-  local a,b=byte(f:read(2),1,2)
+  local a,b,c,d=byte(f:read(4),1,4)
   if a>=0x80 then
-   local n=-(0x100*a+b)
-   return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
   else
-   local n=0x100*a+b
-   return   (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    return (0x100*a+b     )+(0x100*c+d)/0x10000
   end
- end
 end
+if bit32 then
+  local extract=bit32.extract
+  local band=bit32.band
+  function files.read2dot14(f)
+    local a,b=byte(f:read(2),1,2)
+    if a>=0x80 then
+      local n=-(0x100*a+b)
+      return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    else
+      local n=0x100*a+b
+      return  (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    end
+  end
+end
 function files.skipshort(f,n)
- f:read(2*(n or 1))
+  f:read(2*(n or 1))
 end
 function files.skiplong(f,n)
- f:read(4*(n or 1))
+  f:read(4*(n or 1))
 end
 if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
+  local rshift=bit32.rshift
+  function files.writecardinal2(f,n)
+    local a=char(n%256)
+    n=rshift(n,8)
+    local b=char(n%256)
+    f:write(b,a)
+  end
+else
+  local floor=math.floor
+  function files.writecardinal2(f,n)
+    local a=char(n%256)
+    n=floor(n/256)
+    local b=char(n%256)
+    f:write(b,a)
+  end
+end
+function files.writecardinal4(f,n)
   local a=char(n%256)
   n=rshift(n,8)
   local b=char(n%256)
-  f:write(b,a)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
-  local a=char(n%256)
-  n=floor(n/256)
-  local b=char(n%256)
-  f:write(b,a)
- end
+  n=rshift(n,8)
+  local c=char(n%256)
+  n=rshift(n,8)
+  local d=char(n%256)
+  f:write(d,c,b,a)
 end
-function files.writecardinal4(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
-end
 function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
+  f:write(char(byte(s,1,#s)))
 end
 function files.writebyte(f,b)
- f:write(char(b))
+  f:write(char(b))
 end
 if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
-  skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
-  skipposition(f,4*(n or 1))
- end
+  files.readcardinal1=fio.readcardinal1
+  files.readcardinal2=fio.readcardinal2
+  files.readcardinal3=fio.readcardinal3
+  files.readcardinal4=fio.readcardinal4
+  files.readinteger1=fio.readinteger1
+  files.readinteger2=fio.readinteger2
+  files.readinteger3=fio.readinteger3
+  files.readinteger4=fio.readinteger4
+  files.readfixed2=fio.readfixed2
+  files.readfixed4=fio.readfixed4
+  files.read2dot14=fio.read2dot14
+  files.setposition=fio.setposition
+  files.getposition=fio.getposition
+  files.readbyte=files.readcardinal1
+  files.readsignedbyte=files.readinteger1
+  files.readcardinal=files.readcardinal1
+  files.readinteger=files.readinteger1
+  local skipposition=fio.skipposition
+  files.skipposition=skipposition
+  files.readbytes=fio.readbytes
+  files.readbytetable=fio.readbytetable
+  function files.skipshort(f,n)
+    skipposition(f,2*(n or 1))
+  end
+  function files.skiplong(f,n)
+    skipposition(f,4*(n or 1))
+  end
 end
-if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
-else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
-  local t={}
-   if b==1 then for i=1,n do t[i]=readcardinal1(f) end
-  elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
-  elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
-  elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
-  return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
-  local t={}
-   if b==1 then for i=1,n do t[i]=readinteger1(f) end
-  elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
-  elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
-  elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
-  return t
- end
-end
 
 
 end -- of closure
@@ -8269,412 +7809,338 @@
 
 package.loaded["util-sac"] = package.loaded["util-sac"] or true
 
--- original size: 11065, stripped down to: 8209
+-- original size: 8716, stripped down to: 6754
 
 if not modules then modules={} end modules ['util-sac']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local byte,sub=string.byte,string.sub
-local tonumber=tonumber
+local extract=bit32 and bit32.extract
 utilities=utilities or {}
 local streams={}
 utilities.streams=streams
 function streams.open(filename,zerobased)
- local f=filename and io.loaddata(filename)
- if f then
+  local f=io.loaddata(filename)
   return { f,1,#f,zerobased or false }
- end
 end
-function streams.openstring(f,zerobased)
- if f then
-  return { f,1,#f,zerobased or false }
- end
-end
 function streams.close()
 end
 function streams.size(f)
- return f and f[3] or 0
+  return f and f[3] or 0
 end
 function streams.setposition(f,i)
- if f[4] then
-  if i<=0 then
-   f[2]=1
+  if f[4] then
+    if i<=0 then
+      f[2]=1
+    else
+      f[2]=i+1
+    end
   else
-   f[2]=i+1
+    if i<=1 then
+      f[2]=1
+    else
+      f[2]=i
+    end
   end
- else
-  if i<=1 then
-   f[2]=1
+end
+function streams.getposition(f)
+  if f[4] then
+    return f[2]-1
   else
-   f[2]=i
+    return f[2]
   end
- end
 end
-function streams.getposition(f)
- if f[4] then
-  return f[2]-1
- else
-  return f[2]
- end
-end
 function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
-  return sub(f[1],b,e)
- else
-  return byte(f[1],b,e)
- end
+  local b=f[2]
+  local e=b+n-1
+  if chars then
+    return sub(f[1],b,e)
+  else
+    return byte(f[1],b,e)
+  end
 end
 function streams.skip(f,n)
- f[2]=f[2]+n
+  f[2]=f[2]+n
 end
 function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+  local i=f[2]
+  f[2]=i+1
+  return byte(f[1],i)
 end
 function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+  local i=f[2]
+  local j=i+n
+  f[2]=j
+  return byte(f[1],i,j-1)
 end
 function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+  local i=f[2]
+  local j=i+n
+  f[2]=j
+  return { byte(f[1],i,j-1) }
 end
 function streams.skipbytes(f,n)
- f[2]=f[2]+n
+  f[2]=f[2]+n
 end
 function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+  local i=f[2]
+  f[2]=i+1
+  return sub(f[1],i,i)
 end
 function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
+  local i=f[2]
+  local j=i+n
+  f[2]=j
+  return sub(f[1],i,j-1)
 end
-function streams.readinteger1(f)  
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
-  return n-0x100
- else
-  return n
- end
+function streams.readinteger1(f) 
+  local i=f[2]
+  f[2]=i+1
+  local n=byte(f[1],i)
+  if n>=0x80 then
+    return n-0x100
+  else
+    return n
+  end
 end
-streams.readcardinal1=streams.readbyte  
+streams.readcardinal1=streams.readbyte 
 streams.readcardinal=streams.readcardinal1
 streams.readinteger=streams.readinteger1
 function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+  local i=f[2]
+  local j=i+1
+  f[2]=j+1
+  local a,b=byte(f[1],i,j)
+  return 0x100*a+b
 end
 function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+  local i=f[2]
+  local j=i+1
+  f[2]=j+1
+  local b,a=byte(f[1],i,j)
+  return 0x100*a+b
 end
 function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
-  return 0x100*a+b-0x10000
- else
-  return 0x100*a+b
- end
+  local i=f[2]
+  local j=i+1
+  f[2]=j+1
+  local a,b=byte(f[1],i,j)
+  if a>=0x80 then
+    return 0x100*a+b-0x10000
+  else
+    return 0x100*a+b
+  end
 end
 function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
-  return 0x100*a+b-0x10000
- else
-  return 0x100*a+b
- end
+  local i=f[2]
+  local j=i+1
+  f[2]=j+1
+  local b,a=byte(f[1],i,j)
+  if a>=0x80 then
+    return 0x100*a+b-0x10000
+  else
+    return 0x100*a+b
+  end
 end
 function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+  local i=f[2]
+  local j=i+2
+  f[2]=j+1
+  local a,b,c=byte(f[1],i,j)
+  return 0x10000*a+0x100*b+c
 end
 function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+  local i=f[2]
+  local j=i+2
+  f[2]=j+1
+  local c,b,a=byte(f[1],i,j)
+  return 0x10000*a+0x100*b+c
 end
 function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
-  return 0x10000*a+0x100*b+c-0x1000000
- else
-  return 0x10000*a+0x100*b+c
- end
+  local i=f[2]
+  local j=i+3
+  f[2]=j+1
+  local a,b,c=byte(f[1],i,j)
+  if a>=0x80 then
+    return 0x10000*a+0x100*b+c-0x1000000
+  else
+    return 0x10000*a+0x100*b+c
+  end
 end
 function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
-  return 0x10000*a+0x100*b+c-0x1000000
- else
-  return 0x10000*a+0x100*b+c
- end
+  local i=f[2]
+  local j=i+3
+  f[2]=j+1
+  local c,b,a=byte(f[1],i,j)
+  if a>=0x80 then
+    return 0x10000*a+0x100*b+c-0x1000000
+  else
+    return 0x10000*a+0x100*b+c
+  end
 end
 function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+  local i=f[2]
+  local j=i+3
+  f[2]=j+1
+  local a,b,c,d=byte(f[1],i,j)
+  return 0x1000000*a+0x10000*b+0x100*c+d
 end
 function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
-  return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
-  return 0x1000000*a+0x10000*b+0x100*c+d
- end
+  local i=f[2]
+  local j=i+3
+  f[2]=j+1
+  local a,b,c,d=byte(f[1],i,j)
+  if a>=0x80 then
+    return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+  else
+    return 0x1000000*a+0x10000*b+0x100*c+d
+  end
 end
 function streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
-  return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
-  return 0x1000000*a+0x10000*b+0x100*c+d
- end
+  local i=f[2]
+  local j=i+3
+  f[2]=j+1
+  local d,c,b,a=byte(f[1],i,j)
+  if a>=0x80 then
+    return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+  else
+    return 0x1000000*a+0x10000*b+0x100*c+d
+  end
 end
-function streams.readfixed2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
-  tonumber((a-0x100).."."..b)
- else
-  tonumber((a  ).."."..b)
- end
-end
 function streams.readfixed4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
-  tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
-  tonumber((0x100*a+b    ).."."..(0x100*c+d))
- end
+  local i=f[2]
+  local j=i+3
+  f[2]=j+1
+  local a,b,c,d=byte(f[1],i,j)
+  if a>=0x80 then
+    return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
+  else
+    return (0x100*a+b     )+(0x100*c+d)/0x10000
+  end
 end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
+function streams.readfixed2(f)
   local i=f[2]
   local j=i+1
   f[2]=j+1
   local a,b=byte(f[1],i,j)
   if a>=0x80 then
-   local n=-(0x100*a+b)
-   return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    return (a-0x100)+b/0x100
   else
-   local n=0x100*a+b
-   return   (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    return (a    )+b/0x100
   end
- end
 end
+if extract then
+  local extract=bit32.extract
+  local band=bit32.band
+  function streams.read2dot14(f)
+    local i=f[2]
+    local j=i+1
+    f[2]=j+1
+    local a,b=byte(f[1],i,j)
+    if a>=0x80 then
+      local n=-(0x100*a+b)
+      return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    else
+      local n=0x100*a+b
+      return  (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+    end
+  end
+end
 function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+  f[2]=f[2]+2*(n or 1)
 end
 function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+  f[2]=f[2]+4*(n or 1)
 end
 if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
-  local i=f[2]
-  f[2]=i+1
-  return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
-  local i=f[2]
-  f[2]=i+2
-  return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
-  local i=f[2]
-  f[2]=i+3
-  return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
-  local i=f[2]
-  f[2]=i+4
-  return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
-  local i=f[2]
-  f[2]=i+1
-  return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
-  local i=f[2]
-  f[2]=i+2
-  return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
-  local i=f[2]
-  f[2]=i+3
-  return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
-  local i=f[2]
-  f[2]=i+4
-  return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
-  local i=f[2]
-  f[2]=i+2
-  return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
-  local i=f[2]
-  local s=f[3]
-  local p=i+n
-  if p>s then
-   f[2]=s+1
-  else
-   f[2]=p
+  local readcardinal1=sio.readcardinal1
+  local readcardinal2=sio.readcardinal2
+  local readcardinal3=sio.readcardinal3
+  local readcardinal4=sio.readcardinal4
+  local readinteger1=sio.readinteger1
+  local readinteger2=sio.readinteger2
+  local readinteger3=sio.readinteger3
+  local readinteger4=sio.readinteger4
+  local readfixed2=sio.readfixed2
+  local readfixed4=sio.readfixed4
+  local read2dot14=sio.read2dot14
+  local readbytes=sio.readbytes
+  local readbytetable=sio.readbytetable
+  function streams.readcardinal1(f)
+    local i=f[2]
+    f[2]=i+1
+    return readcardinal1(f[1],i)
   end
-  return readbytes(f[1],i,n)
- end
- function streams.readbytetable(f,n)
-  local i=f[2]
-  local s=f[3]
-  local p=i+n
-  if p>s then
-   f[2]=s+1
-  else
-   f[2]=p
+  function streams.readcardinal2(f)
+    local i=f[2]
+    f[2]=i+2
+    return readcardinal2(f[1],i)
   end
-  return readbytetable(f[1],i,n)
- end
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
-end
-if sio and sio.readcardinaltable then
- local readcardinaltable=sio.readcardinaltable
- local readintegertable=sio.readintegertable
- function utilities.streams.readcardinaltable(f,n,b)
-  local i=f[2]
-  local s=f[3]
-  local p=i+n*b
-  if p>s then
-   f[2]=s+1
-  else
-   f[2]=p
+  function streams.readcardinal3(f)
+    local i=f[2]
+    f[2]=i+3
+    return readcardinal3(f[1],i)
   end
-  return readcardinaltable(f[1],i,n,b)
- end
- function utilities.streams.readintegertable(f,n,b)
-  local i=f[2]
-  local s=f[3]
-  local p=i+n*b
-  if p>s then
-   f[2]=s+1
-  else
-   f[2]=p
+  function streams.readcardinal4(f)
+    local i=f[2]
+    f[2]=i+4
+    return readcardinal4(f[1],i)
   end
-  return readintegertable(f[1],i,n,b)
- end
-else
- local readcardinal1=streams.readcardinal1
- local readcardinal2=streams.readcardinal2
- local readcardinal3=streams.readcardinal3
- local readcardinal4=streams.readcardinal4
- function streams.readcardinaltable(f,n,b)
-  local i=f[2]
-  local s=f[3]
-  local p=i+n*b
-  if p>s then
-   f[2]=s+1
-  else
-   f[2]=p
+  function streams.readinteger1(f)
+    local i=f[2]
+    f[2]=i+1
+    return readinteger1(f[1],i)
   end
-  local t={}
-   if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
-  elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
-  elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
-  elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
-  return t
- end
- local readinteger1=streams.readinteger1
- local readinteger2=streams.readinteger2
- local readinteger3=streams.readinteger3
- local readinteger4=streams.readinteger4
- function streams.readintegertable(f,n,b)
-  local i=f[2]
-  local s=f[3]
-  local p=i+n*b
-  if p>s then
-   f[2]=s+1
-  else
-   f[2]=p
+  function streams.readinteger2(f)
+    local i=f[2]
+    f[2]=i+2
+    return readinteger2(f[1],i)
   end
-  local t={}
-   if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
-  elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
-  elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
-  elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
-  return t
- end
+  function streams.readinteger3(f)
+    local i=f[2]
+    f[2]=i+3
+    return readinteger3(f[1],i)
+  end
+  function streams.readinteger4(f)
+    local i=f[2]
+    f[2]=i+4
+    return readinteger4(f[1],i)
+  end
+  function streams.read2dot4(f)
+    local i=f[2]
+    f[2]=i+2
+    return read2dot4(f[1],i)
+  end
+  function streams.readbytes(f,n)
+    local i=f[2]
+    local s=f[3]
+    local p=i+n
+    if p>s then
+      f[2]=s+1
+    else
+      f[2]=p
+    end
+    return readbytes(f[1],i,n)
+  end
+  function streams.readbytetable(f,n)
+    local i=f[2]
+    local s=f[3]
+    local p=i+n
+    if p>s then
+      f[2]=s+1
+    else
+      f[2]=p
+    end
+    return readbytetable(f[1],i,n)
+  end
+  streams.readbyte=streams.readcardinal1
+  streams.readsignedbyte=streams.readinteger1
+  streams.readcardinal=streams.readcardinal1
+  streams.readinteger=streams.readinteger1
 end
 
 
@@ -8684,14 +8150,14 @@
 
 package.loaded["util-sto"] = package.loaded["util-sto"] or true
 
--- original size: 6661, stripped down to: 3074
+-- original size: 6449, stripped down to: 3069
 
 if not modules then modules={} end modules ['util-sto']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
 utilities=utilities or {}
@@ -8698,155 +8164,143 @@
 utilities.storage=utilities.storage or {}
 local storage=utilities.storage
 function storage.mark(t)
- if not t then
-  print("\nfatal error: storage cannot be marked\n")
-  os.exit()
-  return
- end
- local m=getmetatable(t)
- if not m then
-  m={}
-  setmetatable(t,m)
- end
- m.__storage__=true
- return t
+  if not t then
+    print("\nfatal error: storage cannot be marked\n")
+    os.exit()
+    return
+  end
+  local m=getmetatable(t)
+  if not m then
+    m={}
+    setmetatable(t,m)
+  end
+  m.__storage__=true
+  return t
 end
 function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
-  m={}
-  setmetatable(t,m)
- end
- m.__storage__=true
- return t
+  t=t or {}
+  local m=getmetatable(t)
+  if not m then
+    m={}
+    setmetatable(t,m)
+  end
+  m.__storage__=true
+  return t
 end
 function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+  local m=getmetatable(t)
+  return m and m.__storage__
 end
 function storage.checked(t)
- if not t then
-  report("\nfatal error: storage has not been allocated\n")
-  os.exit()
-  return
- end
- return t
+  if not t then
+    report("\nfatal error: storage has not been allocated\n")
+    os.exit()
+    return
+  end
+  return t
 end
 function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
-  m.__index=nil 
-  initialize()
-  return data[k]
- end
- setmetatable(data,m)
+  local m=getmetatable(data) or {}
+  m.__index=function(data,k)
+    m.__index=nil 
+    initialize()
+    return data[k]
+  end
+  setmetatable(data,m)
 end
 local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+  t[k]=k
+  return k
 end }
 function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
+  t=t or {}
+  setmetatable(t,keyisvalue)
+  return t
 end
-local function f_empty ()         return "" end 
-local function f_self  (t,k) t[k]=k      return k  end
-local function f_table (t,k) local v={} t[k]=v return v  end
-local function f_number(t,k) t[k]=0      return 0  end 
-local function f_ignore()          end 
+local function f_empty ()              return "" end 
+local function f_self (t,k) t[k]=k        return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0        return 0 end 
+local function f_ignore()                   end 
 local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+  ["empty"]=f_empty,
+  ["self"]=f_self,
+  ["table"]=f_table,
+  ["number"]=f_number,
 }
 function table.setmetatableindex(t,f)
- if type(t)~="table" then
-  f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
-  m.__index=i
- else
-  setmetatable(t,{ __index=i })
- end
- return t
+  if type(t)~="table" then
+    f,t=t,{}
+  end
+  local m=getmetatable(t)
+  local i=f_index[f] or f
+  if m then
+    m.__index=i
+  else
+    setmetatable(t,{ __index=i })
+  end
+  return t
 end
 local f_index={
- ["ignore"]=f_ignore,
+  ["ignore"]=f_ignore,
 }
 function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
-  f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
-  m.__newindex=i
- else
-  setmetatable(t,{ __newindex=i })
- end
- return t
+  if type(t)~="table" then
+    f,t=t,{}
+  end
+  local m=getmetatable(t)
+  local i=f_index[f] or f
+  if m then
+    m.__newindex=i
+  else
+    setmetatable(t,{ __newindex=i })
+  end
+  return t
 end
 function table.setmetatablecall(t,f)
- if type(t)~="table" then
-  f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
-  m.__call=f
- else
-  setmetatable(t,{ __call=f })
- end
- return t
+  if type(t)~="table" then
+    f,t=t,{}
+  end
+  local m=getmetatable(t)
+  if m then
+    m.__call=f
+  else
+    setmetatable(t,{ __call=f })
+  end
+  return t
 end
 function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
-  f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
-  m.__index=i
-  m.__newindex=n
-  m.__call=c
- else
-  setmetatable(t,{
-   __index=i,
-   __newindex=n,
-   __call=c,
-  })
- end
- return t
+  if type(t)~="table" then
+    f,t=t,{}
+  end
+  local m=getmetatable(t)
+  local i=f_index[f] or f
+  if m then
+    m.__index=i
+    m.__newindex=n
+    m.__call=c
+  else
+    setmetatable(t,{
+      __index=i,
+      __newindex=n,
+      __call=c,
+    })
+  end
+  return t
 end
 function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
-  m={}
-  setmetatable(t,m)
- end
- m[key]=value
- return t
+  local m=getmetatable(t)
+  if not m then
+    m={}
+    setmetatable(t,m)
+  end
+  m[key]=value
+  return t
 end
 function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+  local m=getmetatable(t)
+  return m and m[key]
 end
-function table.makeweak(t)
- if not t then
-  t={}
- end
- local m=getmetatable(t)
- if m then
-  m.__mode="v"
- else
-  setmetatable(t,{ __mode="v" })
- end
- return t
-end
 
 
 end -- of closure
@@ -8855,14 +8309,14 @@
 
 package.loaded["util-prs"] = package.loaded["util-prs"] or true
 
--- original size: 23460, stripped down to: 15834
+-- original size: 22956, stripped down to: 16106
 
 if not modules then modules={} end modules ['util-prs']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local lpeg,table,string=lpeg,table,string
 local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8884,7 +8338,6 @@
 local digit=R("09")
 local space=P(' ')
 local equal=P("=")
-local colon=P(":")
 local comma=P(",")
 local lbrace=P("{")
 local rbrace=P("}")
@@ -8904,8 +8357,8 @@
 local nobracket=1-(lbracket+rbracket)
 local escape,left,right=P("\\"),P('{'),P('}')
 lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+  [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+  [2]=left*V(1)*right
 }
 local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
 local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8913,329 +8366,311 @@
 local spaces=space^0
 local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
 local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces  
+lpegpatterns.nestedbraces=nestedbraces 
 lpegpatterns.nestedparents=nestedparents 
-lpegpatterns.nested=nestedbraces  
+lpegpatterns.nested=nestedbraces 
 lpegpatterns.argument=argument   
 lpegpatterns.content=content    
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
+local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+(1-comma))^0)
 local key=C((1-equal-comma)^1)
 local pattern_a=(space+comma)^0*(key*equal*value+key*C(""))
 local pattern_c=(space+comma)^0*(key*equal*value)
-local pattern_d=(space+comma)^0*(key*(equal+colon)*value+key*C(""))
 local key=C((1-space-equal-comma)^1)
 local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
 local hash={}
 local function set(key,value)
- hash[key]=value
+  hash[key]=value
 end
 local pattern_a_s=(pattern_a/set)^1
 local pattern_b_s=(pattern_b/set)^1
 local pattern_c_s=(pattern_c/set)^1
-local pattern_d_s=(pattern_d/set)^1
 patterns.settings_to_hash_a=pattern_a_s
 patterns.settings_to_hash_b=pattern_b_s
 patterns.settings_to_hash_c=pattern_c_s
-patterns.settings_to_hash_d=pattern_d_s
 function parsers.make_settings_to_hash_pattern(set,how)
- if how=="strict" then
-  return (pattern_c/set)^1
- elseif how=="tolerant" then
-  return (pattern_b/set)^1
- else
-  return (pattern_a/set)^1
- end
+  if how=="strict" then
+    return (pattern_c/set)^1
+  elseif how=="tolerant" then
+    return (pattern_b/set)^1
+  else
+    return (pattern_a/set)^1
+  end
 end
 function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
-  return {}
- elseif type(str)=="table" then
-  if existing then
-   for k,v in next,str do
-    existing[k]=v
-   end
-   return exiting
+  if not str or str=="" then
+    return {}
+  elseif type(str)=="table" then
+    if existing then
+      for k,v in next,str do
+        existing[k]=v
+      end
+      return exiting
+    else
+      return str
+    end
   else
-   return str
+    hash=existing or {}
+    lpegmatch(pattern_a_s,str)
+    return hash
   end
- else
-  hash=existing or {}
-  lpegmatch(pattern_a_s,str)
-  return hash
- end
 end
-function parsers.settings_to_hash_colon_too(str)
- if not str or str=="" then
-  return {}
- elseif type(str)=="table" then
-  return str
- else
-  hash={}
-  lpegmatch(pattern_d_s,str)
-  return hash
- end
-end
 function parsers.settings_to_hash_tolerant(str,existing)
- if not str or str=="" then
-  return {}
- elseif type(str)=="table" then
-  if existing then
-   for k,v in next,str do
-    existing[k]=v
-   end
-   return exiting
+  if not str or str=="" then
+    return {}
+  elseif type(str)=="table" then
+    if existing then
+      for k,v in next,str do
+        existing[k]=v
+      end
+      return exiting
+    else
+      return str
+    end
   else
-   return str
+    hash=existing or {}
+    lpegmatch(pattern_b_s,str)
+    return hash
   end
- else
-  hash=existing or {}
-  lpegmatch(pattern_b_s,str)
-  return hash
- end
 end
 function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
-  return nil
- elseif type(str)=="table" then
-  if existing then
-   for k,v in next,str do
-    existing[k]=v
-   end
-   return exiting
-  else
-   return str
+  if not str or str=="" then
+    return nil
+  elseif type(str)=="table" then
+    if existing then
+      for k,v in next,str do
+        existing[k]=v
+      end
+      return exiting
+    else
+      return str
+    end
+  elseif str and str~="" then
+    hash=existing or {}
+    lpegmatch(pattern_c_s,str)
+    return next(hash) and hash
   end
- elseif str and str~="" then
-  hash=existing or {}
-  lpegmatch(pattern_c_s,str)
-  return next(hash) and hash
- end
 end
 local separator=comma*space^0
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
+local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+(1-comma))^0)
 local pattern=spaces*Ct(value*(separator*value)^0)
 patterns.settings_to_array=pattern
 function parsers.settings_to_array(str,strict)
- if not str or str=="" then
-  return {}
- elseif type(str)=="table" then
-  return str
- elseif strict then
-  if find(str,"{",1,true) then
-   return lpegmatch(pattern,str)
+  if not str or str=="" then
+    return {}
+  elseif type(str)=="table" then
+    return str
+  elseif strict then
+    if find(str,"{",1,true) then
+      return lpegmatch(pattern,str)
+    else
+      return { str }
+    end
+  elseif find(str,",",1,true) then
+    return lpegmatch(pattern,str)
   else
-   return { str }
+    return { str }
   end
- elseif find(str,",",1,true) then
-  return lpegmatch(pattern,str)
- else
-  return { str }
- end
 end
 function parsers.settings_to_numbers(str)
- if not str or str=="" then
-  return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
-  str=lpegmatch(pattern,str)
- else
-  return { tonumber(str) }
- end
- for i=1,#str do
-  str[i]=tonumber(str[i])
- end
- return str
+  if not str or str=="" then
+    return {}
+  end
+  if type(str)=="table" then
+  elseif find(str,",",1,true) then
+    str=lpegmatch(pattern,str)
+  else
+    return { tonumber(str) }
+  end
+  for i=1,#str do
+    str[i]=tonumber(str[i])
+  end
+  return str
 end
-local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
+local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
 local pattern=spaces*Ct(value*(separator*value)^0)
 function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+  return lpegmatch(pattern,str)
 end
 local cache_a={}
 local cache_b={}
 function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
-  symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
-  local symbols=S(symbol)
-  local separator=space^0*symbols*space^0
-  local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
-  if withaction then
-   local withvalue=Carg(1)*value/function(f,s) return f(s) end
-   pattern=spaces*withvalue*(separator*withvalue)^0
-   cache_b[symbol]=pattern
-  else
-   pattern=spaces*Ct(value*(separator*value)^0)
-   cache_a[symbol]=pattern
+  if not symbol then
+    symbol=","
   end
- end
- return pattern
+  local pattern=(withaction and cache_b or cache_a)[symbol]
+  if not pattern then
+    local symbols=S(symbol)
+    local separator=space^0*symbols*space^0
+    local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+    if withaction then
+      local withvalue=Carg(1)*value/function(f,s) return f(s) end
+      pattern=spaces*withvalue*(separator*withvalue)^0
+      cache_b[symbol]=pattern
+    else
+      pattern=spaces*Ct(value*(separator*value)^0)
+      cache_a[symbol]=pattern
+    end
+  end
+  return pattern
 end
 local pattern_a=parsers.groupedsplitat(",",false)
 local pattern_b=parsers.groupedsplitat(",",true)
 function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
-  return {}
- else
-  return lpegmatch(pattern_a,str)
- end
+  if not str or str=="" then
+    return {}
+  else
+    return lpegmatch(pattern_a,str)
+  end
 end
 function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
-  return {}
- else
-  return lpegmatch(pattern_b,str,1,action)
- end
+  if not str or str=="" then
+    return {}
+  else
+    return lpegmatch(pattern_b,str,1,action)
+  end
 end
 local function set(t,v)
- t[#t+1]=v
+  t[#t+1]=v
 end
 local value=P(Carg(1)*value)/set
 local pattern=value*(separator*value)^0*Carg(1)
 function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+  return lpegmatch(pattern,str,nil,t)
 end
 function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
-  local t={}
-  local tn=0
-  local s=sortedkeys(h)
-  omit=omit and tohash(omit)
-  for i=1,#s do
-   local key=s[i]
-   if not omit or not omit[key] then
-    local value=h[key]
-    if type(value)=="boolean" then
-     if yes and no then
-      if value then
-       tn=tn+1
-       t[tn]=key..'='..yes
-      elseif not strict then
-       tn=tn+1
-       t[tn]=key..'='..no
+  if h then
+    local t,tn,s={},0,sortedkeys(h)
+    omit=omit and tohash(omit)
+    for i=1,#s do
+      local key=s[i]
+      if not omit or not omit[key] then
+        local value=h[key]
+        if type(value)=="boolean" then
+          if yes and no then
+            if value then
+              tn=tn+1
+              t[tn]=key..'='..yes
+            elseif not strict then
+              tn=tn+1
+              t[tn]=key..'='..no
+            end
+          elseif value or not strict then
+            tn=tn+1
+            t[tn]=key..'='..tostring(value)
+          end
+        else
+          tn=tn+1
+          t[tn]=key..'='..value
+        end
       end
-     elseif value or not strict then
-      tn=tn+1
-      t[tn]=key..'='..tostring(value)
-     end
-    else
-     tn=tn+1
-     t[tn]=key..'='..value
     end
-   end
+    return concat(t,separator or ",")
+  else
+    return ""
   end
-  return concat(t,separator or ",")
- else
-  return ""
- end
 end
 function parsers.array_to_string(a,separator)
- if a then
-  return concat(a,separator or ",")
- else
-  return ""
- end
+  if a then
+    return concat(a,separator or ",")
+  else
+    return ""
+  end
 end
 local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
 function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+  return str and lpegmatch(pattern,str) or {}
 end
 hashes.settings_to_set=table.setmetatableindex(function(t,k) 
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+  local v=k and lpegmatch(pattern,k) or {}
+  t[k]=v
+  return v
 end)
 getmetatable(hashes.settings_to_set).__mode="kv" 
 function parsers.simple_hash_to_string(h,separator)
- local t={}
- local tn=0
- for k,v in sortedhash(h) do
-  if v then
-   tn=tn+1
-   t[tn]=k
+  local t,tn={},0
+  for k,v in sortedhash(h) do
+    if v then
+      tn=tn+1
+      t[tn]=k
+    end
   end
- end
- return concat(t,separator or ",")
+  return concat(t,separator or ",")
 end
 local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
 local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
 local splitter=setting^1
 function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+  return str and lpegmatch(splitter,str,1,target or {}) or {}
 end
 local splitter=lpeg.tsplitat(" ")
 function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+  return str and lpegmatch(splitter,str) or {}
 end
 local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
 local pattern_a=spaces*Ct(value*(separator*value)^0)
 local function repeater(n,str)
- if not n then
-  return str
- else
-  local s=lpegmatch(pattern_a,str)
-  if n==1 then
-   return unpack(s)
+  if not n then
+    return str
   else
-   local t={}
-   local tn=0
-   for i=1,n do
-    for j=1,#s do
-     tn=tn+1
-     t[tn]=s[j]
+    local s=lpegmatch(pattern_a,str)
+    if n==1 then
+      return unpack(s)
+    else
+      local t,tn={},0
+      for i=1,n do
+        for j=1,#s do
+          tn=tn+1
+          t[tn]=s[j]
+        end
+      end
+      return unpack(t)
     end
-   end
-   return unpack(t)
   end
- end
 end
 local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
 local pattern_b=spaces*Ct(value*(separator*value)^0)
 function parsers.settings_to_array_with_repeat(str,expand) 
- if expand then
-  return lpegmatch(pattern_b,str) or {}
- else
-  return lpegmatch(pattern_a,str) or {}
- end
+  if expand then
+    return lpegmatch(pattern_b,str) or {}
+  else
+    return lpegmatch(pattern_a,str) or {}
+  end
 end
 local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
 local pattern=Ct((space+value)^0)
 function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+  return lpegmatch(pattern,str)
 end
 function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
-  sc={}
-  self[class]=sc
-  if parentclass then
-   local sp=self[parentclass]
-   if not sp then
-    sp={}
-    self[parentclass]=sp
-   end
-   setmetatableindex(sc,sp)
+  local sc=self[class]
+  if not sc then
+    sc={}
+    self[class]=sc
+    if parentclass then
+      local sp=self[parentclass]
+      if not sp then
+        sp={}
+        self[parentclass]=sp
+      end
+      setmetatableindex(sc,sp)
+    end
   end
- end
- parsers.settings_to_hash(settings,sc)
+  parsers.settings_to_hash(settings,sc)
 end
 function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+  return gmatch(str,"[^, ]+")
 end
 local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+  start=V("one")+V("two")+V("three"),
+  rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+  thousand=digit*digit*digit,
+  one=digit*V("rest"),
+  two=digit*digit*V("rest"),
+  three=V("thousand")*V("rest"),
 }
 lpegpatterns.splitthousands=pattern 
 function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+  return lpegmatch(pattern,str) or str
 end
 local optionalwhitespace=whitespace^0
 lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -9249,75 +8684,75 @@
 local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
 local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
 function parsers.keq_to_hash(str)
- if str and str~="" then
-  return lpegmatch(pattern,str)
- else
-  return {}
- end
+  if str and str~="" then
+    return lpegmatch(pattern,str)
+  else
+    return {}
+  end
 end
 local defaultspecification={ separator=",",quote='"' }
 function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
-  local quotedata=nil
-  for chr in gmatch(quotechar,".") do
-   local quotechar=P(chr)
-   local quoteword=quotechar*C((1-quotechar)^0)*quotechar
-   if quotedata then
-    quotedata=quotedata+quoteword
-   else
-    quotedata=quoteword
-   end
+  specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+  local separator=specification.separator
+  local quotechar=specification.quote
+  local separator=S(separator~="" and separator or ",")
+  local whatever=C((1-separator-newline)^0)
+  if quotechar and quotechar~="" then
+    local quotedata=nil
+    for chr in gmatch(quotechar,".") do
+      local quotechar=P(chr)
+      local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+      if quotedata then
+        quotedata=quotedata+quoteword
+      else
+        quotedata=quoteword
+      end
+    end
+    whatever=quotedata+whatever
   end
-  whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
-  return lpegmatch(parser,data)
- end
+  local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+  return function(data)
+    return lpegmatch(parser,data)
+  end
 end
 function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator 
- local quotechar=P(specification.quote)  
- local dquotechar=quotechar*quotechar   
+  specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+  local separator=specification.separator 
+  local quotechar=P(specification.quote) 
+  local dquotechar=quotechar*quotechar  
 /specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
-  if getheader then
-   local header,position=lpegmatch(headerline,data)
-   local data=lpegmatch(headeryes,data,position)
-   return data,header
-  else
-   return lpegmatch(headernop,data)
+  local separator=S(separator~="" and separator or ",")
+  local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+  local non_escaped=C((1-quotechar-newline-separator)^1)
+  local field=escaped+non_escaped+Cc("")
+  local record=Ct(field*(separator*field)^1)
+  local headerline=record*Cp()
+  local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+  local headeryes=Ct(morerecords)
+  local headernop=Ct(record*morerecords)
+  return function(data,getheader)
+    if getheader then
+      local header,position=lpegmatch(headerline,data)
+      local data=lpegmatch(headeryes,data,position)
+      return data,header
+    else
+      return lpegmatch(headernop,data)
+    end
   end
- end
 end
 local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
-  for i=first,n or first do
-   action(i)
+  if not first then
+  elseif last==true then
+    for i=first,n or first do
+      action(i)
+    end
+  elseif last then
+    for i=first,last do
+      action(i)
+    end
+  else
+    action(first)
   end
- elseif last then
-  for i=first,last do
-   action(i)
-  end
- else
-  action(first)
- end
 end
 local cardinal=lpegpatterns.cardinal/tonumber
 local spacers=lpegpatterns.spacer^0
@@ -9325,89 +8760,89 @@
 local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
 local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring 
 function parsers.stepper(str,n,action)
- if type(n)=="function" then
-  lpegmatch(stepper,str,1,false,n or print)
- else
-  lpegmatch(stepper,str,1,n,action or print)
- end
+  if type(n)=="function" then
+    lpegmatch(stepper,str,1,false,n or print)
+  else
+    lpegmatch(stepper,str,1,n,action or print)
+  end
 end
 local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
 local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
 patterns.unittotex=pattern
 function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+  return lpegmatch(textmode and pattern_text or pattern_math,str)
 end
 local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
 function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+  return lpegmatch(pattern,str)
 end
 local cache={}
 local spaces=lpegpatterns.space^0
 local dummy=function() end
 setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+  local separator=P(k)
+  local value=(1-separator)^0
+  local pattern=spaces*C(value)*separator^0*Cp()
+  t[k]=pattern
+  return pattern
 end)
 local commalistiterator=cache[","]
 function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
-  return dummy
- else
-  local pattern=separator and cache[separator] or commalistiterator
-  local p=1
-  return function()
-   if p<=n then
-    local s,e=lpegmatch(pattern,str,p)
-    if e then
-     p=e
-     return s
+  local n=#str
+  if n==0 then
+    return dummy
+  else
+    local pattern=separator and cache[separator] or commalistiterator
+    local p=1
+    return function()
+      if p<=n then
+        local s,e=lpegmatch(pattern,str,p)
+        if e then
+          p=e
+          return s
+        end
+      end
     end
-   end
   end
- end
 end
 local function initialize(t,name)
- local source=t[name]
- if source then
-  local result={}
-  for k,v in next,t[name] do
-   result[k]=v
+  local source=t[name]
+  if source then
+    local result={}
+    for k,v in next,t[name] do
+      result[k]=v
+    end
+    return result
+  else
+    return {}
   end
-  return result
- else
-  return {}
- end
 end
 local function fetch(t,name)
- return t[name] or {}
+  return t[name] or {}
 end
 local function process(result,more)
- for k,v in next,more do
-  result[k]=v
- end
- return result
+  for k,v in next,more do
+    result[k]=v
+  end
+  return result
 end
 local name=C((1-S(", "))^1)
 local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
 local merge=Cf(parser,process)
 function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+  return lpegmatch(merge,list,1,hash)
 end
 function utilities.parsers.runtime(time)
- if not time then
-  time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+  if not time then
+    time=os.runtime()
+  end
+  local days=div(time,24*60*60)
+  time=mod(time,24*60*60)
+  local hours=div(time,60*60)
+  time=mod(time,60*60)
+  local minutes=div(time,60)
+  local seconds=mod(time,60)
+  return days,hours,minutes,seconds
 end
 local spacing=whitespace^0
 local apply=P("->")
@@ -9415,11 +8850,11 @@
 local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
 local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
 function utilities.parsers.splitmethod(str,default)
- if str then
-  return lpegmatch(pattern,str,1,default or false)
- else
-  return default or false,""
- end
+  if str then
+    return lpegmatch(pattern,str,1,default or false)
+  else
+    return default or false,""
+  end
 end
 
 
@@ -9429,14 +8864,14 @@
 
 package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
 
--- original size: 2541, stripped down to: 1624
+-- original size: 2274, stripped down to: 1781
 
 if not modules then modules={} end modules ['util-fmt']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 utilities=utilities or {}
 utilities.formatters=utilities.formatters or {}
@@ -9447,1272 +8882,61 @@
 local lpegmatch=lpeg.match
 local stripper=lpeg.patterns.stripzeros
 function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+  return lpegmatch(stripper,str)
 end
 function formatters.formatcolumns(result,between)
- if result and #result>0 then
-  between=between or "   "
-  local widths,numbers={},{}
-  local first=result[1]
-  local n=#first
-  for i=1,n do
-   widths[i]=0
-  end
-  for i=1,#result do
-   local r=result[i]
-   for j=1,n do
-    local rj=r[j]
-    local tj=type(rj)
-    if tj=="number" then
-     numbers[j]=true
-     rj=tostring(rj)
-    elseif tj~="string" then
-     rj=tostring(rj)
-     r[j]=rj
+  if result and #result>0 then
+    between=between or "   "
+    local widths,numbers={},{}
+    local first=result[1]
+    local n=#first
+    for i=1,n do
+      widths[i]=0
     end
-    local w=#rj
-    if w>widths[j] then
-     widths[j]=w
-    end
-   end
-  end
-  for i=1,n do
-   local w=widths[i]
-   if numbers[i] then
-    if w>80 then
-     widths[i]="%s"..between
-     else
-     widths[i]="%0"..w.."i"..between
-    end
-   else
-    if w>80 then
-     widths[i]="%s"..between
-     elseif w>0 then
-     widths[i]="%-"..w.."s"..between
-    else
-     widths[i]="%s"
-    end
-   end
-  end
-  local template=strip(concat(widths))
-  for i=1,#result do
-   local str=format(template,unpack(result[i]))
-   result[i]=strip(str)
-  end
- end
- return result
-end
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true
-
--- original size: 374, stripped down to: 282
-
-local loaded=package.loaded
-loaded["socket"]=nil
-loaded["copas"]=nil
-loaded["ltn12"]=nil
-loaded["mbox"]=nil
-loaded["mime"]=nil
-loaded["socket.url"]=nil
-loaded["socket.headers"]=nil
-loaded["socket.tp"]=nil
-loaded["socket.http"]=nil
-loaded["socket.ftp"]=nil
-loaded["socket.smtp"]=nil
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
-
--- original size: 4870, stripped down to: 3527
-
-
-local type,tostring,setmetatable=type,tostring,setmetatable
-local min=math.min
-local format=string.format
-local socket=require("socket.core")
-local connect=socket.connect
-local tcp4=socket.tcp4
-local tcp6=socket.tcp6
-local getaddrinfo=socket.dns.getaddrinfo
-local defaulthost="0.0.0.0"
-local function report(fmt,first,...)
- if logs then
-  report=logs and logs.reporter("socket")
-  report(fmt,first,...)
- elseif fmt then
-  fmt="socket: "..fmt
-  if first then
-   print(format(fmt,first,...))
-  else
-   print(fmt)
-  end
- end
-end
-socket.report=report
-function socket.connect4(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet")
-end
-function socket.connect6(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet6")
-end
-function socket.bind(host,port,backlog)
- if host=="*" or host=="" then
-  host=defaulthost
- end
- local addrinfo,err=getaddrinfo(host)
- if not addrinfo then
-  return nil,err
- end
- for i=1,#addrinfo do
-  local alt=addrinfo[i]
-  local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
-  if not sock then
-   return nil,err or "unknown error"
-  end
-  sock:setoption("reuseaddr",true)
-  local res,err=sock:bind(alt.addr,port)
-  if res then
-   res,err=sock:listen(backlog)
-   if res then
-    return sock
-   else
-    sock:close()
-   end
-  else
-   sock:close()
-  end
- end
- return nil,"invalid address"
-end
-socket.try=socket.newtry()
-function socket.choose(list)
- return function(name,opt1,opt2)
-  if type(name)~="string" then
-   name,opt1,opt2="default",name,opt1
-  end
-  local f=list[name or "nil"]
-  if f then
-   return f(opt1,opt2)
-  else
-   report("error: unknown key '%s'",tostring(name))
-  end
- end
-end
-local sourcet={}
-local sinkt={}
-socket.sourcet=sourcet
-socket.sinkt=sinkt
-socket.BLOCKSIZE=2048
-sinkt["close-when-done"]=function(sock)
- return setmetatable (
-  {
-   getfd=function() return sock:getfd() end,
-   dirty=function() return sock:dirty() end,
-  },
-  {
-   __call=function(self,chunk,err)
-    if chunk then
-     return sock:send(chunk)
-    else
-     sock:close()
-     return 1 
-    end
-   end
-  }
- )
-end
-sinkt["keep-open"]=function(sock)
- return setmetatable (
-  {
-   getfd=function() return sock:getfd() end,
-   dirty=function() return sock:dirty() end,
-  },{
-   __call=function(self,chunk,err)
-    if chunk then
-     return sock:send(chunk)
-    else
-     return 1 
-    end
-   end
-  }
- )
-end
-sinkt["default"]=sinkt["keep-open"]
-socket.sink=socket.choose(sinkt)
-sourcet["by-length"]=function(sock,length)
- local blocksize=socket.BLOCKSIZE
- return setmetatable (
-  {
-   getfd=function() return sock:getfd() end,
-   dirty=function() return sock:dirty() end,
-  },
-  {
-   __call=function()
-    if length<=0 then
-     return nil
-    end
-    local chunk,err=sock:receive(min(blocksize,length))
-    if err then
-     return nil,err
-    end
-    length=length-#chunk
-    return chunk
-   end
-  }
- )
-end
-sourcet["until-closed"]=function(sock)
- local blocksize=socket.BLOCKSIZE
- local done=false
- return setmetatable (
-  {
-   getfd=function() return sock:getfd() end,
-   dirty=function() return sock:dirty() end,
-  },{
-   __call=function()
-    if done then
-     return nil
-    end
-    local chunk,status,partial=sock:receive(blocksize)
-    if not status then
-     return chunk
-    elseif status=="closed" then
-     sock:close()
-     done=true
-     return partial
-    else
-     return nil,status
-    end
-   end
-  }
- )
-end
-sourcet["default"]=sourcet["until-closed"]
-socket.source=socket.choose(sourcet)
-_G.socket=socket 
-package.loaded["socket"]=socket
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
-
--- original size: 25844, stripped down to: 14821
-
-
-local socket=socket or require("socket")
-local ssl=ssl or nil 
-local WATCH_DOG_TIMEOUT=120
-local UDP_DATAGRAM_MAX=8192
-local type,next,pcall,getmetatable,tostring=type,next,pcall,getmetatable,tostring
-local min,max,random=math.min,math.max,math.random
-local find=string.find
-local insert,remove=table.insert,table.remove
-local gettime=socket.gettime
-local selectsocket=socket.select
-local createcoroutine=coroutine.create
-local resumecoroutine=coroutine.resume
-local yieldcoroutine=coroutine.yield
-local runningcoroutine=coroutine.running
-local function report(fmt,first,...)
- if logs then
-  report=logs and logs.reporter("copas")
-  report(fmt,first,...)
- elseif fmt then
-  fmt="copas: "..fmt
-  if first then
-   print(format(fmt,first,...))
-  else
-   print(fmt)
-  end
- end
-end
-local copas={
- _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
- _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
- _VERSION="Copas 2.0.1",
- autoclose=true,
- running=false,
- report=report,
-}
-local function statushandler(status,...)
- if status then
-  return...
- end
- local err=(...)
- if type(err)=="table" then
-  err=err[1]
- end
- report("error: %s",tostring(err))
- return nil,err
-end
-function socket.protect(func)
- return function(...)
-  return statushandler(pcall(func,...))
- end
-end
-function socket.newtry(finalizer)
- return function (...)
-  local status=(...)
-  if not status then
-   local detail=select(2,...)
-   pcall(finalizer,detail)
-   report("error: %s",tostring(detail))
-   return
-  end
-  return...
- end
-end
-local function newset()
- local reverse={}
- local set={}
- local queue={}
- setmetatable(set,{
-  __index={
-   insert=function(set,value)
-     if not reverse[value] then
-      local n=#set+1
-      set[n]=value
-      reverse[value]=n
-     end
-    end,
-   remove=function(set,value)
-     local index=reverse[value]
-     if index then
-      reverse[value]=nil
-      local n=#set
-      local top=set[n]
-      set[n]=nil
-      if top~=value then
-       reverse[top]=index
-       set[index]=top
+    for i=1,#result do
+      local r=result[i]
+      for j=1,n do
+        local rj=r[j]
+        local tj=type(rj)
+        if tj=="number" then
+          numbers[j]=true
+        end
+        if tj~="string" then
+          rj=tostring(rj)
+          r[j]=rj
+        end
+        local w=#rj
+        if w>widths[j] then
+          widths[j]=w
+        end
       end
-     end
-    end,
-   push=function (set,key,itm)
-     local entry=queue[key]
-     if entry==nil then 
-      queue[key]={ itm }
-     else
-      entry[#entry+1]=itm
-     end
-    end,
-   pop=function (set,key)
-     local top=queue[key]
-     if top~=nil then
-      local ret=remove(top,1)
-      if top[1]==nil then
-       queue[key]=nil
-      end
-      return ret
-     end
     end
-  }
- } )
- return set
-end
-local _sleeping={
- times={},
- cos={},
- lethargy={},
- insert=function()
-  end,
- remove=function()
-  end,
- push=function(self,sleeptime,co)
-   if not co then
-    return
-   end
-   if sleeptime<0 then
-    self.lethargy[co]=true
-    return
-   else
-    sleeptime=gettime()+sleeptime
-   end
-   local t=self.times
-   local c=self.cos
-   local i=1
-   local n=#t
-   while i<=n and t[i]<=sleeptime do
-    i=i+1
-   end
-   insert(t,i,sleeptime)
-   insert(c,i,co)
-  end,
- getnext=
-  function(self)
-   local t=self.times
-   local delay=t[1] and t[1]-gettime() or nil
-   return delay and max(delay,0) or nil
-  end,
- pop=
-  function(self,time)
-   local t=self.times
-   local c=self.cos
-   if #t==0 or time<t[1] then
-    return
-   end
-   local co=c[1]
-   remove(t,1)
-   remove(c,1)
-   return co
-  end,
-  wakeup=function(self,co)
-    local let=self.lethargy
-    if let[co] then
-     self:push(0,co)
-     let[co]=nil
-    else
-     local c=self.cos
-     local t=self.times
-     for i=1,#c do
-      if c[i]==co then
-       remove(c,i)
-       remove(t,i)
-       self:push(0,co)
-       return
+    for i=1,n do
+      local w=widths[i]
+      if numbers[i] then
+        if w>80 then
+          widths[i]="%s"..between
+         else
+          widths[i]="%0"..w.."i"..between
+        end
+      else
+        if w>80 then
+          widths[i]="%s"..between
+         elseif w>0 then
+          widths[i]="%-"..w.."s"..between
+        else
+          widths[i]="%s"
+        end
       end
-     end
     end
-   end
-}
-local _servers=newset() 
-local _reading=newset() 
-local _writing=newset() 
-local _reading_log={}
-local _writing_log={}
-local _is_timeout={  
- timeout=true,
- wantread=true,
- wantwrite=true,
-}
-local function isTCP(socket)
- return not find(tostring(socket),"^udp")
-end
-local function copasreceive(client,pattern,part)
- if not pattern or pattern=="" then
-  pattern="*l"
- end
- local current_log=_reading_log
- local s,err
- repeat
-  s,err,part=client:receive(pattern,part)
-  if s or (not _is_timeout[err]) then
-   current_log[client]=nil
-   return s,err,part
-  end
-  if err=="wantwrite" then
-   current_log=_writing_log
-   current_log[client]=gettime()
-   yieldcoroutine(client,_writing)
-  else
-   current_log=_reading_log
-   current_log[client]=gettime()
-   yieldcoroutine(client,_reading)
-  end
- until false
-end
-local function copasreceivefrom(client,size)
- local s,err,port
- if not size or size==0 then
-  size=UDP_DATAGRAM_MAX
- end
- repeat
-  s,err,port=client:receivefrom(size)
-  if s or err~="timeout" then
-   _reading_log[client]=nil
-   return s,err,port
-  end
-  _reading_log[client]=gettime()
-  yieldcoroutine(client,_reading)
- until false
-end
-local function copasreceivepartial(client,pattern,part)
- if not pattern or pattern=="" then
-  pattern="*l"
- end
- local logger=_reading_log
- local queue=_reading
- local s,err
- repeat
-  s,err,part=client:receive(pattern,part)
-  if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
-    logger[client]=nil
-    return s,err,part
-  end
-  if err=="wantwrite" then
-   logger=_writing_log
-   queue=_writing
-  else
-   logger=_reading_log
-   queue=_reading
-  end
-  logger[client]=gettime()
-  yieldcoroutine(client,queue)
- until false
-end
-local function copassend(client,data,from,to)
- if not from then
-  from=1
- end
- local lastIndex=from-1
- local logger=_writing_log
- local queue=_writing
- local s,err
- repeat
-  s,err,lastIndex=client:send(data,lastIndex+1,to)
-  if random(100)>90 then
-   logger[client]=gettime()
-   yieldcoroutine(client,queue)
-  end
-  if s or not _is_timeout[err] then
-   logger[client]=nil
-   return s,err,lastIndex
-  end
-  if err=="wantread" then
-   logger=_reading_log
-   queue=_reading
-  else
-   logger=_writing_log
-   queue=_writing
-  end
-  logger[client]=gettime()
-  yieldcoroutine(client,queue)
- until false
-end
-local function copassendto(client,data,ip,port)
- repeat
-  local s,err=client:sendto(data,ip,port)
-  if random(100)>90 then
-   _writing_log[client]=gettime()
-   yieldcoroutine(client,_writing)
-  end
-  if s or err~="timeout" then
-   _writing_log[client]=nil
-   return s,err
-  end
-  _writing_log[client]=gettime()
-  yieldcoroutine(client,_writing)
- until false
-end
-local function copasconnect(skt,host,port)
- skt:settimeout(0)
- local ret,err,tried_more_than_once
- repeat
-  ret,err=skt:connect (host,port)
-  if ret or (err~="timeout" and err~="Operation already in progress") then
-   if not ret and err=="already connected" and tried_more_than_once then
-    ret=1
-    err=nil
-   end
-   _writing_log[skt]=nil
-   return ret,err
-  end
-  tried_more_than_once=tried_more_than_once or true
-  _writing_log[skt]=gettime()
-  yieldcoroutine(skt,_writing)
- until false
-end
-local function copasdohandshake(skt,sslt) 
- if not ssl then
-  ssl=require("ssl")
- end
- if not ssl then
-  report("error: no ssl library")
-  return
- end
- local nskt,err=ssl.wrap(skt,sslt)
- if not nskt then
-  report("error: %s",tostring(err))
-  return
- end
- nskt:settimeout(0)
- local queue
- repeat
-  local success,err=nskt:dohandshake()
-  if success then
-   return nskt
-  elseif err=="wantwrite" then
-   queue=_writing
-  elseif err=="wantread" then
-   queue=_reading
-  else
-   report("error: %s",tostring(err))
-   return
-  end
-  yieldcoroutine(nskt,queue)
- until false
-end
-local function copasflush(client)
-end
-copas.connect=copassconnect
-copas.send=copassend
-copas.sendto=copassendto
-copas.receive=copasreceive
-copas.receivefrom=copasreceivefrom
-copas.copasreceivepartial=copasreceivepartial
-copas.copasreceivePartial=copasreceivepartial
-copas.dohandshake=copasdohandshake
-copas.flush=copasflush
-local function _skt_mt_tostring(self)
- return tostring(self.socket).." (copas wrapped)"
-end
-local _skt_mt_tcp_index={
- send=function(self,data,from,to)
-   return copassend (self.socket,data,from,to)
-  end,
- receive=function (self,pattern,prefix)
-   if self.timeout==0 then
-    return copasreceivePartial(self.socket,pattern,prefix)
-   else
-    return copasreceive(self.socket,pattern,prefix)
-   end
-  end,
- flush=function (self)
-   return copasflush(self.socket)
-  end,
- settimeout=function (self,time)
-   self.timeout=time
-   return true
-  end,
- connect=function(self,...)
-   local res,err=copasconnect(self.socket,...)
-   if res and self.ssl_params then
-    res,err=self:dohandshake()
-   end
-   return res,err
-  end,
- close=function(self,...)
-   return self.socket:close(...)
-  end,
- bind=function(self,...)
-   return self.socket:bind(...)
-  end,
- getsockname=function(self,...)
-   return self.socket:getsockname(...)
-  end,
- getstats=function(self,...)
-   return self.socket:getstats(...)
-  end,
- setstats=function(self,...)
-   return self.socket:setstats(...)
-  end,
- listen=function(self,...)
-   return self.socket:listen(...)
-  end,
- accept=function(self,...)
-   return self.socket:accept(...)
-  end,
- setoption=function(self,...)
-   return self.socket:setoption(...)
-  end,
- getpeername=function(self,...)
-   return self.socket:getpeername(...)
-  end,
- shutdown=function(self,...)
-   return self.socket:shutdown(...)
-  end,
- dohandshake=function(self,sslt)
-   self.ssl_params=sslt or self.ssl_params
-   local nskt,err=copasdohandshake(self.socket,self.ssl_params)
-   if not nskt then
-    return nskt,err
-   end
-   self.socket=nskt
-   return self
-  end,
-}
-local _skt_mt_tcp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_tcp_index,
-}
-local _skt_mt_udp_index={
- sendto=function (self,...)
-   return copassendto(self.socket,...)
-  end,
- receive=function (self,size)
-   return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
-  end,
- receivefrom=function (self,size)
-   return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
-  end,
- setpeername=function(self,...)
-   return self.socket:getpeername(...)
-  end,
- setsockname=function(self,...)
-   return self.socket:setsockname(...)
-  end,
- close=function(self,...)
-   return true
-  end
-}
-local _skt_mt_udp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_udp_index,
-}
-for k,v in next,_skt_mt_tcp_index do
- if not _skt_mt_udp_index[k] then
-  _skt_mt_udp_index[k]=v
- end
-end
-local function wrap(skt,sslt)
- if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
-  return skt 
- end
- skt:settimeout(0)
- if isTCP(skt) then
-  return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
- else
-  return setmetatable ({ socket=skt },_skt_mt_udp)
- end
-end
-copas.wrap=wrap
-function copas.handler(handler,sslparams)
- return function (skt,...)
-  skt=wrap(skt)
-  if sslparams then
-   skt:dohandshake(sslparams)
-  end
-  return handler(skt,...)
- end
-end
-local _errhandlers={}
-function copas.setErrorHandler(err)
- local co=runningcoroutine()
- if co then
-  _errhandlers[co]=err
- end
-end
-local function _deferror (msg,co,skt)
- report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
-end
-local function _doTick (co,skt,...)
- if not co then
-  return
- end
- local ok,res,new_q=resumecoroutine(co,skt,...)
- if ok and res and new_q then
-  new_q:insert(res)
-  new_q:push(res,co)
- else
-  if not ok then
-   pcall(_errhandlers[co] or _deferror,res,co,skt)
-  end
-  if skt and copas.autoclose and isTCP(skt) then
-   skt:close()
-  end
-  _errhandlers[co]=nil
- end
-end
-local function _accept(input,handler)
- local client=input:accept()
- if client then
-  client:settimeout(0)
-  local co=createcoroutine(handler)
-  _doTick (co,client)
- end
- return client
-end
-local function _tickRead(skt)
- _doTick(_reading:pop(skt),skt)
-end
-local function _tickWrite(skt)
- _doTick(_writing:pop(skt),skt)
-end
-local function addTCPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- _servers[server]=handler
- _reading:insert(server)
-end
-local function addUDPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- local co=createcoroutine(handler)
- _reading:insert(server)
- _doTick(co,server)
-end
-function copas.addserver(server,handler,timeout)
- if isTCP(server) then
-  addTCPserver(server,handler,timeout)
- else
-  addUDPserver(server,handler,timeout)
- end
-end
-function copas.removeserver(server,keep_open)
- local s=server
- local mt=getmetatable(server)
- if mt==_skt_mt_tcp or mt==_skt_mt_udp then
-  s=server.socket
- end
- _servers[s]=nil
- _reading:remove(s)
- if keep_open then
-  return true
- end
- return server:close()
-end
-function copas.addthread(handler,...)
- local thread=createcoroutine(function(_,...) return handler(...) end)
- _doTick(thread,nil,...)
- return thread
-end
-local _tasks={}
-local function addtaskRead(task)
- task.def_tick=_tickRead
- _tasks[task]=true
-end
-local function addtaskWrite(task)
- task.def_tick=_tickWrite
- _tasks[task]=true
-end
-local function tasks()
- return next,_tasks
-end
-local _readable_t={
- events=function(self)
-   local i=0
-   return function ()
-    i=i+1
-    return self._evs[i]
-   end
-  end,
- tick=function(self,input)
-   local handler=_servers[input]
-   if handler then
-    input=_accept(input,handler)
-   else
-    _reading:remove(input)
-    self.def_tick(input)
-   end
-  end
-}
-addtaskRead(_readable_t)
-local _writable_t={
- events=function(self)
-   local i=0
-   return function()
-    i=i+1
-    return self._evs[i]
-   end
-  end,
- tick=function(self,output)
-   _writing:remove(output)
-   self.def_tick(output)
-  end
-}
-addtaskWrite(_writable_t)
-local _sleeping_t={
- tick=function(self,time,...)
-  _doTick(_sleeping:pop(time),...)
- end
-}
-function copas.sleep(sleeptime)
- yieldcoroutine((sleeptime or 0),_sleeping)
-end
-function copas.wakeup(co)
- _sleeping:wakeup(co)
-end
-local last_cleansing=0
-local function _select(timeout)
- local now=gettime()
- local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
- _readable_t._evs=r_evs
- _writable_t._evs=w_evs
- if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
-  last_cleansing=now
-  for skt,time in next,_reading_log do
-   if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
-    local n=#r_evs+1
-    _reading_log[skt]=nil
-    r_evs[n]=skt
-    r_evs[skt]=n
-   end
-  end
-  for skt,time in next,_writing_log do
-   if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
-    local n=#w_evs+1
-    _writing_log[skt]=nil
-    w_evs[n]=skt
-    w_evs[skt]=n
-   end
-  end
- end
- if err=="timeout" and #r_evs+#w_evs>0 then
-  return nil
- else
-  return err
- end
-end
-local function copasfinished()
- return not (next(_reading) or next(_writing) or _sleeping:getnext())
-end
-local function copasstep(timeout)
- _sleeping_t:tick(gettime())
- local nextwait=_sleeping:getnext()
- if nextwait then
-  timeout=timeout and min(nextwait,timeout) or nextwait
- elseif copasfinished() then
-  return false
- end
- local err=_select(timeout)
- if err then
-  if err=="timeout" then
-   return false
-  end
-  return nil,err
- end
- for task in tasks() do
-  for event in task:events() do
-   task:tick(event)
-  end
- end
- return true
-end
-copas.finished=copasfinished
-copas.step=copasstep
-function copas.loop(timeout)
- copas.running=true
- while not copasfinished() do
-  copasstep(timeout)
- end
- copas.running=false
-end
-package.loaded["copas"]=copas
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
-
--- original size: 8709, stripped down to: 5411
-
-
-local select,unpack=select,unpack
-local insert,remove=table.insert,table.remove
-local sub=string.sub
-local function report(fmt,first,...)
- if logs then
-  report=logs and logs.reporter("ltn12")
-  report(fmt,first,...)
- elseif fmt then
-  fmt="ltn12: "..fmt
-  if first then
-   print(format(fmt,first,...))
-  else
-   print(fmt)
-  end
- end
-end
-local filter={}
-local source={}
-local sink={}
-local pump={}
-local ltn12={
- _VERSION="LTN12 1.0.3",
- BLOCKSIZE=2048,
- filter=filter,
- source=source,
- sink=sink,
- pump=pump,
- report=report,
-}
-function filter.cycle(low,ctx,extra)
- if low then
-  return function(chunk)
-   return (low(ctx,chunk,extra))
-  end
- end
-end
-function filter.chain(...)
- local arg={... }
- local n=select('#',...)
- local top=1
- local index=1
- local retry=""
- return function(chunk)
-  retry=chunk and retry
-  while true do
-   local action=arg[index]
-   if index==top then
-    chunk=action(chunk)
-    if chunk=="" or top==n then
-     return chunk
-    elseif chunk then
-     index=index+1
-    else
-     top=top+1
-     index=top
+    local template=strip(concat(widths))
+    for i=1,#result do
+      local str=format(template,unpack(result[i]))
+      result[i]=strip(str)
     end
-   else
-    chunk=action(chunk or "")
-    if chunk=="" then
-     index=index-1
-     chunk=retry
-    elseif chunk then
-     if index==n then
-      return chunk
-     else
-      index=index+1
-     end
-    else
-     report("error: filter returned inappropriate 'nil'")
-     return
-    end
-   end
   end
- end
+  return result
 end
-local function empty()
- return nil
-end
-function source.empty()
- return empty
-end
-local function sourceerror(err)
- return function()
-  return nil,err
- end
-end
-source.error=sourceerror
-function source.file(handle,io_err)
- if handle then
-  local blocksize=ltn12.BLOCKSIZE
-  return function()
-   local chunk=handle:read(blocksize)
-   if not chunk then
-    handle:close()
-   end
-   return chunk
-  end
- else
-  return sourceerror(io_err or "unable to open file")
- end
-end
-function source.simplify(src)
- return function()
-  local chunk,err_or_new=src()
-  if err_or_new then
-   src=err_or_new
-  end
-  if chunk then
-   return chunk
-  else
-   return nil,err_or_new
-  end
- end
-end
-function source.string(s)
- if s then
-  local blocksize=ltn12.BLOCKSIZE
-  local i=1
-  return function()
-   local nexti=i+blocksize
-   local chunk=sub(s,i,nexti-1)
-   i=nexti
-   if chunk~="" then
-    return chunk
-   else
-    return nil
-   end
-  end
- else return source.empty() end
-end
-function source.rewind(src)
- local t={}
- return function(chunk)
-  if chunk then
-   insert(t,chunk)
-  else
-   chunk=remove(t)
-   if chunk then
-    return chunk
-   else
-    return src()
-   end
-  end
- end
-end
-function source.chain(src,f,...)
- if... then
-  f=filter.chain(f,...)
- end
- local last_in=""
- local last_out=""
- local state="feeding"
- local err
- return function()
-  if not last_out then
-   report("error: source is empty")
-   return
-  end
-  while true do
-   if state=="feeding" then
-    last_in,err=src()
-    if err then
-     return nil,err
-    end
-    last_out=f(last_in)
-    if not last_out then
-     if last_in then
-      report("error: filter returned inappropriate 'nil'")
-     end
-     return nil
-    elseif last_out~="" then
-     state="eating"
-     if last_in then
-      last_in=""
-     end
-     return last_out
-    end
-   else
-    last_out=f(last_in)
-    if last_out=="" then
-     if last_in=="" then
-      state="feeding"
-     else
-      report("error: filter returned nothing")
-      return
-     end
-    elseif not last_out then
-     if last_in then
-      report("filter returned inappropriate 'nil'")
-     end
-     return nil
-    else
-     return last_out
-    end
-   end
-  end
- end
-end
-function source.cat(...)
- local arg={... }
- local src=remove(arg,1)
- return function()
-  while src do
-   local chunk,err=src()
-   if chunk then
-    return chunk
-   end
-   if err then
-    return nil,err
-   end
-   src=remove(arg,1)
-  end
- end
-end
-function sink.table(t)
- if not t then
-  t={}
- end
- local f=function(chunk,err)
-  if chunk then
-   insert(t,chunk)
-  end
-  return 1
- end
- return f,t
-end
-function sink.simplify(snk)
- return function(chunk,err)
-  local ret,err_or_new=snk(chunk,err)
-  if not ret then
-   return nil,err_or_new
-  end
-  if err_or_new then
-   snk=err_or_new
-  end
-  return 1
- end
-end
-local function null()
- return 1
-end
-function sink.null()
- return null
-end
-local function sinkerror(err)
- return function()
-  return nil,err
- end
-end
-sink.error=sinkerror
-function sink.file(handle,io_err)
- if handle then
-  return function(chunk,err)
-   if not chunk then
-    handle:close()
-    return 1
-   else
-    return handle:write(chunk)
-   end
-  end
- else
-  return sinkerror(io_err or "unable to open file")
- end
-end
-function sink.chain(f,snk,...)
- if... then
-  local args={ f,snk,... }
-  snk=remove(args,#args)
-  f=filter.chain(unpack(args))
- end
- return function(chunk,err)
-  if chunk~="" then
-   local filtered=f(chunk)
-   local done=chunk and ""
-   while true do
-    local ret,snkerr=snk(filtered,err)
-    if not ret then
-     return nil,snkerr
-    end
-    if filtered==done then
-     return 1
-    end
-    filtered=f(done)
-   end
-  else
-   return 1
-  end
- end
-end
-function pump.step(src,snk)
- local chunk,src_err=src()
- local ret,snk_err=snk(chunk,src_err)
- if chunk and ret then
-  return 1
- else
-  return nil,src_err or snk_err
- end
-end
-function pump.all(src,snk,step)
- if not step then
-  step=pump.step
- end
- while true do
-  local ret,err=step(src,snk)
-  if not ret then
-   if err then
-    return nil,err
-   else
-    return 1
-   end
-  end
- end
-end
-package.loaded["ltn12"]=ltn12
 
 
 end -- of closure
@@ -10719,1631 +8943,16 @@
 
 do -- create closure to overcome 200 locals limit
 
-package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
-
--- original size: 2328, stripped down to: 1874
-
-
-local type,tostring=type,tostring
-local mime=require("mime.core")
-local ltn12=ltn12 or require("ltn12")
-local filtercycle=ltn12.filter.cycle
-local function report(fmt,first,...)
- if logs then
-  report=logs and logs.reporter("mime")
-  report(fmt,first,...)
- elseif fmt then
-  fmt="mime: "..fmt
-  if first then
-   print(format(fmt,first,...))
-  else
-   print(fmt)
-  end
- end
-end
-mime.report=report
-local encodet={}
-local decodet={}
-local wrapt={}
-mime.encodet=encodet
-mime.decodet=decodet
-mime.wrapt=wrapt
-local mime_b64=mime.b64
-local mime_qp=mime.qp
-local mime_unb64=mime.unb64
-local mime_unqp=mime.unqp
-local mime_wrp=mime.wrp
-local mime_qpwrp=mime.qpwrp
-local mime_eol=mime_eol
-local mime_dot=mime_dot
-encodet['base64']=function()
- return filtercycle(mime_b64,"")
-end
-encodet['quoted-printable']=function(mode)
- return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
-end
-decodet['base64']=function()
- return filtercycle(mime_unb64,"")
-end
-decodet['quoted-printable']=function()
- return filtercycle(mime_unqp,"")
-end
-local wraptext=function(length)
- if not length then
-  length=76
- end
- return filtercycle(mime_wrp,length,length)
-end
-local wrapquoted=function()
- return filtercycle(mime_qpwrp,76,76)
-end
-wrapt['text']=wraptext
-wrapt['base64']=wraptext
-wrapt['default']=wraptext
-wrapt['quoted-printable']=wrapquoted
-function mime.normalize(marker)
- return filtercycle(mime_eol,0,marker)
-end
-function mime.stuff()
- return filtercycle(mime_dot,2)
-end
-local function choose(list)
- return function(name,opt1,opt2)
-  if type(name)~="string" then
-   name,opt1,opt2="default",name,opt1
-  end
-  local filter=list[name or "nil"]
-  if filter then
-   return filter(opt1,opt2)
-  else
-   report("error: unknown key '%s'",tostring(name))
-  end
- end
-end
-mime.encode=choose(encodet)
-mime.decode=choose(decodet)
-mime.wrap=choose(wrapt)
-package.loaded["mime"]=mime
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
-
--- original size: 6863, stripped down to: 5269
-
-
-local tonumber,tostring,type=tonumber,tostring,type
-local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,string.find,string.format,string.byte,string.char
-local insert=table.insert
-local socket=socket or require("socket")
-local url={
- _VERSION="URL 1.0.3",
-}
-socket.url=url
-function url.escape(s)
- return (gsub(s,"([^A-Za-z0-9_])",function(c)
-  return format("%%%02x",byte(c))
- end))
-end
-local function make_set(t) 
- local s={}
- for i=1,#t do
-  s[t[i]]=true
- end
- return s
-end
-local segment_set=make_set {
- "-","_",".","!","~","*","'","(",
- ")",":","@","&","=","+","$",",",
-}
-local function protect_segment(s)
- return gsub(s,"([^A-Za-z0-9_])",function(c)
-  if segment_set[c] then
-   return c
-  else
-   return format("%%%02X",byte(c))
-  end
- end)
-end
-function url.unescape(s)
- return (gsub(s,"%%(%x%x)",function(hex)
-  return char(tonumber(hex,16))
- end))
-end
-local function absolute_path(base_path,relative_path)
- if find(relative_path,"^/") then
-  return relative_path
- end
- local path=gsub(base_path,"[^/]*$","")
- path=path..relative_path
- path=gsub(path,"([^/]*%./)",function (s)
-  if s~="./" then
-   return s
-  else
-   return ""
-  end
- end)
- path=gsub(path,"/%.$","/")
- local reduced
- while reduced~=path do
-  reduced=path
-  path=gsub(reduced,"([^/]*/%.%./)",function (s)
-   if s~="../../" then
-    return ""
-   else
-    return s
-   end
-  end)
- end
- path=gsub(reduced,"([^/]*/%.%.)$",function (s)
-  if s~="../.." then
-   return ""
-  else
-   return s
-  end
- end)
- return path
-end
-function url.parse(url,default)
- local parsed={}
- for k,v in next,default or parsed do
-  parsed[k]=v
- end
- if not url or url=="" then
-  return nil,"invalid url"
- end
- url=gsub(url,"#(.*)$",function(f)
-  parsed.fragment=f
-  return ""
- end)
- url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
-  parsed.scheme=s
-  return ""
- end)
- url=gsub(url,"^//([^/]*)",function(n)
-  parsed.authority=n
-  return ""
- end)
- url=gsub(url,"%?(.*)",function(q)
-  parsed.query=q
-  return ""
- end)
- url=gsub(url,"%;(.*)",function(p)
-  parsed.params=p
-  return ""
- end)
- if url~="" then
-  parsed.path=url
- end
- local authority=parsed.authority
- if not authority then
-  return parsed
- end
- authority=gsub(authority,"^([^@]*)@",function(u)
-  parsed.userinfo=u
-  return ""
- end)
- authority=gsub(authority,":([^:%]]*)$",function(p)
-  parsed.port=p
-  return ""
- end)
- if authority~="" then
-  parsed.host=match(authority,"^%[(.+)%]$") or authority
- end
- local userinfo=parsed.userinfo
- if not userinfo then
-  return parsed
- end
- userinfo=gsub(userinfo,":([^:]*)$",function(p)
-  parsed.password=p
-  return ""
- end)
- parsed.user=userinfo
- return parsed
-end
-function url.build(parsed)
- local url=parsed.path or ""
- if parsed.params then
-  url=url..";"..parsed.params
- end
- if parsed.query then
-  url=url.."?"..parsed.query
- end
- local authority=parsed.authority
- if parsed.host then
-  authority=parsed.host
-  if find(authority,":") then 
-   authority="["..authority.."]"
-  end
-  if parsed.port then
-   authority=authority..":"..tostring(parsed.port)
-  end
-  local userinfo=parsed.userinfo
-  if parsed.user then
-   userinfo=parsed.user
-   if parsed.password then
-    userinfo=userinfo..":"..parsed.password
-   end
-  end
-  if userinfo then authority=userinfo.."@"..authority end
- end
- if authority then
-  url="//"..authority..url
- end
- if parsed.scheme then
-  url=parsed.scheme..":"..url
- end
- if parsed.fragment then
-  url=url.."#"..parsed.fragment
- end
- return url
-end
-function url.absolute(base_url,relative_url)
- local base_parsed
- if type(base_url)=="table" then
-  base_parsed=base_url
-  base_url=url.build(base_parsed)
- else
-  base_parsed=url.parse(base_url)
- end
- local relative_parsed=url.parse(relative_url)
- if not base_parsed then
-  return relative_url
- elseif not relative_parsed then
-  return base_url
- elseif relative_parsed.scheme then
-  return relative_url
- else
-  relative_parsed.scheme=base_parsed.scheme
-  if not relative_parsed.authority then
-   relative_parsed.authority=base_parsed.authority
-   if not relative_parsed.path then
-    relative_parsed.path=base_parsed.path
-    if not relative_parsed.params then
-     relative_parsed.params=base_parsed.params
-     if not relative_parsed.query then
-      relative_parsed.query=base_parsed.query
-     end
-    end
-   else
-    relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
-   end
-  end
-  return url.build(relative_parsed)
- end
-end
-function url.parse_path(path)
- local parsed={}
- path=path or ""
- gsub(path,"([^/]+)",function (s)
-  insert(parsed,s)
- end)
- for i=1,#parsed do
-  parsed[i]=url.unescape(parsed[i])
- end
- if sub(path,1,1)=="/" then
-  parsed.is_absolute=1
- end
- if sub(path,-1,-1)=="/" then
-  parsed.is_directory=1
- end
- return parsed
-end
-function url.build_path(parsed,unsafe)
- local path=""
- local n=#parsed
- if unsafe then
-  for i=1,n-1 do
-   path=path..parsed[i].."/"
-  end
-  if n>0 then
-   path=path..parsed[n]
-   if parsed.is_directory then
-    path=path.."/"
-   end
-  end
- else
-  for i=1,n-1 do
-   path=path..protect_segment(parsed[i]).."/"
-  end
-  if n>0 then
-   path=path..protect_segment(parsed[n])
-   if parsed.is_directory then
-    path=path.."/"
-   end
-  end
- end
- if parsed.is_absolute then
-  path="/"..path
- end
- return path
-end
-package.loaded["socket.url"]=url
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
-
--- original size: 5721, stripped down to: 3754
-
-
-local next=next
-local lower=string.lower
-local concat=table.concat
-local socket=socket or require("socket")
-local headers={}
-socket.headers=headers
-local canonic={
- ["accept"]="Accept",
- ["accept-charset"]="Accept-Charset",
- ["accept-encoding"]="Accept-Encoding",
- ["accept-language"]="Accept-Language",
- ["accept-ranges"]="Accept-Ranges",
- ["action"]="Action",
- ["alternate-recipient"]="Alternate-Recipient",
- ["age"]="Age",
- ["allow"]="Allow",
- ["arrival-date"]="Arrival-Date",
- ["authorization"]="Authorization",
- ["bcc"]="Bcc",
- ["cache-control"]="Cache-Control",
- ["cc"]="Cc",
- ["comments"]="Comments",
- ["connection"]="Connection",
- ["content-description"]="Content-Description",
- ["content-disposition"]="Content-Disposition",
- ["content-encoding"]="Content-Encoding",
- ["content-id"]="Content-ID",
- ["content-language"]="Content-Language",
- ["content-length"]="Content-Length",
- ["content-location"]="Content-Location",
- ["content-md5"]="Content-MD5",
- ["content-range"]="Content-Range",
- ["content-transfer-encoding"]="Content-Transfer-Encoding",
- ["content-type"]="Content-Type",
- ["cookie"]="Cookie",
- ["date"]="Date",
- ["diagnostic-code"]="Diagnostic-Code",
- ["dsn-gateway"]="DSN-Gateway",
- ["etag"]="ETag",
- ["expect"]="Expect",
- ["expires"]="Expires",
- ["final-log-id"]="Final-Log-ID",
- ["final-recipient"]="Final-Recipient",
- ["from"]="From",
- ["host"]="Host",
- ["if-match"]="If-Match",
- ["if-modified-since"]="If-Modified-Since",
- ["if-none-match"]="If-None-Match",
- ["if-range"]="If-Range",
- ["if-unmodified-since"]="If-Unmodified-Since",
- ["in-reply-to"]="In-Reply-To",
- ["keywords"]="Keywords",
- ["last-attempt-date"]="Last-Attempt-Date",
- ["last-modified"]="Last-Modified",
- ["location"]="Location",
- ["max-forwards"]="Max-Forwards",
- ["message-id"]="Message-ID",
- ["mime-version"]="MIME-Version",
- ["original-envelope-id"]="Original-Envelope-ID",
- ["original-recipient"]="Original-Recipient",
- ["pragma"]="Pragma",
- ["proxy-authenticate"]="Proxy-Authenticate",
- ["proxy-authorization"]="Proxy-Authorization",
- ["range"]="Range",
- ["received"]="Received",
- ["received-from-mta"]="Received-From-MTA",
- ["references"]="References",
- ["referer"]="Referer",
- ["remote-mta"]="Remote-MTA",
- ["reply-to"]="Reply-To",
- ["reporting-mta"]="Reporting-MTA",
- ["resent-bcc"]="Resent-Bcc",
- ["resent-cc"]="Resent-Cc",
- ["resent-date"]="Resent-Date",
- ["resent-from"]="Resent-From",
- ["resent-message-id"]="Resent-Message-ID",
- ["resent-reply-to"]="Resent-Reply-To",
- ["resent-sender"]="Resent-Sender",
- ["resent-to"]="Resent-To",
- ["retry-after"]="Retry-After",
- ["return-path"]="Return-Path",
- ["sender"]="Sender",
- ["server"]="Server",
- ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
- ["status"]="Status",
- ["subject"]="Subject",
- ["te"]="TE",
- ["to"]="To",
- ["trailer"]="Trailer",
- ["transfer-encoding"]="Transfer-Encoding",
- ["upgrade"]="Upgrade",
- ["user-agent"]="User-Agent",
- ["vary"]="Vary",
- ["via"]="Via",
- ["warning"]="Warning",
- ["will-retry-until"]="Will-Retry-Until",
- ["www-authenticate"]="WWW-Authenticate",
- ["x-mailer"]="X-Mailer",
-}
-headers.canonic=setmetatable(canonic,{
- __index=function(t,k)
-  socket.report("invalid header: %s",k)
-  t[k]=k
-  return k
- end
-})
-function headers.normalize(headers)
- if not headers then
-  return {}
- end
- local normalized={}
- for k,v in next,headers do
-  normalized[#normalized+1]=canonic[k]..": "..v
- end
- normalized[#normalized+1]=""
- normalized[#normalized+1]=""
- return concat(normalized,"\r\n")
-end
-function headers.lower(lowered,headers)
- if not lowered then
-  return {}
- end
- if not headers then
-  lowered,headers={},lowered
- end
- for k,v in next,headers do
-  lowered[lower(k)]=v
- end
- return lowered
-end
-socket.headers=headers
-package.loaded["socket.headers"]=headers
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
-
--- original size: 3116, stripped down to: 2533
-
-
-local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber
-local find,upper=string.find,string.upper
-local socket=socket or require("socket")
-local ltn12=ltn12  or require("ltn12")
-local skipsocket=socket.skip
-local sinksocket=socket.sink
-local tcpsocket=socket.tcp
-local ltn12pump=ltn12.pump
-local pumpall=ltn12pump.all
-local pumpstep=ltn12pump.step
-local tp={
- TIMEOUT=60,
-}
-socket.tp=tp
-local function get_reply(c)
- local line,err=c:receive()
- local reply=line
- if err then return
-  nil,err
- end
- local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- if not code then
-  return nil,"invalid server reply"
- end
- if sep=="-" then
-  local current
-  repeat
-   line,err=c:receive()
-   if err then
-    return nil,err
-   end
-   current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
-   reply=reply.."\n"..line
-  until code==current and sep==" "
- end
- return code,reply
-end
-local methods={}
-local mt={ __index=methods }
-function methods.getpeername(self)
- return self.c:getpeername()
-end
-function methods.getsockname(self)
- return self.c:getpeername()
-end
-function methods.check(self,ok)
- local code,reply=get_reply(self.c)
- if not code then
-  return nil,reply
- end
- local c=tonumber(code)
- local t=type(ok)
- if t=="function" then
-  return ok(c,reply)
- elseif t=="table" then
-  for i=1,#ok do
-   if find(code,ok[i]) then
-    return c,reply
-   end
-  end
-  return nil,reply
- elseif find(code,ok) then
-  return c,reply
- else
-  return nil,reply
- end
-end
-function methods.command(self,cmd,arg)
- cmd=upper(cmd)
- if arg then
-  cmd=cmd.." "..arg.."\r\n"
- else
-  cmd=cmd.."\r\n"
- end
- return self.c:send(cmd)
-end
-function methods.sink(self,snk,pat)
- local chunk,err=self.c:receive(pat)
- return snk(chunk,err)
-end
-function methods.send(self,data)
- return self.c:send(data)
-end
-function methods.receive(self,pat)
- return self.c:receive(pat)
-end
-function methods.getfd(self)
- return self.c:getfd()
-end
-function methods.dirty(self)
- return self.c:dirty()
-end
-function methods.getcontrol(self)
- return self.c
-end
-function methods.source(self,source,step)
- local sink=sinksocket("keep-open",self.c)
- local ret,err=pumpall(source,sink,step or pumpstep)
- return ret,err
-end
-function methods.close(self)
- self.c:close()
- return 1
-end
-function tp.connect(host,port,timeout,create)
- local c,e=(create or tcpsocket)()
- if not c then
-  return nil,e
- end
- c:settimeout(timeout or tp.TIMEOUT)
- local r,e=c:connect(host,port)
- if not r then
-  c:close()
-  return nil,e
- end
- return setmetatable({ c=c },mt)
-end
-package.loaded["socket.tp"]=tp
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
-
--- original size: 12577, stripped down to: 9577
-
-
-local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type
-local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match
-local concat=table.concat
-local socket=socket   or require("socket")
-local url=socket.url  or require("socket.url")
-local ltn12=ltn12    or require("ltn12")
-local mime=mime     or require("mime")
-local headers=socket.headers or require("socket.headers")
-local normalizeheaders=headers.normalize
-local parseurl=url.parse
-local buildurl=url.build
-local absoluteurl=url.absolute
-local unescapeurl=url.unescape
-local skipsocket=socket.skip
-local sinksocket=socket.sink
-local sourcesocket=socket.source
-local trysocket=socket.try
-local tcpsocket=socket.tcp
-local newtrysocket=socket.newtry
-local protectsocket=socket.protect
-local emptysource=ltn12.source.empty
-local stringsource=ltn12.source.string
-local rewindsource=ltn12.source.rewind
-local pumpstep=ltn12.pump.step
-local pumpall=ltn12.pump.all
-local sinknull=ltn12.sink.null
-local sinktable=ltn12.sink.table
-local lowerheaders=headers.lower
-local mimeb64=mime.b64
-local http={
- TIMEOUT=60,
- USERAGENT=socket._VERSION,
-}
-socket.http=http
-local PORT=80
-local SCHEMES={
- http=true,
-}
-local function receiveheaders(sock,headers)
- if not headers then
-  headers={}
- end
- local line,err=sock:receive()
- if err then
-  return nil,err
- end
- while line~="" do
-  local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
-  if not (name and value) then
-   return nil,"malformed reponse headers"
-  end
-  name=lower(name)
-  line,err=sock:receive()
-  if err then
-   return nil,err
-  end
-  while find(line,"^%s") do
-   value=value..line
-   line=sock:receive()
-   if err then
-    return nil,err
-   end
-  end
-  local found=headers[name]
-  if found then
-   value=found..", "..value
-  end
-  headers[name]=value
- end
- return headers
-end
-socket.sourcet["http-chunked"]=function(sock,headers)
- return setmetatable (
-  {
-   getfd=function() return sock:getfd() end,
-   dirty=function() return sock:dirty() end,
-  },{
-   __call=function()
-    local line,err=sock:receive()
-    if err then
-     return nil,err
-    end
-    local size=tonumber(gsub(line,";.*",""),16)
-    if not size then
-     return nil,"invalid chunk size"
-    end
-    if size>0 then
-     local chunk,err,part=sock:receive(size)
-     if chunk then
-      sock:receive()
-     end
-     return chunk,err
-    else
-     headers,err=receiveheaders(sock,headers)
-     if not headers then
-      return nil,err
-     end
-    end
-   end
-  }
- )
-end
-socket.sinkt["http-chunked"]=function(sock)
- return setmetatable(
-  {
-   getfd=function() return sock:getfd() end,
-   dirty=function() return sock:dirty() end,
-  },
-  {
-   __call=function(self,chunk,err)
-    if not chunk then
-     chunk=""
-    end
-    return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
-   end
- })
-end
-local methods={}
-local mt={ __index=methods }
-local function openhttp(host,port,create)
- local c=trysocket((create or tcpsocket)())
- local h=setmetatable({ c=c },mt)
- local try=newtrysocket(function() h:close() end)
- h.try=try
- try(c:settimeout(http.TIMEOUT))
- try(c:connect(host,port or PORT))
- return h
-end
-http.open=openhttp
-function methods.sendrequestline(self,method,uri)
- local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
- return self.try(self.c:send(requestline))
-end
-function methods.sendheaders(self,headers)
- self.try(self.c:send(normalizeheaders(headers)))
- return 1
-end
-function methods.sendbody(self,headers,source,step)
- if not source then
-  source=emptysource()
- end
- if not step then
-  step=pumpstep
- end
- local mode="http-chunked"
- if headers["content-length"] then
-  mode="keep-open"
- end
- return self.try(pumpall(source,sinksocket(mode,self.c),step))
-end
-function methods.receivestatusline(self)
- local try=self.try
- local status=try(self.c:receive(5))
- if status~="HTTP/" then
-  return nil,status 
- end
- status=try(self.c:receive("*l",status))
- local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
- return try(tonumber(code),status)
-end
-function methods.receiveheaders(self)
- return self.try(receiveheaders(self.c))
-end
-function methods.receivebody(self,headers,sink,step)
- if not sink then
-  sink=sinknull()
- end
- if not step then
-  step=pumpstep
- end
- local length=tonumber(headers["content-length"])
- local encoding=headers["transfer-encoding"] 
- local mode="default" 
- if encoding and encoding~="identity" then
-  mode="http-chunked"
- elseif length then
-  mode="by-length"
- end
- return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
-end
-function methods.receive09body(self,status,sink,step)
- local source=rewindsource(sourcesocket("until-closed",self.c))
- source(status)
- return self.try(pumpall(source,sink,step))
-end
-function methods.close(self)
- return self.c:close()
-end
-local function adjusturi(request)
- if not request.proxy and not http.PROXY then
-  request={
-     path=trysocket(request.path,"invalid path 'nil'"),
-     params=request.params,
-     query=request.query,
-     fragment=request.fragment,
-  }
- end
- return buildurl(request)
-end
-local function adjustheaders(request)
- local headers={
-  ["user-agent"]=http.USERAGENT,
-  ["host"]=gsub(request.authority,"^.-@",""),
-  ["connection"]="close, TE",
-  ["te"]="trailers"
- }
- local username=request.user
- local password=request.password
- if username and password then
-  headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
- end
- local proxy=request.proxy or http.PROXY
- if proxy then
-  proxy=parseurl(proxy)
-  local username=proxy.user
-  local password=proxy.password
-  if username and password then
-   headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
-  end
- end
- local requestheaders=request.headers
- if requestheaders then
-  headers=lowerheaders(headers,requestheaders)
- end
- return headers
-end
-local default={
- host="",
- port=PORT,
- path="/",
- scheme="http"
-}
-local function adjustrequest(originalrequest)
- local url=originalrequest.url
- local request=url and parseurl(url,default) or {}
- for k,v in next,originalrequest do
-  request[k]=v
- end
- local host=request.host
- local port=request.port
- local uri=request.uri
- if not host or host=="" then
-  trysocket(nil,"invalid host '"..tostring(host).."'")
- end
- if port=="" then
-  request.port=PORT
- end
- if not uri or uri=="" then
-  request.uri=adjusturi(request)
- end
- request.headers=adjustheaders(request)
- local proxy=request.proxy or http.PROXY
- if proxy then
-  proxy=parseurl(proxy)
-  request.host=proxy.host
-  request.port=proxy.port or 3128
- end
- return request
-end
-local maxredericts=4
-local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true }
-local validmethods={ [false]=true,GET=true,HEAD=true }
-local function shouldredirect(request,code,headers)
- local location=headers.location
- if not location then
-  return false
- end
- location=gsub(location,"%s","")
- if location=="" then
-  return false
- end
- local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then
-  return false
- end
- local method=request.method
- local redirect=request.redirect
- local redirects=request.nredirects or 0
- return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
-end
-local function shouldreceivebody(request,code)
- if request.method=="HEAD" then
-  return nil
- end
- if code==204 or code==304 then
-  return nil
- end
- if code>=100 and code<200 then
-  return nil
- end
- return 1
-end
-local tredirect,trequest,srequest
-tredirect=function(request,location)
- local result,code,headers,status=trequest {
-  url=absoluteurl(request.url,location),
-  source=request.source,
-  sink=request.sink,
-  headers=request.headers,
-  proxy=request.proxy,
-  nredirects=(request.nredirects or 0)+1,
-  create=request.create,
- }
- if not headers then
-  headers={}
- end
- if not headers.location then
-  headers.location=location
- end
- return result,code,headers,status
-end
-trequest=function(originalrequest)
- local request=adjustrequest(originalrequest)
- local connection=openhttp(request.host,request.port,request.create)
- local headers=request.headers
- connection:sendrequestline(request.method,request.uri)
- connection:sendheaders(headers)
- if request.source then
-  connection:sendbody(headers,request.source,request.step)
- end
- local code,status=connection:receivestatusline()
- if not code then
-  connection:receive09body(status,request.sink,request.step)
-  return 1,200
- end
- while code==100 do
-  headers=connection:receiveheaders()
-  code,status=connection:receivestatusline()
- end
- headers=connection:receiveheaders()
- if shouldredirect(request,code,headers) and not request.source then
-  connection:close()
-  return tredirect(originalrequest,headers.location)
- end
- if shouldreceivebody(request,code) then
-  connection:receivebody(headers,request.sink,request.step)
- end
- connection:close()
- return 1,code,headers,status
-end
-local function genericform(url,body)
- local buffer={}
- local request={
-  url=url,
-  sink=sinktable(buffer),
-  target=buffer,
- }
- if body then
-  request.source=stringsource(body)
-  request.method="POST"
-  request.headers={
-   ["content-length"]=#body,
-   ["content-type"]="application/x-www-form-urlencoded"
-  }
- end
- return request
-end
-http.genericform=genericform
-srequest=function(url,body)
- local request=genericform(url,body)
- local _,code,headers,status=trequest(request)
- return concat(request.target),code,headers,status
-end
-http.request=protectsocket(function(request,body)
- if type(request)=="string" then
-  return srequest(request,body)
- else
-  return trequest(request)
- end
-end)
-package.loaded["socket.http"]=http
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
-
--- original size: 10357, stripped down to: 8548
-
-
-local setmetatable,type,next=setmetatable,type,next
-local find,format,gsub,match=string.find,string.format,string.gsub,string.match
-local concat=table.concat
-local mod=math.mod
-local socket=socket  or require("socket")
-local url=socket.url or require("socket.url")
-local tp=socket.tp  or require("socket.tp")
-local ltn12=ltn12   or require("ltn12")
-local tcpsocket=socket.tcp
-local trysocket=socket.try
-local skipsocket=socket.skip
-local sinksocket=socket.sink
-local selectsocket=socket.select
-local bindsocket=socket.bind
-local newtrysocket=socket.newtry
-local sourcesocket=socket.source
-local protectsocket=socket.protect
-local parseurl=url.parse
-local unescapeurl=url.unescape
-local pumpall=ltn12.pump.all
-local pumpstep=ltn12.pump.step
-local sourcestring=ltn12.source.string
-local sinktable=ltn12.sink.table
-local ftp={
- TIMEOUT=60,
- USER="ftp",
- PASSWORD="anonymous at anonymous.org",
-}
-socket.ftp=ftp
-local PORT=21
-local methods={}
-local mt={ __index=methods }
-function ftp.open(server,port,create)
- local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
- local f=setmetatable({ tp=tp },metat)
- f.try=newtrysocket(function() f:close() end)
- return f
-end
-function methods.portconnect(self)
- local try=self.try
- local server=self.server
- try(server:settimeout(ftp.TIMEOUT))
- self.data=try(server:accept())
- try(self.data:settimeout(ftp.TIMEOUT))
-end
-function methods.pasvconnect(self)
- local try=self.try
- self.data=try(tcpsocket())
- self(self.data:settimeout(ftp.TIMEOUT))
- self(self.data:connect(self.pasvt.address,self.pasvt.port))
-end
-function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("user",user or ftp.USER))
- local code,reply=try(tp:check{"2..",331})
- if code==331 then
-  try(tp:command("pass",password or ftp.PASSWORD))
-  try(tp:check("2.."))
- end
- return 1
-end
-function methods.pasv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("pasv"))
- local code,reply=try(self.tp:check("2.."))
- local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
- try(a and b and c and d and p1 and p2,reply)
- local address=format("%d.%d.%d.%d",a,b,c,d)
- local port=p1*256+p2
- local server=self.server
- self.pasvt={
-  address=address,
-  port=port,
- }
- if server then
-  server:close()
-  self.server=nil
- end
- return address,port
-end
-function methods.epsv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("epsv"))
- local code,reply=try(tp:check("229"))
- local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
- local d,prt,address,port=match(reply,pattern)
- try(port,"invalid epsv response")
- local address=tp:getpeername()
- local server=self.server
- self.pasvt={
-  address=address,
-  port=port,
- }
- if self.server then
-  server:close()
-  self.server=nil
- end
- return address,port
-end
-function methods.port(self,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
-  address,port=try(tp:getsockname())
-  self.server=try(bindsocket(address,0))
-  address,port=try(self.server:getsockname())
-  try(self.server:settimeout(ftp.TIMEOUT))
- end
- local pl=mod(port,256)
- local ph=(port-pl)/256
- local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
- try(tp:command("port",arg))
- try(tp:check("2.."))
- return 1
-end
-function methods.eprt(self,family,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
-  address,port=try(tp:getsockname())
-  self.server=try(bindsocket(address,0))
-  address,port=try(self.server:getsockname())
-  try(self.server:settimeout(ftp.TIMEOUT))
- end
- local arg=format("|%s|%s|%d|",family,address,port)
- try(tp:command("eprt",arg))
- try(tp:check("2.."))
- return 1
-end
-function methods.send(self,sendt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then
-  self:pasvconnect()
- end
- local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
- if argument=="" then
-  argument=nil
- end
- local command=sendt.command or "stor"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"2..","1.."})
- if not self.pasvt then
-  self:portconnect()
- end
- local step=sendt.step or pumpstep
- local readt={ tp }
- local checkstep=function(src,snk)
-  local readyt=selectsocket(readt,nil,0)
-  if readyt[tp] then
-   code=try(tp:check("2.."))
-  end
-  return step(src,snk)
- end
- local sink=sinksocket("close-when-done",self.data)
- try(pumpall(sendt.source,sink,checkstep))
- if find(code,"1..") then
-  try(tp:check("2.."))
- end
- self.data:close()
- local sent=skipsocket(1,self.data:getstats())
- self.data=nil
- return sent
-end
-function methods.receive(self,recvt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
- if argument=="" then
-  argument=nil
- end
- local command=recvt.command or "retr"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"1..","2.."})
- if code>=200 and code<=299 then
-  recvt.sink(reply)
-  return 1
- end
- if not self.pasvt then
-  self:portconnect()
- end
- local source=sourcesocket("until-closed",self.data)
- local step=recvt.step or pumpstep
- try(pumpall(source,recvt.sink,step))
- if find(code,"1..") then
-  try(tp:check("2.."))
- end
- self.data:close()
- self.data=nil
- return 1
-end
-function methods.cwd(self,dir)
- local try=self.try
- local tp=self.tp
- try(tp:command("cwd",dir))
- try(tp:check(250))
- return 1
-end
-function methods.type(self,typ)
- local try=self.try
- local tp=self.tp
- try(tp:command("type",typ))
- try(tp:check(200))
- return 1
-end
-function methods.greet(self)
- local try=self.try
- local tp=self.tp
- local code=try(tp:check{"1..","2.."})
- if find(code,"1..") then
-  try(tp:check("2.."))
- end
- return 1
-end
-function methods.quit(self)
- local try=self.try
- try(self.tp:command("quit"))
- try(self.tp:check("2.."))
- return 1
-end
-function methods.close(self)
- local data=self.data
- if data then
-  data:close()
- end
- local server=self.server
- if server then
-  server:close()
- end
- local tp=self.tp
- if tp then
-  tp:close()
- end
-end
-local function override(t)
- if t.url then
-  local u=parseurl(t.url)
-  for k,v in next,t do
-   u[k]=v
-  end
-  return u
- else
-  return t
- end
-end
-local function tput(putt)
- putt=override(putt)
- local host=putt.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,putt.port,putt.create)
- f:greet()
- f:login(putt.user,putt.password)
- local typ=putt.type
- if typ then
-  f:type(typ)
- end
- f:epsv()
- local sent=f:send(putt)
- f:quit()
- f:close()
- return sent
-end
-local default={
- path="/",
- scheme="ftp",
-}
-local function genericform(u)
- local t=trysocket(parseurl(u,default))
- trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
- trysocket(t.host,"missing hostname")
- local pat="^type=(.)$"
- if t.params then
-  local typ=skipsocket(2,find(t.params,pat))
-  t.type=typ
-  trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
- end
- return t
-end
-ftp.genericform=genericform
-local function sput(u,body)
- local putt=genericform(u)
- putt.source=sourcestring(body)
- return tput(putt)
-end
-ftp.put=protectsocket(function(putt,body)
- if type(putt)=="string" then
-  return sput(putt,body)
- else
-  return tput(putt)
- end
-end)
-local function tget(gett)
- gett=override(gett)
- local host=gett.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,gett.port,gett.create)
- f:greet()
- f:login(gett.user,gett.password)
- if gett.type then
-  f:type(gett.type)
- end
- f:epsv()
- f:receive(gett)
- f:quit()
- return f:close()
-end
-local function sget(u)
- local gett=genericform(u)
- local t={}
- gett.sink=sinktable(t)
- tget(gett)
- return concat(t)
-end
-ftp.command=protectsocket(function(cmdt)
- cmdt=override(cmdt)
- local command=cmdt.command
- local argument=cmdt.argument
- local check=cmdt.check
- local host=cmdt.host
- trysocket(host,"missing hostname")
- trysocket(command,"missing command")
- local f=ftp.open(host,cmdt.port,cmdt.create)
- local try=f.try
- local tp=f.tp
- f:greet()
- f:login(cmdt.user,cmdt.password)
- if type(command)=="table" then
-  local argument=argument or {}
-  for i=1,#command do
-   local cmd=command[i]
-   try(tp:command(cmd,argument[i]))
-   if check and check[i] then
-    try(tp:check(check[i]))
-   end
-  end
- else
-  try(tp:command(command,argument))
-  if check then
-   try(tp:check(check))
-  end
- end
- f:quit()
- return f:close()
-end)
-ftp.get=protectsocket(function(gett)
- if type(gett)=="string" then
-  return sget(gett)
- else
-  return tget(gett)
- end
-end)
-package.loaded["socket.ftp"]=ftp
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
-
--- original size: 7018, stripped down to: 5883
-
-
-local type,setmetatable,next=type,setmetatable,next
-local find,lower,format=string.find,string.lower,string.format
-local osdate,osgetenv=os.date,os.getenv
-local random=math.random
-local socket=socket   or require("socket")
-local headers=socket.headers or require("socket.headers")
-local ltn12=ltn12    or require("ltn12")
-local tp=socket.tp   or require("socket.tp")
-local mime=mime     or require("mime")
-local mimeb64=mime.b64
-local mimestuff=mime.stuff
-local skipsocket=socket.skip
-local trysocket=socket.try
-local newtrysocket=socket.newtry
-local protectsocket=socket.protect
-local normalizeheaders=headers.normalize
-local lowerheaders=headers.lower
-local createcoroutine=coroutine.create
-local resumecoroutine=coroutine.resume
-local yieldcoroutine=coroutine.resume
-local smtp={
- TIMEOUT=60,
- SERVER="localhost",
- PORT=25,
- DOMAIN=osgetenv("SERVER_NAME") or "localhost",
- ZONE="-0000",
-}
-socket.smtp=smtp
-local methods={}
-local mt={ __index=methods }
-function methods.greet(self,domain)
- local try=self.try
- local tp=self.tp
- try(tp:check("2.."))
- try(tp:command("EHLO",domain or _M.DOMAIN))
- return skipsocket(1,try(tp:check("2..")))
-end
-function methods.mail(self,from)
- local try=self.try
- local tp=self.tp
- try(tp:command("MAIL","FROM:"..from))
- return try(tp:check("2.."))
-end
-function methods.rcpt(self,to)
- local try=self.try
- local tp=self.tp
- try(tp:command("RCPT","TO:"..to))
- return try(tp:check("2.."))
-end
-function methods.data(self,src,step)
- local try=self.try
- local tp=self.tp
- try(tp:command("DATA"))
- try(tp:check("3.."))
- try(tp:source(src,step))
- try(tp:send("\r\n.\r\n"))
- return try(tp:check("2.."))
-end
-function methods.quit(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("QUIT"))
- return try(tp:check("2.."))
-end
-function methods.close(self)
- return self.tp:close()
-end
-function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("AUTH","LOGIN"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(user).."\r\n"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(password).."\r\n"))
- return try(tp:check("2.."))
-end
-function methods.plain(self,user,password)
- local try=self.try
- local tp=self.tp
- local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
- try(tp:command("AUTH",auth))
- return try(tp:check("2.."))
-end
-function methods.auth(self,user,password,ext)
- if not user or not password then
-  return 1
- end
- local try=self.try
- if find(ext,"AUTH[^\n]+LOGIN") then
-  return self:login(user,password)
- elseif find(ext,"AUTH[^\n]+PLAIN") then
-  return self:plain(user,password)
- else
-  try(nil,"authentication not supported")
- end
-end
-function methods.send(self,mail)
- self:mail(mail.from)
- local receipt=mail.rcpt
- if type(receipt)=="table" then
-  for i=1,#receipt do
-   self:rcpt(receipt[i])
-  end
- elseif receipt then
-  self:rcpt(receipt)
- end
- self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
-end
-local function opensmtp(self,server,port,create)
- if not server or server=="" then
-  server=smtp.SERVER
- end
- if not port or port=="" then
-  port=smtp.PORT
- end
- local s={
-  tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
-  try=newtrysocket(function()
-   s:close()
-  end),
- }
- setmetatable(s,mt)
- return s
-end
-smtp.open=opensmtp
-local nofboundaries=0
-local function newboundary()
- nofboundaries=nofboundaries+1
- return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
-end
-local send_message
-local function send_headers(headers)
- yieldcoroutine(normalizeheaders(headers))
-end
-local function send_multipart(message)
- local boundary=newboundary()
- local headers=lowerheaders(message.headers)
- local body=message.body
- local preamble=body.preamble
- local epilogue=body.epilogue
- local content=headers['content-type'] or 'multipart/mixed'
- headers['content-type']=content..'; boundary="'..boundary..'"'
- send_headers(headers)
- if preamble then
-  yieldcoroutine(preamble)
-  yieldcoroutine("\r\n")
- end
- for i=1,#body do
-  yieldcoroutine("\r\n--"..boundary.."\r\n")
-  send_message(body[i])
- end
- yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
- if epilogue then
-  yieldcoroutine(epilogue)
-  yieldcoroutine("\r\n")
- end
-end
-local default_content_type='text/plain; charset="UTF-8"'
-local function send_source(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
-  headers['content-type']=default_content_type
- end
- send_headers(headers)
- local getchunk=message.body
- while true do
-  local chunk,err=getchunk()
-  if err then
-   yieldcoroutine(nil,err)
-  elseif chunk then
-   yieldcoroutine(chunk)
-  else
-   break
-  end
- end
-end
-local function send_string(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
-  headers['content-type']=default_content_type
- end
- send_headers(headers)
- yieldcoroutine(message.body)
-end
-function send_message(message)
- local body=message.body
- if type(body)=="table" then
-  send_multipart(message)
- elseif type(body)=="function" then
-  send_source(message)
- else
-  send_string(message)
- end
-end
-local function adjust_headers(message)
- local headers=lowerheaders(message.headers)
- if not headers["date"] then
-  headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
- end
- if not headers["x-mailer"] then
-  headers["x-mailer"]=socket._VERSION
- end
- headers["mime-version"]="1.0"
- return headers
-end
-function smtp.message(message)
- message.headers=adjust_headers(message)
- local action=createcoroutine(function()
-  send_message(message)
- end)
- return function()
-  local ret,a,b=resumecoroutine(action)
-  if ret then
-   return a,b
-  else
-   return nil,a
-  end
- end
-end
-smtp.send=protectsocket(function(mail)
- local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
- local ext=snd:greet(mail.domain)
- snd:auth(mail.user,mail.password,ext)
- snd:send(mail)
- snd:quit()
- return snd:close()
-end)
-package.loaded["socket.smtp"]=smtp
-
-
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
 package.loaded["trac-set"] = package.loaded["trac-set"] or true
 
--- original size: 13340, stripped down to: 8826
+-- original size: 13044, stripped down to: 9231
 
 if not modules then modules={} end modules ['trac-set']={ 
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type,next,tostring,tonumber=type,next,tostring,tonumber
 local concat,sortedhash=table.concat,table.sortedhash
@@ -12358,318 +8967,305 @@
 local data={}
 local trace_initialize=false 
 function setters.initialize(filename,name,values) 
- local setter=data[name]
- if setter then
-  frozen=true
-  local data=setter.data
-  if data then
-   for key,newvalue in sortedhash(values) do
-    local newvalue=is_boolean(newvalue,newvalue,true) 
-    local functions=data[key]
-    if functions then
-     local oldvalue=functions.value
-     if functions.frozen then
-      if trace_initialize then
-       setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+  local setter=data[name]
+  if setter then
+    frozen=true
+    local data=setter.data
+    if data then
+      for key,newvalue in sortedhash(values) do
+        local newvalue=is_boolean(newvalue,newvalue,true) 
+        local functions=data[key]
+        if functions then
+          local oldvalue=functions.value
+          if functions.frozen then
+            if trace_initialize then
+              setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+            end
+          elseif #functions>0 and not oldvalue then
+            if trace_initialize then
+              setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+            end
+            for i=1,#functions do
+              functions[i](newvalue)
+            end
+            functions.value=newvalue
+            functions.frozen=functions.frozen or frozen
+          else
+            if trace_initialize then
+              setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
+            end
+          end
+        else
+          functions={ default=newvalue,frozen=frozen }
+          data[key]=functions
+          if trace_initialize then
+            setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+          end
+        end
       end
-     elseif #functions>0 and not oldvalue then
-      if trace_initialize then
-       setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
-      end
-      for i=1,#functions do
-       functions[i](newvalue)
-      end
-      functions.value=newvalue
-      functions.frozen=functions.frozen or frozen
-     else
-      if trace_initialize then
-       setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
-      end
-     end
-    else
-     functions={ default=newvalue,frozen=frozen }
-     data[key]=functions
-     if trace_initialize then
-      setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
-     end
+      return true
     end
-   end
-   return true
   end
- end
 end
 local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
-  local done=t.done
-  if type(what)=="string" then
-   what=settings_to_hash(what) 
-  end
-  if type(what)~="table" then
-   return
-  end
-  if not done then 
-   done={}
-   t.done=done
-  end
-  for w,value in sortedhash(what) do
-   if value=="" then
-    value=newvalue
-   elseif not value then
-    value=false 
-   else
-    value=is_boolean(value,value,true) 
-   end
-   w=topattern(w,true,true)
-   for name,functions in sortedhash(data) do
-    if done[name] then
-    elseif find(name,w) then
-     done[name]=true
-     for i=1,#functions do
-      functions[i](value)
-     end
-     functions.value=value
+  local data=t.data
+  if not data.frozen then
+    local done=t.done
+    if type(what)=="string" then
+      what=settings_to_hash(what) 
     end
-   end
+    if type(what)~="table" then
+      return
+    end
+    if not done then 
+      done={}
+      t.done=done
+    end
+    for w,value in sortedhash(what) do
+      if value=="" then
+        value=newvalue
+      elseif not value then
+        value=false 
+      else
+        value=is_boolean(value,value,true) 
+      end
+      w=topattern(w,true,true)
+      for name,functions in sortedhash(data) do
+        if done[name] then
+        elseif find(name,w) then
+          done[name]=true
+          for i=1,#functions do
+            functions[i](value)
+          end
+          functions.value=value
+        end
+      end
+    end
   end
- end
 end
 local function reset(t)
- local data=t.data
- if not data.frozen then
-  for name,functions in sortedthash(data) do
-   for i=1,#functions do
-    functions[i](false)
-   end
-   functions.value=false
+  local data=t.data
+  if not data.frozen then
+    for name,functions in sortedthash(data) do
+      for i=1,#functions do
+        functions[i](false)
+      end
+      functions.value=false
+    end
   end
- end
 end
 local function enable(t,what)
- set(t,what,true)
+  set(t,what,true)
 end
 local function disable(t,what)
- local data=t.data
- if not what or what=="" then
-  t.done={}
-  reset(t)
- else
-  set(t,what,false)
- end
+  local data=t.data
+  if not what or what=="" then
+    t.done={}
+    reset(t)
+  else
+    set(t,what,false)
+  end
 end
 function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
-  functions={}
-  data[what]=functions
-  if trace_initialize then
-   t.report("defining %a",what)
+  local data=t.data
+  what=lower(what)
+  local functions=data[what]
+  if not functions then
+    functions={}
+    data[what]=functions
+    if trace_initialize then
+      t.report("defining %a",what)
+    end
   end
- end
- local default=functions.default 
- for i=1,select("#",...) do
-  local fnc=select(i,...)
-  local typ=type(fnc)
-  if typ=="string" then
-   if trace_initialize then
-    t.report("coupling %a to %a",what,fnc)
-   end
-   local s=fnc 
-   fnc=function(value) set(t,s,value) end
-  elseif typ~="function" then
-   fnc=nil
+  local default=functions.default 
+  for i=1,select("#",...) do
+    local fnc=select(i,...)
+    local typ=type(fnc)
+    if typ=="string" then
+      if trace_initialize then
+        t.report("coupling %a to %a",what,fnc)
+      end
+      local s=fnc 
+      fnc=function(value) set(t,s,value) end
+    elseif typ~="function" then
+      fnc=nil
+    end
+    if fnc then
+      functions[#functions+1]=fnc
+      local value=functions.value or default
+      if value~=nil then
+        fnc(value)
+        functions.value=value
+      end
+    end
   end
-  if fnc then
-   functions[#functions+1]=fnc
-   local value=functions.value or default
-   if value~=nil then
-    fnc(value)
-    functions.value=value
-   end
-  end
- end
- return false 
+  return false 
 end
 function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+  local e=t.enable
+  t.enable,t.done=enable,{}
+  enable(t,what)
+  t.enable,t.done=e,{}
 end
 function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+  local e=t.disable
+  t.disable,t.done=disable,{}
+  disable(t,what)
+  t.disable,t.done=e,{}
 end
 function setters.reset(t)
- t.done={}
- reset(t)
+  t.done={}
+  reset(t)
 end
 function setters.list(t) 
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
-  local what=list[l]
-  if find(what,"^%*") then
-   system[#system+1]=what
-  else
-   user[#user+1]=what
+  local list=table.sortedkeys(t.data)
+  local user,system={},{}
+  for l=1,#list do
+    local what=list[l]
+    if find(what,"^%*") then
+      system[#system+1]=what
+    else
+      user[#user+1]=what
+    end
   end
- end
- return user,system
+  return user,system
 end
 function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
-  local name=list[k]
-  local functions=t.data[name]
-  if functions then
-   local value=functions.value
-   local default=functions.default
-   local modules=#functions
-   if default==nil then
-    default="unset"
-   elseif type(default)=="table" then
-    default=concat(default,"|")
-   else
-    default=tostring(default)
-   end
-   if value==nil then
-    value="unset"
-   elseif type(value)=="table" then
-    value=concat(value,"|")
-   else
-    value=tostring(value)
-   end
-   t.report(name)
-   t.report("    modules : %i",modules)
-   t.report("    default : %s",default)
-   t.report("    value   : %s",value)
-   t.report()
+  local list=setters.list(t)
+  t.report()
+  for k=1,#list do
+    local name=list[k]
+    local functions=t.data[name]
+    if functions then
+      local value=functions.value
+      local default=functions.default
+      local modules=#functions
+      if default==nil then
+        default="unset"
+      elseif type(default)=="table" then
+        default=concat(default,"|")
+      else
+        default=tostring(default)
+      end
+      if value==nil then
+        value="unset"
+      elseif type(value)=="table" then
+        value=concat(value,"|")
+      else
+        value=tostring(value)
+      end
+      t.report(name)
+      t.report("    modules : %i",modules)
+      t.report("    default : %s",default)
+      t.report("    value   : %s",value)
+      t.report()
+    end
   end
- end
 end
 local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
 function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+  print(format("%-15s : %s\n",setter.name,format(...)))
 end
 local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+  local d=setter.data[name]
+  return d and d.default
 end
 local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+  local d=setter.data[name]
+  return d and (d.value or d.default)
 end
 function setters.new(name) 
- local setter 
- setter={
-  data=allocate(),
-  name=name,
-  report=function(...) setters.report  (setter,...) end,
-  enable=function(...)   enable  (setter,...) end,
-  disable=function(...)   disable (setter,...) end,
-  reset=function(...)   reset   (setter,...) end,
-  register=function(...)   register(setter,...) end,
-  list=function(...)   list (setter,...) end,
-  show=function(...)   show (setter,...) end,
-  default=function(...)  return default (setter,...) end,
-  value=function(...)  return value   (setter,...) end,
- }
- data[name]=setter
- return setter
+  local setter 
+  setter={
+    data=allocate(),
+    name=name,
+    report=function(...) setters.report (setter,...) end,
+    enable=function(...)     enable (setter,...) end,
+    disable=function(...)     disable (setter,...) end,
+    reset=function(...)     reset  (setter,...) end,
+    register=function(...)     register(setter,...) end,
+    list=function(...)     list  (setter,...) end,
+    show=function(...)     show  (setter,...) end,
+    default=function(...) return default (setter,...) end,
+    value=function(...) return value  (setter,...) end,
+  }
+  data[name]=setter
+  return setter
 end
 trackers=setters.new("trackers")
 directives=setters.new("directives")
 experiments=setters.new("experiments")
-local t_enable,t_disable=trackers   .enable,trackers   .disable
+local t_enable,t_disable=trackers  .enable,trackers  .disable
 local d_enable,d_disable=directives .enable,directives .disable
 local e_enable,e_disable=experiments.enable,experiments.disable
-local trace_directives=false local trace_directives=false  trackers.register("system.directives",function(v) trace_directives=v end)
-local trace_experiments=false local trace_experiments=false  trackers.register("system.experiments",function(v) trace_experiments=v end)
+local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
+local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
 function directives.enable(...)
- if trace_directives then
-  directives.report("enabling: % t",{...})
- end
- d_enable(...)
+  if trace_directives then
+    directives.report("enabling: % t",{...})
+  end
+  d_enable(...)
 end
 function directives.disable(...)
- if trace_directives then
-  directives.report("disabling: % t",{...})
- end
- d_disable(...)
+  if trace_directives then
+    directives.report("disabling: % t",{...})
+  end
+  d_disable(...)
 end
 function experiments.enable(...)
- if trace_experiments then
-  experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+  if trace_experiments then
+    experiments.report("enabling: % t",{...})
+  end
+  e_enable(...)
 end
 function experiments.disable(...)
- if trace_experiments then
-  experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+  if trace_experiments then
+    experiments.report("disabling: % t",{...})
+  end
+  e_disable(...)
 end
 directives.register("system.nostatistics",function(v)
- if statistics then
-  statistics.enable=not v
- else
- end
+  if statistics then
+    statistics.enable=not v
+  else
+  end
 end)
 directives.register("system.nolibraries",function(v)
- if libraries then
-  libraries=nil 
- else
- end
+  if libraries then
+    libraries=nil 
+  else
+  end
 end)
 if environment then
- local engineflags=environment.engineflags
- if engineflags then
-  local list=engineflags["c:trackers"] or engineflags["trackers"]
-  if type(list)=="string" then
-   setters.initialize("commandline flags","trackers",settings_to_hash(list))
+  local engineflags=environment.engineflags
+  if engineflags then
+    local list=engineflags["c:trackers"] or engineflags["trackers"]
+    if type(list)=="string" then
+      setters.initialize("commandline flags","trackers",settings_to_hash(list))
+    end
+    local list=engineflags["c:directives"] or engineflags["directives"]
+    if type(list)=="string" then
+      setters.initialize("commandline flags","directives",settings_to_hash(list))
+    end
   end
-  local list=engineflags["c:directives"] or engineflags["directives"]
-  if type(list)=="string" then
-   setters.initialize("commandline flags","directives",settings_to_hash(list))
-  end
- end
 end
 if texconfig then
- local function set(k,v)
-  v=tonumber(v)
-  if v then
-   texconfig[k]=v
+  local function set(k,v)
+    v=tonumber(v)
+    if v then
+      texconfig[k]=v
+    end
   end
- end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v)   end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v)  end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v)   end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v)  end)
- directives.register("luatex.savesize",function(v) set("save_size",v)   end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v)  end)
+  directives.register("luatex.expanddepth",function(v) set("expand_depth",v)  end)
+  directives.register("luatex.hashextra",function(v) set("hash_extra",v)   end)
+  directives.register("luatex.nestsize",function(v) set("nest_size",v)   end)
+  directives.register("luatex.maxinopen",function(v) set("max_in_open",v)  end)
+  directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+  directives.register("luatex.maxstrings",function(v) set("max_strings",v)  end)
+  directives.register("luatex.paramsize",function(v) set("param_size",v)   end)
+  directives.register("luatex.savesize",function(v) set("save_size",v)   end)
+  directives.register("luatex.stacksize",function(v) set("stack_size",v)   end)
 end
-local data=table.setmetatableindex("table")
-updaters={
- register=function(what,f)
-  local d=data[what]
-  d[#d+1]=f
- end,
- apply=function(what,...)
-  local d=data[what]
-  for i=1,#d do
-   d[i](...)
-  end
- end,
-}
 
 
 end -- of closure
@@ -12678,14 +9274,14 @@
 
 package.loaded["trac-log"] = package.loaded["trac-log"] or true
 
--- original size: 32608, stripped down to: 20925
+-- original size: 32922, stripped down to: 23011
 
 if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to trac-log.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local next,type,select,print=next,type,select,print
 local format,gmatch,find=string.format,string.gmatch,string.find
@@ -12696,7 +9292,7 @@
 local openfile=io.open
 local runningtex=tex and (tex.jobname or tex.formatname)
 local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write  or io.write
 local setmetatableindex=table.setmetatableindex
 local formatters=string.formatters
 local settings_to_hash=utilities.parsers.settings_to_hash
@@ -12712,12 +9308,12 @@
 wiki     : http://contextgarden.net
 ]]
 formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+  formatters,"unichr",
+  [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
 )
 formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+  formatters,"chruni",
+  [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
 )
 local function ignore() end
 setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
@@ -12724,392 +9320,392 @@
 local report,subreport,status,settarget,setformats,settranslations
 local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
 if runningtex then
- if texio.setescape then
-  texio.setescape(0) 
- end
- if arg then
-  for k,v in next,arg do 
-   if v=="--ansi" or v=="--c:ansi" then
-    variant="ansi"
-    break
-   end
+  if texio.setescape then
+    texio.setescape(0) 
   end
- end
- local function useluawrites()
-  local texio_write_nl=texio.write_nl
-  local texio_write=texio.write
-  local io_write=io.write
-  write_nl=function(target,...)
-   if not io_write then
-    io_write=io.write
-   end
-   if target=="term and log" then
-    texio_write_nl("log",...)
-    texio_write_nl("term","")
-    io_write(...)
-   elseif target=="log" then
-    texio_write_nl("log",...)
-   elseif target=="term" then
-    texio_write_nl("term","")
-    io_write(...)
-   elseif type(target)=="number" then
-    texio_write_nl(target,...) 
-   elseif target~="none" then
-    texio_write_nl("log",target,...)
-    texio_write_nl("term","")
-    io_write(target,...)
-   end
+  if arg then
+    for k,v in next,arg do 
+      if v=="--ansi" or v=="--c:ansi" then
+        variant="ansi"
+        break
+      end
+    end
   end
-  write=function(target,...)
-   if not io_write then
-    io_write=io.write
-   end
-   if target=="term and log" then
-    texio_write("log",...)
-    io_write(...)
-   elseif target=="log" then
-    texio_write("log",...)
-   elseif target=="term" then
-    io_write(...)
-   elseif type(target)=="number" then
-    texio_write(target,...) 
-   elseif target~="none" then
-    texio_write("log",target,...)
-    io_write(target,...)
-   end
+  local function useluawrites()
+    local texio_write_nl=texio.write_nl
+    local texio_write=texio.write
+    local io_write=io.write
+    write_nl=function(target,...)
+      if not io_write then
+        io_write=io.write
+      end
+      if target=="term and log" then
+        texio_write_nl("log",...)
+        texio_write_nl("term","")
+        io_write(...)
+      elseif target=="log" then
+        texio_write_nl("log",...)
+      elseif target=="term" then
+        texio_write_nl("term","")
+        io_write(...)
+      elseif type(target)=="number" then
+        texio_write_nl(target,...) 
+      elseif target~="none" then
+        texio_write_nl("log",target,...)
+        texio_write_nl("term","")
+        io_write(target,...)
+      end
+    end
+    write=function(target,...)
+      if not io_write then
+        io_write=io.write
+      end
+      if target=="term and log" then
+        texio_write("log",...)
+        io_write(...)
+      elseif target=="log" then
+        texio_write("log",...)
+      elseif target=="term" then
+        io_write(...)
+      elseif type(target)=="number" then
+        texio_write(target,...) 
+      elseif target~="none" then
+        texio_write("log",target,...)
+        io_write(target,...)
+      end
+    end
+    texio.write=write
+    texio.write_nl=write_nl
+    useluawrites=ignore
   end
-  texio.write=write
-  texio.write_nl=write_nl
-  useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
-  default={
-   formats={
-    report_yes=formatters["%-15s > %s\n"],
-    report_nop=formatters["%-15s >\n"],
-    direct_yes=formatters["%-15s > %s"],
-    direct_nop=formatters["%-15s >"],
-    subreport_yes=formatters["%-15s > %s > %s\n"],
-    subreport_nop=formatters["%-15s > %s >\n"],
-    subdirect_yes=formatters["%-15s > %s > %s"],
-    subdirect_nop=formatters["%-15s > %s >"],
-    status_yes=formatters["%-15s : %s\n"],
-    status_nop=formatters["%-15s :\n"],
-   },
-   targets={
-    logfile="log",
-    log="log",
-    file="log",
-    console="term",
-    terminal="term",
-    both="term and log",
-   },
-  },
-  ansi={
-   formats={
-    report_yes=formatters["%-15s > %s\n"],
-    report_nop=formatters["%-15s >\n"],
-    direct_yes=formatters["%-15s > %s"],
-    direct_nop=formatters["%-15s >"],
-    subreport_yes=formatters["%-15s > %s > %s\n"],
-    subreport_nop=formatters["%-15s > %s >\n"],
-    subdirect_yes=formatters["%-15s > %s > %s"],
-    subdirect_nop=formatters["%-15s > %s >"],
-    status_yes=formatters["%-15s : %s\n"],
-    status_nop=formatters["%-15s :\n"],
-   },
-   targets={
-    logfile="none",
-    log="none",
-    file="none",
-    console="term",
-    terminal="term",
-    both="term",
-   },
+  local whereto="both"
+  local target=nil
+  local targets=nil
+  local formats=table.setmetatableindex("self")
+  local translations=table.setmetatableindex("self")
+  local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+  local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+  local variants={
+    default={
+      formats={
+        report_yes=formatters["%-15s > %s\n"],
+        report_nop=formatters["%-15s >\n"],
+        direct_yes=formatters["%-15s > %s"],
+        direct_nop=formatters["%-15s >"],
+        subreport_yes=formatters["%-15s > %s > %s\n"],
+        subreport_nop=formatters["%-15s > %s >\n"],
+        subdirect_yes=formatters["%-15s > %s > %s"],
+        subdirect_nop=formatters["%-15s > %s >"],
+        status_yes=formatters["%-15s : %s\n"],
+        status_nop=formatters["%-15s :\n"],
+      },
+      targets={
+        logfile="log",
+        log="log",
+        file="log",
+        console="term",
+        terminal="term",
+        both="term and log",
+      },
+    },
+    ansi={
+      formats={
+        report_yes=formatters["%-15s > %s\n"],
+        report_nop=formatters["%-15s >\n"],
+        direct_yes=formatters["%-15s > %s"],
+        direct_nop=formatters["%-15s >"],
+        subreport_yes=formatters["%-15s > %s > %s\n"],
+        subreport_nop=formatters["%-15s > %s >\n"],
+        subdirect_yes=formatters["%-15s > %s > %s"],
+        subdirect_nop=formatters["%-15s > %s >"],
+        status_yes=formatters["%-15s : %s\n"],
+        status_nop=formatters["%-15s :\n"],
+      },
+      targets={
+        logfile="none",
+        log="none",
+        file="none",
+        console="term",
+        terminal="term",
+        both="term",
+      },
+    }
   }
- }
- logs.flush=io.flush
- writer=function(...)
-  write_nl(target,...)
- end
- newline=function()
-  write_nl(target,"\n")
- end
- report=function(a,b,c,...)
-  if c~=nil then
-   write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
-  elseif b then
-   write_nl(target,report_yes(translations[a],formats[b]))
-  elseif a then
-   write_nl(target,report_nop(translations[a]))
-  else
-   write_nl(target,"\n")
+  logs.flush=io.flush
+  writer=function(...)
+    write_nl(target,...)
   end
- end
- direct=function(a,b,c,...)
-  if c~=nil then
-   return direct_yes(translations[a],formatters[formats[b]](c,...))
-  elseif b then
-   return direct_yes(translations[a],formats[b])
-  elseif a then
-   return direct_nop(translations[a])
-  else
-   return ""
+  newline=function()
+    write_nl(target,"\n")
   end
- end
- subreport=function(a,s,b,c,...)
-  if c~=nil then
-   write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
-  elseif b then
-   write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
-  elseif a then
-   write_nl(target,subreport_nop(translations[a],translations[s]))
-  else
-   write_nl(target,"\n")
+  report=function(a,b,c,...)
+    if c~=nil then
+      write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+    elseif b then
+      write_nl(target,report_yes(translations[a],formats[b]))
+    elseif a then
+      write_nl(target,report_nop(translations[a]))
+    else
+      write_nl(target,"\n")
+    end
   end
- end
- subdirect=function(a,s,b,c,...)
-  if c~=nil then
-   return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
-  elseif b then
-   return subdirect_yes(translations[a],translations[s],formats[b])
-  elseif a then
-   return subdirect_nop(translations[a],translations[s])
-  else
-   return ""
+  direct=function(a,b,c,...)
+    if c~=nil then
+      return direct_yes(translations[a],formatters[formats[b]](c,...))
+    elseif b then
+      return direct_yes(translations[a],formats[b])
+    elseif a then
+      return direct_nop(translations[a])
+    else
+      return ""
+    end
   end
- end
- status=function(a,b,c,...)
-  if c~=nil then
-   write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
-  elseif b then
-   write_nl(target,status_yes(translations[a],formats[b]))
-  elseif a then
-   write_nl(target,status_nop(translations[a]))
-  else
-   write_nl(target,"\n")
+  subreport=function(a,s,b,c,...)
+    if c~=nil then
+      write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+    elseif b then
+      write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+    elseif a then
+      write_nl(target,subreport_nop(translations[a],translations[s]))
+    else
+      write_nl(target,"\n")
+    end
   end
- end
- settarget=function(askedwhereto)
-  whereto=askedwhereto or whereto or "both"
-  target=targets[whereto]
-  if not target then
-   whereto="both"
-   target=targets[whereto]
+  subdirect=function(a,s,b,c,...)
+    if c~=nil then
+      return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+    elseif b then
+      return subdirect_yes(translations[a],translations[s],formats[b])
+    elseif a then
+      return subdirect_nop(translations[a],translations[s])
+    else
+      return ""
+    end
   end
-  if target=="term" or target=="term and log" then
-   logs.flush=io.flush
-  else
-   logs.flush=ignore
+  status=function(a,b,c,...)
+    if c~=nil then
+      write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+    elseif b then
+      write_nl(target,status_yes(translations[a],formats[b]))
+    elseif a then
+      write_nl(target,status_nop(translations[a]))
+    else
+      write_nl(target,"\n")
+    end
   end
- end
- local stack={}
- pushtarget=function(newtarget)
-  insert(stack,target)
-  settarget(newtarget)
- end
- poptarget=function()
-  if #stack>0 then
-   settarget(remove(stack))
+  settarget=function(askedwhereto)
+    whereto=askedwhereto or whereto or "both"
+    target=targets[whereto]
+    if not target then
+      whereto="both"
+      target=targets[whereto]
+    end
+    if target=="term" or target=="term and log" then
+      logs.flush=io.flush
+    else
+      logs.flush=ignore
+    end
   end
- end
- setformats=function(f)
-  formats=f
- end
- settranslations=function(t)
-  translations=t
- end
- setprocessor=function(f)
-  local writeline=write_nl
-  write_nl=function(target,...)
-   writeline(target,f(...))
+  local stack={}
+  pushtarget=function(newtarget)
+    insert(stack,target)
+    settarget(newtarget)
   end
- end
- setformatters=function(specification)
-  local t=nil
-  local f=nil
-  local d=variants.default
-  if not specification then
-  elseif type(specification)=="table" then
-   t=specification.targets
-   f=specification.formats or specification
-  else
-   local v=variants[specification]
-   if v then
-    t=v.targets
-    f=v.formats
-    variant=specification
-   end
+  poptarget=function()
+    if #stack>0 then
+      settarget(remove(stack))
+    end
   end
-  targets=t or d.targets
-  target=targets[whereto] or target
-  if f then
-   d=d.formats
-  else
-   f=d.formats
-   d=f
+  setformats=function(f)
+    formats=f
   end
-  setmetatableindex(f,d)
-  report_yes=f.report_yes
-  report_nop=f.report_nop
-  subreport_yes=f.subreport_yes
-  subreport_nop=f.subreport_nop
-  direct_yes=f.direct_yes
-  direct_nop=f.direct_nop
-  subdirect_yes=f.subdirect_yes
-  subdirect_nop=f.subdirect_nop
-  status_yes=f.status_yes
-  status_nop=f.status_nop
-  if variant=="ansi" then
-   useluawrites() 
+  settranslations=function(t)
+    translations=t
   end
-  settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+  setprocessor=function(f)
+    local writeline=write_nl
+    write_nl=function(target,...)
+      writeline(target,f(...))
+    end
+  end
+  setformatters=function(specification)
+    local t=nil
+    local f=nil
+    local d=variants.default
+    if not specification then
+    elseif type(specification)=="table" then
+      t=specification.targets
+      f=specification.formats or specification
+    else
+      local v=variants[specification]
+      if v then
+        t=v.targets
+        f=v.formats
+        variant=specification
+      end
+    end
+    targets=t or d.targets
+    target=targets[whereto] or target
+    if f then
+      d=d.formats
+    else
+      f=d.formats
+      d=f
+    end
+    setmetatableindex(f,d)
+    report_yes=f.report_yes
+    report_nop=f.report_nop
+    subreport_yes=f.subreport_yes
+    subreport_nop=f.subreport_nop
+    direct_yes=f.direct_yes
+    direct_nop=f.direct_nop
+    subdirect_yes=f.subdirect_yes
+    subdirect_nop=f.subdirect_nop
+    status_yes=f.status_yes
+    status_nop=f.status_nop
+    if variant=="ansi" then
+      useluawrites() 
+    end
+    settarget(whereto)
+  end
+  setformatters(variant)
+  setlogfile=ignore
+  settimedlog=ignore
 else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
-  default={
-   formats={
-    report_yes=formatters["%-15s | %s"],
-    report_nop=formatters["%-15s |"],
-    subreport_yes=formatters["%-15s | %s | %s"],
-    subreport_nop=formatters["%-15s | %s |"],
-    status_yes=formatters["%-15s : %s\n"],
-    status_nop=formatters["%-15s :\n"],
-   },
-  },
-  ansi={
-   formats={
-    report_yes=formatters["%-15s | %s"],
-    report_nop=formatters["%-15s |"],
-    subreport_yes=formatters["%-15s | %s | %s"],
-    subreport_nop=formatters["%-15s | %s |"],
-    status_yes=formatters["%-15s : %s\n"],
-    status_nop=formatters["%-15s :\n"],
-   },
-  },
- }
- logs.flush=ignore
- writer=function(s)
-  write_nl(s)
- end
- newline=function()
-  write_nl("\n")
- end
- report=function(a,b,c,...)
-  if c then
-   write_nl(report_yes(a,formatters[b](c,...)))
-  elseif b then
-   write_nl(report_yes(a,b))
-  elseif a then
-   write_nl(report_nop(a))
-  else
-   write_nl("")
+  local report_yes,subreport_yes,status_yes
+  local report_nop,subreport_nop,status_nop
+  local variants={
+    default={
+      formats={
+        report_yes=formatters["%-15s | %s"],
+        report_nop=formatters["%-15s |"],
+        subreport_yes=formatters["%-15s | %s | %s"],
+        subreport_nop=formatters["%-15s | %s |"],
+        status_yes=formatters["%-15s : %s\n"],
+        status_nop=formatters["%-15s :\n"],
+      },
+    },
+    ansi={
+      formats={
+        report_yes=formatters["%-15s | %s"],
+        report_nop=formatters["%-15s |"],
+        subreport_yes=formatters["%-15s | %s | %s"],
+        subreport_nop=formatters["%-15s | %s |"],
+        status_yes=formatters["%-15s : %s\n"],
+        status_nop=formatters["%-15s :\n"],
+      },
+    },
+  }
+  logs.flush=ignore
+  writer=function(s)
+    write_nl(s)
   end
- end
- subreport=function(a,sub,b,c,...)
-  if c then
-   write_nl(subreport_yes(a,sub,formatters[b](c,...)))
-  elseif b then
-   write_nl(subreport_yes(a,sub,b))
-  elseif a then
-   write_nl(subreport_nop(a,sub))
-  else
-   write_nl("")
+  newline=function()
+    write_nl("\n")
   end
- end
- status=function(a,b,c,...) 
-  if c then
-   write_nl(status_yes(a,formatters[b](c,...)))
-  elseif b then
-   write_nl(status_yes(a,b)) 
-  elseif a then
-   write_nl(status_nop(a))
-  else
-   write_nl("\n")
+  report=function(a,b,c,...)
+    if c then
+      write_nl(report_yes(a,formatters[b](c,...)))
+    elseif b then
+      write_nl(report_yes(a,b))
+    elseif a then
+      write_nl(report_nop(a))
+    else
+      write_nl("")
+    end
   end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
-  local writeline=write_nl
-  write_nl=function(s)
-   writeline(f(s))
+  subreport=function(a,sub,b,c,...)
+    if c then
+      write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+    elseif b then
+      write_nl(subreport_yes(a,sub,b))
+    elseif a then
+      write_nl(subreport_nop(a,sub))
+    else
+      write_nl("")
+    end
   end
- end
- setformatters=function(specification)
-  local f=nil
-  local d=variants.default
-  if specification then
-   if type(specification)=="table" then
-    f=specification.formats or specification
-   else
-    local v=variants[specification]
-    if v then
-     f=v.formats
+  status=function(a,b,c,...) 
+    if c then
+      write_nl(status_yes(a,formatters[b](c,...)))
+    elseif b then
+      write_nl(status_yes(a,b)) 
+    elseif a then
+      write_nl(status_nop(a))
+    else
+      write_nl("\n")
     end
-   end
   end
-  if f then
-   d=d.formats
-  else
-   f=d.formats
-   d=f
-  end
-  setmetatableindex(f,d)
-  report_yes=f.report_yes
-  report_nop=f.report_nop
-  subreport_yes=f.subreport_yes
-  subreport_nop=f.subreport_nop
-  status_yes=f.status_yes
-  status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
-  if name and name~="" then
-   local localtime=os.localtime
-   local writeline=write_nl
-   if keepopen then
-    local f=io.open(name,"ab")
+  direct=ignore
+  subdirect=ignore
+  settarget=ignore
+  pushtarget=ignore
+  poptarget=ignore
+  setformats=ignore
+  settranslations=ignore
+  setprocessor=function(f)
+    local writeline=write_nl
     write_nl=function(s)
-     writeline(s)
-     f:write(localtime()," | ",s,"\n")
+      writeline(f(s))
     end
-   else
+  end
+  setformatters=function(specification)
+    local f=nil
+    local d=variants.default
+    if specification then
+      if type(specification)=="table" then
+        f=specification.formats or specification
+      else
+        local v=variants[specification]
+        if v then
+          f=v.formats
+        end
+      end
+    end
+    if f then
+      d=d.formats
+    else
+      f=d.formats
+      d=f
+    end
+    setmetatableindex(f,d)
+    report_yes=f.report_yes
+    report_nop=f.report_nop
+    subreport_yes=f.subreport_yes
+    subreport_nop=f.subreport_nop
+    status_yes=f.status_yes
+    status_nop=f.status_nop
+  end
+  setformatters(variant)
+  setlogfile=function(name,keepopen)
+    if name and name~="" then
+      local localtime=os.localtime
+      local writeline=write_nl
+      if keepopen then
+        local f=io.open(name,"ab")
+        write_nl=function(s)
+          writeline(s)
+          f:write(localtime()," | ",s,"\n")
+        end
+      else
+        write_nl=function(s)
+          writeline(s)
+          local f=io.open(name,"ab")
+          f:write(localtime()," | ",s,"\n")
+          f:close()
+        end
+      end
+    end
+    setlogfile=ignore
+  end
+  settimedlog=function()
+    local localtime=os.localtime
+    local writeline=write_nl
     write_nl=function(s)
-     writeline(s)
-     local f=io.open(name,"ab")
-     f:write(localtime()," | ",s,"\n")
-     f:close()
+      writeline(localtime().." | "..s)
     end
-   end
+    settimedlog=ignore
   end
-  setlogfile=ignore
- end
- settimedlog=function()
-  local localtime=os.localtime
-  local writeline=write_nl
-  write_nl=function(s)
-   writeline(localtime().." | "..s)
-  end
-  settimedlog=ignore
- end
 end
 logs.report=report
 logs.subreport=subreport
@@ -13131,186 +9727,198 @@
 local states=nil
 local force=false
 function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
-  local state=states==true
-  if not state and type(states)=="table" then
-   for c,_ in next,states do
-    if find(category,c) then
-     state=true
-     break
+  local logger=data[category]
+  if not logger then
+    local state=states==true
+    if not state and type(states)=="table" then
+      for c,_ in next,states do
+        if find(category,c) then
+          state=true
+          break
+        end
+      end
     end
-   end
+    logger={
+      reporters={},
+      state=state,
+    }
+    data[category]=logger
   end
-  logger={
-   reporters={},
-   state=state,
-  }
-  data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
-  if subcategory then
-   reporter=function(...)
-    if force or not logger.state then
-     subreport(category,subcategory,...)
+  local reporter=logger.reporters[subcategory or "default"]
+  if not reporter then
+    if subcategory then
+      reporter=function(...)
+        if force or not logger.state then
+          subreport(category,subcategory,...)
+        end
+      end
+      logger.reporters[subcategory]=reporter
+    else
+      local tag=category
+      reporter=function(...)
+        if force or not logger.state then
+          report(category,...)
+        end
+      end
+      logger.reporters.default=reporter
     end
-   end
-   logger.reporters[subcategory]=reporter
-  else
-   local tag=category
-   reporter=function(...)
-    if force or not logger.state then
-     report(category,...)
-    end
-   end
-   logger.reporters.default=reporter
   end
- end
- return reporter
+  return reporter
 end
 logs.new=logs.reporter
 local ctxreport=logs.writer
 function logs.setmessenger(m)
- ctxreport=m
+  ctxreport=m
 end
 function logs.messenger(category,subcategory)
- if subcategory then
-  return function(...)
-   ctxreport(subdirect(category,subcategory,...))
+  if subcategory then
+    return function(...)
+      ctxreport(subdirect(category,subcategory,...))
+    end
+  else
+    return function(...)
+      ctxreport(direct(category,...))
+    end
   end
- else
-  return function(...)
-   ctxreport(direct(category,...))
-  end
- end
 end
 local function setblocked(category,value) 
- if category==true or category=="all" then
-  category,value="*",true
- elseif category==false then
-  category,value="*",false
- elseif value==nil then
-  value=true
- end
- if category=="*" then
-  states=value
-  for k,v in next,data do
-   v.state=value
+  if category==true or category=="all" then
+    category,value="*",true
+  elseif category==false then
+    category,value="*",false
+  elseif value==nil then
+    value=true
   end
- else
-  alllocked=false
-  states=settings_to_hash(category,type(states)=="table" and states or nil)
-  for c in next,states do
-   local v=data[c]
-   if v then
-    v.state=value
-   else
-    c=topattern(c,true,true)
+  if category=="*" then
+    states=value
     for k,v in next,data do
-     if find(k,c) then
       v.state=value
-     end
     end
-   end
+  else
+    alllocked=false
+    states=settings_to_hash(category,type(states)=="table" and states or nil)
+    for c in next,states do
+      local v=data[c]
+      if v then
+        v.state=value
+      else
+        c=topattern(c,true,true)
+        for k,v in next,data do
+          if find(k,c) then
+            v.state=value
+          end
+        end
+      end
+    end
   end
- end
 end
 function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+  setblocked(category,value==nil and true or value)
 end
 function logs.enable(category)
- setblocked(category,false)
+  setblocked(category,false)
 end
 function logs.categories()
- return sortedkeys(data)
+  return sortedkeys(data)
 end
 function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
-  n=n+1
-  local state=v.state
-  local reporters=v.reporters
-  local nc=#category
-  if nc>c then
-   c=nc
+  local n,c,s,max=0,0,0,0
+  for category,v in table.sortedpairs(data) do
+    n=n+1
+    local state=v.state
+    local reporters=v.reporters
+    local nc=#category
+    if nc>c then
+      c=nc
+    end
+    for subcategory,_ in next,reporters do
+      local ns=#subcategory
+      if ns>c then
+        s=ns
+      end
+      local m=nc+ns
+      if m>max then
+        max=m
+      end
+    end
+    local subcategories=concat(sortedkeys(reporters),", ")
+    if state==true then
+      state="disabled"
+    elseif state==false then
+      state="enabled"
+    else
+      state="unknown"
+    end
+    report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
   end
-  for subcategory,_ in next,reporters do
-   local ns=#subcategory
-   if ns>c then
-    s=ns
-   end
-   local m=nc+ns
-   if m>max then
-    max=m
-   end
-  end
-  local subcategories=concat(sortedkeys(reporters),", ")
-  if state==true then
-   state="disabled"
-  elseif state==false then
-   state="enabled"
-  else
-   state="unknown"
-  end
-  report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
- end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+  report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
 end
 local delayed_reporters={}
 setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+  local v=logs.reporter(k.name)
+  t[k]=v
+  return v
 end)
 function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+  delayed_reporters[setter](...)
 end
 directives.register("logs.blocked",function(v)
- setblocked(v,true)
+  setblocked(v,true)
 end)
 directives.register("logs.target",function(v)
- settarget(v)
+  settarget(v)
 end)
 if tex then
- local report=logs.reporter("pages") 
- local texgetcount=tex and tex.getcount
- local real,user,sub=0,0,0
- function logs.start_page_number()
-  real=texgetcount("realpageno")
-  user=texgetcount("userpageno")
-  sub=texgetcount("subpageno")
- end
- local timing=false
- local lasttime=nil
- trackers.register("pages.timing",function(v) 
-  timing=""
- end)
- function logs.stop_page_number() 
-  if timing then
-   local elapsed=statistics.currenttime(statistics)
-   local average,page
-   if not lasttime or real<2 then
-    average=elapsed
-    page=elapsed
-   else
-    average=elapsed/(real-1)
-    page=elapsed-lasttime
-   end
-   lasttime=elapsed
-   timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
+  local report=logs.reporter("pages") 
+  local texgetcount=tex and tex.getcount
+  local real,user,sub
+  function logs.start_page_number()
+    real=texgetcount("realpageno")
+    user=texgetcount("userpageno")
+    sub=texgetcount("subpageno")
   end
-  if real<=0 then
-   report("flushing page%s",timing)
-  elseif user<=0 then
-   report("flushing realpage %s%s",real,timing)
-  elseif sub<=0 then
-   report("flushing realpage %s, userpage %s%s",real,user,timing)
-  else
-   report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+  local timing=false
+  local starttime=nil
+  local lasttime=nil
+  trackers.register("pages.timing",function(v) 
+    starttime=os.clock() 
+    timing=true
+  end)
+  function logs.stop_page_number() 
+    if timing then
+      local elapsed,average
+      local stoptime=os.clock()
+      if not lasttime or real<2 then
+        elapsed=stoptime
+        average=stoptime
+        starttime=stoptime
+      else
+        elapsed=stoptime-lasttime
+        average=(stoptime-starttime)/(real-1)
+      end
+      lasttime=stoptime
+      if real<=0 then
+        report("flushing page, time %0.04f / %0.04f",elapsed,average)
+      elseif user<=0 then
+        report("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average)
+      elseif sub<=0 then
+        report("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average)
+      else
+        report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average)
+      end
+    else
+      if real<=0 then
+        report("flushing page")
+      elseif user<=0 then
+        report("flushing realpage %s",real)
+      elseif sub<=0 then
+        report("flushing realpage %s, userpage %s",real,user)
+      else
+        report("flushing realpage %s, userpage %s, subpage %s",real,user,sub)
+      end
+    end
+    logs.flush()
   end
-  logs.flush()
- end
 end
 local nesting=0
 local verbose=false
@@ -13334,53 +9942,53 @@
 local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
 local p_newline=lpeg.patterns.newline
 local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t)   t.report()  end+p_newline
+  Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t)  t.report() end+p_newline
 )^1
 local function reportlines(t,str)
- if str then
-  lpegmatch(linewise,str,1,t)
- end
+  if str then
+    lpegmatch(linewise,str,1,t)
+  end
 end
 local function reportbanner(t)
- local banner=t.banner
- if banner then
-  t.report(banner)
-  t.report()
- end
+  local banner=t.banner
+  if banner then
+    t.report(banner)
+    t.report()
+  end
 end
 local function reportversion(t)
- local banner=t.banner
- if banner then
-  t.report(banner)
- end
+  local banner=t.banner
+  if banner then
+    t.report(banner)
+  end
 end
 local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
-  reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
-  for i=1,select("#",...) do
-   reportlines(t,t.helpinfo[select(i,...)])
-   if i<n then
-    t.report()
-   end
+  local helpinfo=t.helpinfo
+  if type(helpinfo)=="string" then
+    reportlines(t,helpinfo)
+  elseif type(helpinfo)=="table" then
+    for i=1,select("#",...) do
+      reportlines(t,t.helpinfo[select(i,...)])
+      if i<n then
+        t.report()
+      end
+    end
   end
- end
 end
 local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+  t.report()
+  reportlines(t,t.moreinfo)
 end
 local function reportexport(t,method)
- report(t.helpinfo)
+  report(t.helpinfo)
 end
 local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+  lines=reportlines,
+  banner=reportbanner,
+  version=reportversion,
+  help=reporthelp,
+  info=reportinfo,
+  export=reportexport,
 }
 local exporters={
 }
@@ -13387,169 +9995,169 @@
 logs.reporters=reporters
 logs.exporters=exporters
 function logs.application(t)
- t.name=t.name   or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
-  reporters.banner(t)
-  reporters.help(t,...)
-  reporters.info(t)
- end
- t.export=function(...)
-  reporters.export(t,...)
- end
- t.identify=function()
-  reporters.banner(t)
- end
- t.version=function()
-  reporters.version(t)
- end
- return t
+  t.name=t.name  or "unknown"
+  t.banner=t.banner
+  t.moreinfo=moreinfo
+  t.report=logs.reporter(t.name)
+  t.help=function(...)
+    reporters.banner(t)
+    reporters.help(t,...)
+    reporters.info(t)
+  end
+  t.export=function(...)
+    reporters.export(t,...)
+  end
+  t.identify=function()
+    reporters.banner(t)
+  end
+  t.version=function()
+    reporters.version(t)
+  end
+  return t
 end
 local f_syslog=formatters["%s %s => %s => %s => %s\r"]
 function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
-  local f=openfile(whereto,"a") 
-  if f then
-   f:write(message)
-   f:close()
-   break
-  else
-   sleep(0.1)
+  local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+  for i=1,10 do
+    local f=openfile(whereto,"a") 
+    if f then
+      f:write(message)
+      f:close()
+      break
+    else
+      sleep(0.1)
+    end
   end
- end
 end
 local report_system=logs.reporter("system","logs")
 function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
-  return function(...)
-   report_system("function %a is obsolete, use %a",old,new)
-   loadstring(old.."="..new.." return "..old)()(...)
+  local o=loadstring("return "..new)()
+  if type(o)=="function" then
+    return function(...)
+      report_system("function %a is obsolete, use %a",old,new)
+      loadstring(old.."="..new.." return "..old)()(...)
+    end
+  elseif type(o)=="table" then
+    local t,m={},{}
+    m.__index=function(t,k)
+      report_system("table %a is obsolete, use %a",old,new)
+      m.__index,m.__newindex=o,o
+      return o[k]
+    end
+    m.__newindex=function(t,k,v)
+      report_system("table %a is obsolete, use %a",old,new)
+      m.__index,m.__newindex=o,o
+      o[k]=v
+    end
+    if libraries then
+      libraries.obsolete[old]=t 
+    end
+    setmetatable(t,m)
+    return t
   end
- elseif type(o)=="table" then
-  local t,m={},{}
-  m.__index=function(t,k)
-   report_system("table %a is obsolete, use %a",old,new)
-   m.__index,m.__newindex=o,o
-   return o[k]
-  end
-  m.__newindex=function(t,k,v)
-   report_system("table %a is obsolete, use %a",old,new)
-   m.__index,m.__newindex=o,o
-   o[k]=v
-  end
-  if libraries then
-   libraries.obsolete[old]=t 
-  end
-  setmetatable(t,m)
-  return t
- end
 end
 if utilities then
- utilities.report=report_system
+  utilities.report=report_system
 end
 if tex and tex.error then
- function logs.texerrormessage(...) 
-  tex.error(format(...))
- end
+  function logs.texerrormessage(...) 
+    tex.error(format(...),{})
+  end
 else
- function logs.texerrormessage(...)
-  print(format(...))
- end
+  function logs.texerrormessage(...)
+    print(format(...))
+  end
 end
 io.stdout:setvbuf('no')
 io.stderr:setvbuf('no')
 if package.helpers.report then
- package.helpers.report=logs.reporter("package loader") 
+  package.helpers.report=logs.reporter("package loader") 
 end
 if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
-  return loggingerrors
- end
- directives.register("logs.errors",function(v)
-  loggingerrors=v
-  if type(v)=="string" then
-   fatalerrors=settings_to_hash(v)
-  else
-   fatalerrors={}
+  local finalactions={}
+  local fatalerrors={}
+  local possiblefatal={}
+  local loggingerrors=false
+  function logs.loggingerrors()
+    return loggingerrors
   end
- end)
- function logs.registerfinalactions(...)
-  insert(finalactions,...) 
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
-  target=t
-  state=force
-  force=true
-  report=type(r)=="function" and r or logs.reporter(r)
-  what=w
-  pushtarget(target)
-  newline()
-  if s then
-   report("start %s: %s",what,s)
-  else
-   report("start %s",what)
+  directives.register("logs.errors",function(v)
+    loggingerrors=v
+    if type(v)=="string" then
+      fatalerrors=settings_to_hash(v)
+    else
+      fatalerrors={}
+    end
+  end)
+  function logs.registerfinalactions(...)
+    insert(finalactions,...) 
   end
-  if target=="logfile" then
-   newline()
+  local what=nil
+  local report=nil
+  local state=nil
+  local target=nil
+  local function startlogging(t,r,w,s)
+    target=t
+    state=force
+    force=true
+    report=type(r)=="function" and r or logs.reporter(r)
+    what=w
+    pushtarget(target)
+    newline()
+    if s then
+      report("start %s: %s",what,s)
+    else
+      report("start %s",what)
+    end
+    if target=="logfile" then
+      newline()
+    end
+    return report
   end
-  return report
- end
- local function stoplogging()
-  if target=="logfile" then
-   newline()
+  local function stoplogging()
+    if target=="logfile" then
+      newline()
+    end
+    report("stop %s",what)
+    if target=="logfile" then
+      newline()
+    end
+    poptarget()
+    state=oldstate
   end
-  report("stop %s",what)
-  if target=="logfile" then
-   newline()
+  function logs.startfilelogging(...)
+    return startlogging("logfile",...)
   end
-  poptarget()
-  state=oldstate
- end
- function logs.startfilelogging(...)
-  return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
-  if not done then
-   pushtarget("terminal")
-   newline()
-   logs.report("error logging","start possible issues")
-   poptarget()
-   done=true
+  logs.stopfilelogging=stoplogging
+  local done=false
+  function logs.starterrorlogging(r,w,...)
+    if not done then
+      pushtarget("terminal")
+      newline()
+      logs.report("error logging","start possible issues")
+      poptarget()
+      done=true
+    end
+    if fatalerrors[w] then
+      possiblefatal[w]=true
+    end
+    return startlogging("terminal",r,w,...)
   end
-  if fatalerrors[w] then
-   possiblefatal[w]=true
+  logs.stoperrorlogging=stoplogging
+  function logs.finalactions()
+    if #finalactions>0 then
+      for i=1,#finalactions do
+        finalactions[i]()
+      end
+      if done then
+        pushtarget("terminal")
+        newline()
+        logs.report("error logging","stop possible issues")
+        poptarget()
+      end
+      return next(possiblefatal) and sortedkeys(possiblefatal) or false
+    end
   end
-  return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
-  if #finalactions>0 then
-   for i=1,#finalactions do
-    finalactions[i]()
-   end
-   if done then
-    pushtarget("terminal")
-    newline()
-    logs.report("error logging","stop possible issues")
-    poptarget()
-   end
-   return next(possiblefatal) and sortedkeys(possiblefatal) or false
-  end
- end
 end
 
 
@@ -13559,14 +10167,14 @@
 
 package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
 
--- original size: 9072, stripped down to: 6055
+-- original size: 8097, stripped down to: 5534
 
 if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to trac-inf.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type,tonumber,select=type,tonumber,select
 local format,lower,find=string.format,string.lower,string.find
@@ -13581,191 +10189,161 @@
 statistics.threshold=0.01
 local statusinfo,n,registered,timers={},0,{},{}
 setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+  local v={ timing=0,loadtime=0 }
+  t[k]=v
+  return v
 end)
 local function hastiming(instance)
- return instance and timers[instance]
+  return instance and timers[instance]
 end
 local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+  timers[instance or "notimer"]={ timing=0,loadtime=0 }
 end
 local ticks=clock
 local seconds=function(n) return n or 0 end
-local function starttiming(instance,reset)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if reset then
-  it=0
-  timer.loadtime=0
- end
- if it==0 then
-  timer.starttime=ticks()
-  if not timer.loadtime then
-   timer.loadtime=0
+local function starttiming(instance)
+  local timer=timers[instance or "notimer"]
+  local it=timer.timing
+  if it==0 then
+    timer.starttime=ticks()
+    if not timer.loadtime then
+      timer.loadtime=0
+    end
   end
- end
- timer.timing=it+1
+  timer.timing=it+1
 end
 local function stoptiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
-  timer.timing=it-1
- else
-  local starttime=timer.starttime
-  if starttime and starttime>0 then
-   local stoptime=ticks()
-   local loadtime=stoptime-starttime
-   timer.stoptime=stoptime
-   timer.loadtime=timer.loadtime+loadtime
-   timer.timing=0
-   timer.starttime=0
-   return loadtime
-  end
- end
- return 0
-end
-local function elapsed(instance)
- if type(instance)=="number" then
-  return instance
- else
   local timer=timers[instance or "notimer"]
-  return timer and seconds(timer.loadtime) or 0
- end
-end
-local function currenttime(instance)
- if type(instance)=="number" then
-  return instance
- else
-  local timer=timers[instance or "notimer"]
   local it=timer.timing
   if it>1 then
+    timer.timing=it-1
   else
-   local starttime=timer.starttime
-   if starttime and starttime>0 then
-    return seconds(timer.loadtime+ticks()-starttime)
-   end
+    local starttime=timer.starttime
+    if starttime and starttime>0 then
+      local stoptime=ticks()
+      local loadtime=stoptime-starttime
+      timer.stoptime=stoptime
+      timer.loadtime=timer.loadtime+loadtime
+      timer.timing=0
+      timer.starttime=0
+      return loadtime
+    end
   end
   return 0
- end
 end
+local function elapsed(instance)
+  if type(instance)=="number" then
+    return instance
+  else
+    local timer=timers[instance or "notimer"]
+    return timer and seconds(timer.loadtime) or 0
+  end
+end
 local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+  return format("%0.3f",elapsed(instance))
 end
 local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+  return elapsed(instance)>statistics.threshold
 end
 local function elapsedseconds(instance,rest) 
- if elapsedindeed(instance) then
-  return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+  if elapsedindeed(instance) then
+    return format("%0.3f seconds %s",elapsed(instance),rest or "")
+  end
 end
 statistics.hastiming=hastiming
 statistics.resettiming=resettiming
 statistics.starttiming=starttiming
 statistics.stoptiming=stoptiming
-statistics.currenttime=currenttime
 statistics.elapsed=elapsed
 statistics.elapsedtime=elapsedtime
 statistics.elapsedindeed=elapsedindeed
 statistics.elapsedseconds=elapsedseconds
 function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
-  local rt=registered[tag] or (#statusinfo+1)
-  statusinfo[rt]={ tag,fnc }
-  registered[tag]=rt
-  if #tag>n then n=#tag end
- end
+  if statistics.enable and type(fnc)=="function" then
+    local rt=registered[tag] or (#statusinfo+1)
+    statusinfo[rt]={ tag,fnc }
+    registered[tag]=rt
+    if #tag>n then n=#tag end
+  end
 end
 local report=logs.reporter("mkiv lua stats")
 function statistics.show()
- if statistics.enable then
-  local register=statistics.register
-  register("used platform",function()
-   return format("%s, type: %s, binary subtree: %s",
-    os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
-  end)
-  register("used engine",function()
-   return format("%s version %s with functionality level %s, banner: %s",
-    LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
-  end)
-  register("control sequences",function()
-   return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
-  end)
-  register("callbacks",statistics.callbacks)
-  if TEXENGINE=="luajittex" and JITSUPPORTED then
-   local jitstatus=jit.status
-   if jitstatus then
-    local jitstatus={ jitstatus() }
-    if jitstatus[1] then
-     register("luajit options",concat(jitstatus," ",2))
+  if statistics.enable then
+    local register=statistics.register
+    register("used platform",function()
+      return format("%s, type: %s, binary subtree: %s",
+        os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+    end)
+    register("used engine",function()
+      return format("%s version %s with functionality level %s, banner: %s",
+        LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+    end)
+    register("control sequences",function()
+      return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+    end)
+    register("callbacks",statistics.callbacks)
+    if TEXENGINE=="luajittex" and JITSUPPORTED then
+      local jitstatus=jit.status
+      if jitstatus then
+        local jitstatus={ jitstatus() }
+        if jitstatus[1] then
+          register("luajit options",concat(jitstatus," ",2))
+        end
+      end
     end
-   end
+    register("lua properties",function()
+      local hashchar=tonumber(status.luatex_hashchars)
+      local hashtype=status.luatex_hashtype
+      local mask=lua.mask or "ascii"
+      return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+        jit and "luajit" or "lua",
+        LUAVERSION,
+        statistics.memused(),
+        hashtype or "default",
+        hashchar and 2^hashchar or "unknown",
+        mask,
+        mask=="utf" and "τεχ" or "tex")
+    end)
+    register("runtime",statistics.runtime)
+    logs.newline() 
+    for i=1,#statusinfo do
+      local s=statusinfo[i]
+      local r=s[2]()
+      if r then
+        report("%s: %s",s[1],r)
+      end
+    end
+    statistics.enable=false
   end
-  register("lua properties",function()
-   local hashchar=tonumber(status.luatex_hashchars)
-   local hashtype=status.luatex_hashtype
-   local mask=lua.mask or "ascii"
-   return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
-    jit and "luajit" or "lua",
-    LUAVERSION,
-    statistics.memused(),
-    hashtype or "default",
-    hashchar and 2^hashchar or "unknown",
-    mask,
-    mask=="utf" and "τεχ" or "tex")
-  end)
-  register("runtime",statistics.runtime)
-  logs.newline() 
-  for i=1,#statusinfo do
-   local s=statusinfo[i]
-   local r=s[2]()
-   if r then
-    report("%s: %s",s[1],r)
-   end
-  end
-  statistics.enable=false
- end
 end
 function statistics.memused() 
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+  local round=math.round or math.floor
+  return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
 end
 starttiming(statistics)
 function statistics.formatruntime(runtime) 
- return format("%s seconds",runtime)   
+  return format("%s seconds",runtime)  
 end
 function statistics.runtime()
- stoptiming(statistics)
- local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
- return statistics.formatruntime(runtime)
+  stoptiming(statistics)
+  return statistics.formatruntime(elapsedtime(statistics))
 end
 local report=logs.reporter("system")
-function statistics.timed(action,all)
- starttiming("run")
- action()
- stoptiming("run")
- local runtime=tonumber(elapsedtime("run"))
- if all then
-  local alltime=tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics))
-  if alltime and alltime>0 then
-   report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
-   return
-  end
- end
- report("total runtime: %0.3f seconds",runtime)
+function statistics.timed(action)
+  starttiming("run")
+  action()
+  stoptiming("run")
+  report("total runtime: %s seconds",elapsedtime("run"))
 end
 function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
-  local name=select(i,...)
-  local stat={}
-  local func=base[name]
-  setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
-  base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
-  statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+  for i=1,select("#",...) do
+    local name=select(i,...)
+    local stat={}
+    local func=base[name]
+    setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+    base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+    statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+  end
 end
 
 
@@ -13775,124 +10353,124 @@
 
 package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
 
--- original size: 5841, stripped down to: 3352
+-- original size: 5841, stripped down to: 3511
 
 if not modules then modules={} end modules ['trac-pro']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false  trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
 local report_system=logs.reporter("system","protection")
 namespaces=namespaces or {}
 local namespaces=namespaces
 local registered={}
 local function report_index(k,name)
- if trace_namespaces then
-  report_system("reference to %a in protected namespace %a: %s",k,name)
-  debugger.showtraceback(report_system)
- else
-  report_system("reference to %a in protected namespace %a",k,name)
- end
+  if trace_namespaces then
+    report_system("reference to %a in protected namespace %a: %s",k,name)
+    debugger.showtraceback(report_system)
+  else
+    report_system("reference to %a in protected namespace %a",k,name)
+  end
 end
 local function report_newindex(k,name)
- if trace_namespaces then
-  report_system("assignment to %a in protected namespace %a: %s",k,name)
-  debugger.showtraceback(report_system)
- else
-  report_system("assignment to %a in protected namespace %a",k,name)
- end
+  if trace_namespaces then
+    report_system("assignment to %a in protected namespace %a: %s",k,name)
+    debugger.showtraceback(report_system)
+  else
+    report_system("assignment to %a in protected namespace %a",k,name)
+  end
 end
 local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
-  return 
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
-  m={}
-  setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
-  if not index[k] then
-   index[k]=true
-   report_index(k,name)
+  local data=name=="global" and _G or _G[name]
+  if not data then
+    return 
   end
-  return nil
- end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
-  if not newindex[k] then
-   newindex[k]=true
-   report_newindex(k,name)
+  registered[name]=data
+  local m=getmetatable(data)
+  if not m then
+    m={}
+    setmetatable(data,m)
   end
-  rawset(t,k,v)
- end
- m.__protection__depth=0
+  local index,newindex={},{}
+  m.__saved__index=m.__index
+  m.__no__index=function(t,k)
+    if not index[k] then
+      index[k]=true
+      report_index(k,name)
+    end
+    return nil
+  end
+  m.__saved__newindex=m.__newindex
+  m.__no__newindex=function(t,k,v)
+    if not newindex[k] then
+      newindex[k]=true
+      report_newindex(k,name)
+    end
+    rawset(t,k,v)
+  end
+  m.__protection__depth=0
 end
 local function private(name) 
- local data=registered[name]
- if not data then
-  data=_G[name]
+  local data=registered[name]
   if not data then
-   data={}
-   _G[name]=data
+    data=_G[name]
+    if not data then
+      data={}
+      _G[name]=data
+    end
+    register(name)
   end
-  register(name)
- end
- return data
+  return data
 end
 local function protect(name)
- local data=registered[name]
- if not data then
-  return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
-  m.__protection__depth=pd+1
- else
-  m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
-  m.__index,m.__newindex=m.__no__index,m.__no__newindex
-  m.__protection__depth=1
- end
+  local data=registered[name]
+  if not data then
+    return
+  end
+  local m=getmetatable(data)
+  local pd=m.__protection__depth
+  if pd>0 then
+    m.__protection__depth=pd+1
+  else
+    m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+    m.__index,m.__newindex=m.__no__index,m.__no__newindex
+    m.__protection__depth=1
+  end
 end
 local function unprotect(name)
- local data=registered[name]
- if not data then
-  return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
-  m.__protection__depth=pd-1
- else
-  m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
-  m.__protection__depth=0
- end
+  local data=registered[name]
+  if not data then
+    return
+  end
+  local m=getmetatable(data)
+  local pd=m.__protection__depth
+  if pd>1 then
+    m.__protection__depth=pd-1
+  else
+    m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+    m.__protection__depth=0
+  end
 end
 local function protectall()
- for name,_ in next,registered do
-  if name~="global" then
-   protect(name)
+  for name,_ in next,registered do
+    if name~="global" then
+      protect(name)
+    end
   end
- end
 end
 local function unprotectall()
- for name,_ in next,registered do
-  if name~="global" then
-   unprotect(name)
+  for name,_ in next,registered do
+    if name~="global" then
+      unprotect(name)
+    end
   end
- end
 end
-namespaces.register=register  
-namespaces.private=private   
+namespaces.register=register    
+namespaces.private=private     
 namespaces.protect=protect
 namespaces.unprotect=unprotect
 namespaces.protectall=protectall
@@ -13899,20 +10477,20 @@
 namespaces.unprotectall=unprotectall
 namespaces.private("namespaces") registered={} register("global") 
 directives.register("system.protect",function(v)
- if v then
-  protectall()
- else
-  unprotectall()
- end
+  if v then
+    protectall()
+  else
+    unprotectall()
+  end
 end)
 directives.register("system.checkglobals",function(v)
- if v then
-  report_system("enabling global namespace guard")
-  protect("global")
- else
-  report_system("disabling global namespace guard")
-  unprotect("global")
- end
+  if v then
+    report_system("enabling global namespace guard")
+    protect("global")
+  else
+    report_system("disabling global namespace guard")
+    unprotect("global")
+  end
 end)
 
 
@@ -13922,15 +10500,15 @@
 
 package.loaded["util-lua"] = package.loaded["util-lua"] or true
 
--- original size: 6664, stripped down to: 4589
+-- original size: 6621, stripped down to: 4764
 
 if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  comment="the strip code is written by Peter Cawley",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
 local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -13941,7 +10519,7 @@
 local report_mem=logs.reporter("system","lua memory")
 local tracestripping=false
 local tracememory=false
-luautilities.stripcode=true  
+luautilities.stripcode=true 
 luautilities.alwaysstripcode=false 
 luautilities.nofstrippedchunks=0
 luautilities.nofstrippedbytes=0
@@ -13948,144 +10526,143 @@
 local strippedchunks={} 
 luautilities.strippedchunks=strippedchunks
 luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+  tma="tma",
+  tmc=jit and "tmb" or "tmc",
+  lua="lua",
+  luc=jit and "lub" or "luc",
+  lui="lui",
+  luv="luv",
+  luj="luj",
+  tua="tua",
+  tuc="tuc",
 }
 local function register(name) 
- if tracestripping then
-  report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+  if tracestripping then
+    report_lua("stripped bytecode from %a",name or "unknown")
+  end
+  strippedchunks[#strippedchunks+1]=name
+  luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
 end
 local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
-  code=load(code)
-  if code then
-   code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
-   if code and code~="" then
-    register(name)
-    io.savedata(lucfile,code)
-    return true,0
-   end
+  local code=io.loaddata(luafile)
+  if code and code~="" then
+    code=load(code)
+    if code then
+      code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+      if code and code~="" then
+        register(name)
+        io.savedata(lucfile,code)
+        return true,0
+      end
+    else
+      report_lua("fatal error %a in file %a",1,luafile)
+    end
   else
-   report_lua("fatal error %a in file %a",1,luafile)
+    report_lua("fatal error %a in file %a",2,luafile)
   end
- else
-  report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
+  return false,0
 end
 function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
-  macros=lua.macros
- end
- local code,message
- if macros then
-  code,message=macros.loaded(fullname,true,false)
- else
-  code,message=loadfile(fullname)
- end
- if code then
-  code()
- else
-  report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
-  code,message=loadfile(fullname)
- end
- if forcestrip and luautilities.stripcode then
-  if type(forcestrip)=="function" then
-   forcestrip=forcestrip(fullname)
+  name=name or fullname
+  if macros then
+    macros=lua.macros
   end
-  if forcestrip or luautilities.alwaysstripcode then
-   register(name)
-   return load(dump(code,true)),0
+  local code,message
+  if macros then
+    code,message=macros.loaded(fullname,true,false)
   else
-   return code,0
+    code,message=loadfile(fullname)
   end
- elseif luautilities.alwaysstripcode then
-  register(name)
-  return load(dump(code,true)),0
- else
-  return code,0
- end
+  if code then
+    code()
+  else
+    report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+  end
+  if forcestrip and luautilities.stripcode then
+    if type(forcestrip)=="function" then
+      forcestrip=forcestrip(fullname)
+    end
+    if forcestrip or luautilities.alwaysstripcode then
+      register(name)
+      return load(dump(code,true)),0
+    else
+      return code,0
+    end
+  elseif luautilities.alwaysstripcode then
+    register(name)
+    return load(dump(code,true)),0
+  else
+    return code,0
+  end
 end
 function luautilities.strippedloadstring(code,name,forcestrip) 
- local code,message=load(code)
- if not code then
-  report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
-  register(name)
-  return load(dump(code,true)),0 
- else
-  return code,0
- end
+  local code,message=load(code)
+  if not code then
+    report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+  end
+  if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+    register(name)
+    return load(dump(code,true)),0 
+  else
+    return code,0
+  end
 end
 function luautilities.loadstring(code,name) 
- local code,message=load(code)
- if not code then
-  report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+  local code,message=load(code)
+  if not code then
+    report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+  end
+  return code,0
 end
 function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) 
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
-  report_lua("dumping %a into %a stripped",luafile,lucfile)
-  if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
-   report_lua("removing %a",luafile)
-   os.remove(luafile)
+  report_lua("compiling %a into %a",luafile,lucfile)
+  os.remove(lucfile)
+  local done=stupidcompile(luafile,lucfile,strip~=false)
+  if done then
+    report_lua("dumping %a into %a stripped",luafile,lucfile)
+    if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+      report_lua("removing %a",luafile)
+      os.remove(luafile)
+    end
   end
- end
- return done
+  return done
 end
 function luautilities.loadstripped(...)
- local l=load(...)
- if l then
-  return load(dump(l,true))
- end
+  local l=load(...)
+  if l then
+    return load(dump(l,true))
+  end
 end
 local finalizers={}
 setmetatable(finalizers,{
- __gc=function(t)
-  for i=1,#t do
-   pcall(t[i]) 
+  __gc=function(t)
+    for i=1,#t do
+      pcall(t[i]) 
+    end
   end
- end
 } )
 function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+  finalizers[#finalizers+1]=f
 end
 function luautilities.checkmemory(previous,threshold,trace) 
- local current=collectgarbage("count")
- if previous then
-  local checked=(threshold or 64)*1024
-  local delta=current-previous
-  if current-previous>checked then
-   collectgarbage("collect")
-   local afterwards=collectgarbage("count")
-   if trace or tracememory then
-    report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
-     previous/1024,current/1024,delta/1024,threshold,afterwards)
-   end
-   return afterwards
-  elseif trace or tracememory then
-   report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
-    previous/1024,current/1024,delta/1024,threshold)
+  local current=collectgarbage("count")
+  if previous then
+    local checked=(threshold or 64)*1024
+    local delta=current-previous
+    if current-previous>checked then
+      collectgarbage("collect")
+      local afterwards=collectgarbage("count")
+      if trace or tracememory then
+        report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB, afterwards %i MB",
+          previous/1024,current/1024,delta/1024,threshold,afterwards)
+      end
+      return afterwards
+    elseif trace or tracememory then
+      report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB",
+        previous/1024,current/1024,delta/1024,threshold)
+    end
   end
- end
- return current
+  return current
 end
 
 
@@ -14095,15 +10672,17 @@
 
 package.loaded["util-deb"] = package.loaded["util-deb"] or true
 
--- original size: 9955, stripped down to: 6693
+-- original size: 8984, stripped down to: 6573
 
 if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
+local debug=require "debug"
+local getinfo,sethook=debug.getinfo,debug.sethook
 local type,next,tostring,tonumber=type,next,tostring,tonumber
 local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
 local insert,remove,sort=table.insert,table.remove,table.sort
@@ -14121,38 +10700,38 @@
 local initialize=false
 if not (FFISUPPORTED and ffi) then
 elseif os.type=="windows" then
- initialize=function()
-  local kernel=ffilib("kernel32","system") 
-  if kernel then
-   local tonumber=ffi.number or tonumber
-   ffi.cdef[[
+  initialize=function()
+    local kernel=ffilib("kernel32","system") 
+    if kernel then
+      local tonumber=ffi.number or tonumber
+      ffi.cdef[[
                 int QueryPerformanceFrequency(int64_t *lpFrequency);
                 int QueryPerformanceCounter(int64_t *lpPerformanceCount);
             ]]
-   local target=ffi.new("__int64[1]")
-   ticks=function()
-    if kernel.QueryPerformanceCounter(target)==1 then
-     return tonumber(target[0])
-    else
-     return 0
+      local target=ffi.new("__int64[1]")
+      ticks=function()
+        if kernel.QueryPerformanceCounter(target)==1 then
+          return tonumber(target[0])
+        else
+          return 0
+        end
+      end
+      local target=ffi.new("__int64[1]")
+      seconds=function(ticks)
+        if kernel.QueryPerformanceFrequency(target)==1 then
+          return ticks/tonumber(target[0])
+        else
+          return 0
+        end
+      end
     end
-   end
-   local target=ffi.new("__int64[1]")
-   seconds=function(ticks)
-    if kernel.QueryPerformanceFrequency(target)==1 then
-     return ticks/tonumber(target[0])
-    else
-     return 0
-    end
-   end
+    initialize=false
   end
-  initialize=false
- end
 elseif os.type=="unix" then
- initialize=function()
-  local C=ffi.C
-  local tonumber=ffi.number or tonumber
-  ffi.cdef [[
+  initialize=function()
+    local C=ffi.C
+    local tonumber=ffi.number or tonumber
+    ffi.cdef [[
             /* what a mess */
             typedef int clk_id_t;
             typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
@@ -14159,228 +10738,190 @@
             typedef struct timespec { long sec; long nsec; } ctx_timespec;
             int clock_gettime(clk_id_t timerid, struct timespec *t);
         ]]
-  local target=ffi.new("ctx_timespec[?]",1)
-  local clock=C.CLOCK_PROCESS_CPUTIME_ID
-  ticks=function ()
-   C.clock_gettime(clock,target)
-   return tonumber(target[0].sec*1000000000+target[0].nsec)
+    local target=ffi.new("ctx_timespec[?]",1)
+    local clock=C.CLOCK_PROCESS_CPUTIME_ID
+    ticks=function ()
+      C.clock_gettime(clock,target)
+      return tonumber(target[0].sec*1000000000+target[0].nsec)
+    end
+    seconds=function(ticks)
+      return ticks/1000000000
+    end
+    initialize=false
   end
-  seconds=function(ticks)
-   return ticks/1000000000
-  end
-  initialize=false
- end
 end
 setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
-  local v=setmetatableindex(function(t,line)
-   local v={ total=0,count=0,nesting=0 }
-   t[line]=v
-   return v
+  local v=setmetatableindex(function(t,source)
+    local v=setmetatableindex(function(t,line)
+      local v={ total=0,count=0 }
+      t[line]=v
+      return v
+    end)
+    t[source]=v
+    return v
   end)
-  t[source]=v
+  t[name]=v
   return v
- end)
- t[name]=v
- return v
 end)
-local getinfo=nil
-local sethook=nil
 local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
-  local source=f.short_src
-  if not source then
-   return
-  end
-  local line=f.linedefined or 0
-  local name=f.name
-  if not name then
-   local what=f.what
-   if what=="C" then
-    name="<anonymous>"
-   else
-    name=f.namewhat or what or "<unknown>"
-   end
-  end
-  local data=names[name][source][line]
-  if where=="call" then
-   local nesting=data.nesting
-   if nesting==0 then
-    data.count=data.count+1
-    insert(data,ticks())
-    data.nesting=1
-   else
-    data.nesting=nesting+1
-   end
-  elseif where=="return" then
-   local nesting=data.nesting
-   if nesting==1 then
-    local t=remove(data)
-    if t then
-     data.total=data.total+ticks()-t
+  local f=getinfo(2,"nSl")
+  if f then
+    local source=f.short_src
+    if not source then
+      return
     end
-    data.nesting=0
-   else
-    data.nesting=nesting-1
-   end
+    local line=f.linedefined or 0
+    local name=f.name
+    if not name then
+      local what=f.what
+      if what=="C" then
+        name="<anonymous>"
+      else
+        name=f.namewhat or what or "<unknown>"
+      end
+    end
+    local data=names[name][source][line]
+    if where=="call" then
+      data.count=data.count+1
+      insert(data,ticks())
+    elseif where=="return" then
+      local t=remove(data)
+      if t then
+        data.total=data.total+ticks()-t
+      end
+    end
   end
- end
 end
 function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
-  for source,lines in next,sources do
-   for line,data in next,lines do
-    local count=data.count
-    if count>threshold then
-     if #name>length then
-      length=#name
-     end
-     local total=data.total
-     local real=total
-     if real>0 then
-      real=total-(count*overhead/dummycalls)
-      if real<0 then
-       real=0
+  local printer=printer or report
+  local calls=0
+  local functions=0
+  local dataset={}
+  local length=0
+  local realtime=0
+  local totaltime=0
+  local threshold=threshold or 0
+  for name,sources in next,names do
+    for source,lines in next,sources do
+      for line,data in next,lines do
+        local count=data.count
+        if count>threshold then
+          if #name>length then
+            length=#name
+          end
+          local total=data.total
+          local real=total
+          if real>0 then
+            real=total-(count*overhead/dummycalls)
+            if real<0 then
+              real=0
+            end
+            realtime=realtime+real
+          end
+          totaltime=totaltime+total
+          if line<0 then
+            line=0
+          end
+          dataset[#dataset+1]={ real,total,count,name,source,line }
+        end
       end
-      realtime=realtime+real
-     end
-     totaltime=totaltime+total
-     if line<0 then
-      line=0
-     end
-     dataset[#dataset+1]={ real,total,count,name,source,line }
     end
-   end
   end
- end
- sort(dataset,function(a,b)
-  if a[1]==b[1] then
-   if a[2]==b[2] then
-    if a[3]==b[3] then
-     if a[4]==b[4] then
-      if a[5]==b[5] then
-       return a[6]<b[6]
+  sort(dataset,function(a,b)
+    if a[1]==b[1] then
+      if a[2]==b[2] then
+        if a[3]==b[3] then
+          if a[4]==b[4] then
+            if a[5]==b[5] then
+              return a[6]<b[6]
+            else
+              return a[5]<b[5]
+            end
+          else
+            return a[4]<b[4]
+          end
+        else
+          return b[3]<a[3]
+        end
       else
-       return a[5]<b[5]
+        return b[2]<a[2]
       end
-     else
-      return a[4]<b[4]
-     end
     else
-     return b[3]<a[3]
+      return b[1]<a[1]
     end
-   else
-    return b[2]<a[2]
-   end
-  else
-   return b[1]<a[1]
+  end)
+  if length>50 then
+    length=50
   end
- end)
- if length>50 then
-  length=50
- end
- local fmt=string.formatters["%4.9k s  %3.3k %%  %4.9k s  %3.3k %%  %8i #  %-"..length.."s  %4i  %s"]
- for i=1,#dataset do
-  local data=dataset[i]
-  local real=data[1]
-  local total=data[2]
-  local count=data[3]
-  local name=data[4]
-  local source=data[5]
-  local line=data[6]
-  calls=calls+count
-  functions=functions+1
-  name=gsub(name,"%s+"," ")
-  if #name>length then
-   name=sub(name,1,length)
+  local fmt=string.formatters["%4.9k s  %3.3k %%  %4.9k s  %3.3k %%  %8i #  %-"..length.."s  %4i  %s"]
+  for i=1,#dataset do
+    local data=dataset[i]
+    local real=data[1]
+    local total=data[2]
+    local count=data[3]
+    local name=data[4]
+    local source=data[5]
+    local line=data[6]
+    calls=calls+count
+    functions=functions+1
+    name=gsub(name,"%s+"," ")
+    if #name>length then
+      name=sub(name,1,length)
+    end
+    printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
   end
-  printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls     : %i",calls))
- printer(format("overhead  : %f",seconds(overhead/1000)))
+  printer("")
+  printer(format("functions : %i",functions))
+  printer(format("calls     : %i",calls))
+  printer(format("overhead  : %f",seconds(overhead/1000)))
 end
-local function getdebug()
- if sethook and getinfo then
-  return
- end
- if not debug then
-  local okay
-  okay,debug=pcall(require,"debug")
- end
- if type(debug)~="table" then
-  return
- end
- getinfo=debug.getinfo
- sethook=debug.sethook
- if type(getinfo)~="function" then
-  getinfo=nil
- end
- if type(sethook)~="function" then
-  sethook=nil
- end
-end
 function debugger.savestats(filename,threshold)
- local f=io.open(filename,'w')
- if f then
-  debugger.showstats(function(str) f:write(str,"\n") end,threshold)
-  f:close()
- end
+  local f=io.open(filename,'w')
+  if f then
+    debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+    f:close()
+  end
 end
 function debugger.enable()
- getdebug()
- if sethook and getinfo and nesting==0 then
-  running=true
-  if initialize then
-   initialize()
+  if nesting==0 then
+    running=true
+    if initialize then
+      initialize()
+    end
+    sethook(hook,"cr")
+    local function dummy() end
+    local t=ticks()
+    for i=1,dummycalls do
+      dummy()
+    end
+    overhead=ticks()-t
   end
-  sethook(hook,"cr")
-  local function dummy() end
-  local t=ticks()
-  for i=1,dummycalls do
-   dummy()
+  if nesting>0 then
+    nesting=nesting+1
   end
-  overhead=ticks()-t
- end
- if nesting>0 then
-  nesting=nesting+1
- end
 end
 function debugger.disable()
- if nesting>0 then
-  nesting=nesting-1
- end
- if sethook and getinfo and nesting==0 then
-  sethook()
- end
+  if nesting>0 then
+    nesting=nesting-1
+  end
+  if nesting==0 then
+    sethook()
+  end
 end
 local function showtraceback(rep) 
- getdebug()
- if getinfo then
   local level=2 
   local reporter=rep or report
   while true do
-   local info=getinfo(level,"Sl")
-   if not info then
-    break
-   elseif info.what=="C" then
-    reporter("%2i : %s",level-1,"C function")
-   else
-    reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
-   end
-   level=level+1
+    local info=getinfo(level,"Sl")
+    if not info then
+      break
+    elseif info.what=="C" then
+      reporter("%2i : %s",level-1,"C function")
+    else
+      reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+    end
+    level=level+1
   end
- end
 end
 debugger.showtraceback=showtraceback
 
@@ -14391,18 +10932,18 @@
 
 package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
 
--- original size: 7112, stripped down to: 3887
+-- original size: 7112, stripped down to: 3988
 
 if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 utilities.templates=utilities.templates or {}
 local templates=utilities.templates
-local trace_template=false  trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
 local report_template=logs.reporter("template")
 local tostring,next=tostring,next
 local format,sub,byte=string.format,string.sub,string.byte
@@ -14409,29 +10950,29 @@
 local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
 local replacer
 local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
-  if trace_template then
-   report_template("unknown key %a",k)
-  end
-  return ""
- else
-  v=tostring(v)
-  if trace_template then
-   report_template("setting key %a to value %a",k,v)
-  end
-  if recursive then
-   return lpegmatch(replacer,v,1,t,how,recursive)
+  local v=t[k]
+  if not v then
+    if trace_template then
+      report_template("unknown key %a",k)
+    end
+    return ""
   else
-   return v
+    v=tostring(v)
+    if trace_template then
+      report_template("setting key %a to value %a",k,v)
+    end
+    if recursive then
+      return lpegmatch(replacer,v,1,t,how,recursive)
+    else
+      return v
+    end
   end
- end
 end
 local sqlescape=lpeg.replacer {
- { "'","''"   },
- { "\\","\\\\" },
- { "\r\n","\\n"  },
- { "\r","\\n"  },
+  { "'","''"  },
+  { "\\","\\\\" },
+  { "\r\n","\\n" },
+  { "\r","\\n" },
 }
 local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
 lpegpatterns.sqlescape=sqlescape
@@ -14438,44 +10979,44 @@
 lpegpatterns.sqlquoted=sqlquoted
 local luaescape=lpegpatterns.luaescape
 local escapers={
- lua=function(s)
-  return lpegmatch(luaescape,s)
- end,
- sql=function(s)
-  return lpegmatch(sqlescape,s)
- end,
+  lua=function(s)
+    return lpegmatch(luaescape,s)
+  end,
+  sql=function(s)
+    return lpegmatch(sqlescape,s)
+  end,
 }
 local quotedescapers={
- lua=function(s)
-  return format("%q",s)
- end,
- sql=function(s)
-  return lpegmatch(sqlquoted,s)
- end,
+  lua=function(s)
+    return format("%q",s)
+  end,
+  sql=function(s)
+    return lpegmatch(sqlquoted,s)
+  end,
 }
 local luaescaper=escapers.lua
 local quotedluaescaper=quotedescapers.lua
 local function replacekeyunquoted(s,t,how,recurse) 
- if how==false then
-  return replacekey(s,t,how,recurse)
- else
-  local escaper=how and escapers[how] or luaescaper
-  return escaper(replacekey(s,t,how,recurse))
- end
+  if how==false then
+    return replacekey(s,t,how,recurse)
+  else
+    local escaper=how and escapers[how] or luaescaper
+    return escaper(replacekey(s,t,how,recurse))
+  end
 end
 local function replacekeyquoted(s,t,how,recurse) 
- if how==false then
-  return replacekey(s,t,how,recurse)
- else
-  local escaper=how and quotedescapers[how] or quotedluaescaper
-  return escaper(replacekey(s,t,how,recurse))
- end
+  if how==false then
+    return replacekey(s,t,how,recurse)
+  else
+    local escaper=how and quotedescapers[how] or quotedluaescaper
+    return escaper(replacekey(s,t,how,recurse))
+  end
 end
 local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+  local v=t[l]
+  return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
 end
-local single=P("%")  
+local single=P("%") 
 local double=P("%%") 
 local lquoted=P("%[") 
 local rquoted=P("]%") 
@@ -14492,41 +11033,41 @@
 local noroptional=P("?%")/''
 local nomoptional=P(":")/''
 local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle   )^1)*args)/replacekey  )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted  )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted  )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle  )^1)*args)/replacekey    )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
 local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
 local any=P(1)
    replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
 local function replace(str,mapping,how,recurse)
- if mapping and str then
-  return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
-  return str
- end
+  if mapping and str then
+    return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+  else
+    return str
+  end
 end
 templates.replace=replace
 function templates.replacer(str,how,recurse) 
- return function(mapping)
-  return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+  return function(mapping)
+    return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+  end
 end
 function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
-  return replace(data,mapping,how,recurse)
- else
-  return data
- end
+  local data=io.loaddata(filename) or ""
+  if mapping and next(mapping) then
+    return replace(data,mapping,how,recurse)
+  else
+    return data
+  end
 end
 function templates.resolve(t,mapping,how,recurse)
- if not mapping then
-  mapping=t
- end
- for k,v in next,t do
-  t[k]=replace(v,mapping,how,recurse)
- end
- return t
+  if not mapping then
+    mapping=t
+  end
+  for k,v in next,t do
+    t[k]=replace(v,mapping,how,recurse)
+  end
+  return t
 end
 
 
@@ -14536,14 +11077,14 @@
 
 package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
 
--- original size: 20393, stripped down to: 13121
+-- original size: 20393, stripped down to: 13924
 
 if not modules then modules={} end modules ['util-sbx']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 if not sandbox then require("l-sandbox") end 
 local next,type=next,type
@@ -14576,144 +11117,144 @@
 trackers.register("sandbox",function(v) trace=v end) 
 sandbox.setreporter(report)
 sandbox.finalizer {
- category="files",
- action=function()
-  finalized=true
- end
+  category="files",
+  action=function()
+    finalized=true
+  end
 }
 local function registerroot(root,what) 
- if finalized then
-  report("roots are already finalized")
- else
-  if type(root)=="table" then
-   root,what=root[1],root[2]
+  if finalized then
+    report("roots are already finalized")
+  else
+    if type(root)=="table" then
+      root,what=root[1],root[2]
+    end
+    if type(root)=="string" and root~="" then
+      root=collapsepath(expandname(root))
+      if what=="r" or what=="ro" or what=="readable" then
+        what="read"
+      elseif what=="w" or what=="wo" or what=="writable" then
+        what="write"
+      end
+      validroots[root]=what=="write" or false
+    end
   end
-  if type(root)=="string" and root~="" then
-   root=collapsepath(expandname(root))
-   if what=="r" or what=="ro" or what=="readable" then
-    what="read"
-   elseif what=="w" or what=="wo" or what=="writable" then
-    what="write"
-   end
-   validroots[root]=what=="write" or false
-  end
- end
 end
 sandbox.finalizer {
- category="files",
- action=function() 
-  if p_validroot then
-   report("roots are already initialized")
-  else
-   sandbox.registerroot(".","write")
-   for name in sortedhash(validroots) do
+  category="files",
+  action=function() 
     if p_validroot then
-     p_validroot=P(name)+p_validroot
+      report("roots are already initialized")
     else
-     p_validroot=P(name)
+      sandbox.registerroot(".","write")
+      for name in sortedhash(validroots) do
+        if p_validroot then
+          p_validroot=P(name)+p_validroot
+        else
+          p_validroot=P(name)
+        end
+      end
+      p_validroot=p_validroot/validroots
     end
-   end
-   p_validroot=p_validroot/validroots
   end
- end
 }
 local function registerbinary(name)
- if finalized then
-  report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
-  if not validbinaries then
-   return
+  if finalized then
+    report("binaries are already finalized")
+  elseif type(name)=="string" and name~="" then
+    if not validbinaries then
+      return
+    end
+    if validbinaries==true then
+      validbinaries={ [name]=true }
+    else
+      validbinaries[name]=true
+    end
+  elseif name==true then
+    validbinaries={}
   end
-  if validbinaries==true then
-   validbinaries={ [name]=true }
-  else
-   validbinaries[name]=true
-  end
- elseif name==true then
-  validbinaries={}
- end
 end
 local function registerlibrary(name)
- if finalized then
-  report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
-  if not validlibraries then
-   return
+  if finalized then
+    report("libraries are already finalized")
+  elseif type(name)=="string" and name~="" then
+    if not validlibraries then
+      return
+    end
+    if validlibraries==true then
+      validlibraries={ [nameonly(name)]=true }
+    else
+      validlibraries[nameonly(name)]=true
+    end
+  elseif name==true then
+    validlibraries={}
   end
-  if validlibraries==true then
-   validlibraries={ [nameonly(name)]=true }
-  else
-   validlibraries[nameonly(name)]=true
-  end
- elseif name==true then
-  validlibraries={}
- end
 end
 local p_write=S("wa")    p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:")  p_path=(1-p_path )^0*p_path  
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path 
 local function normalized(name) 
- if platform=="windows" then
-  name=gsub(name,"/","\\")
- end
- return name
+  if platform=="windows" then
+    name=gsub(name,"/","\\")
+  end
+  return name
 end
 function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+  return lpegmatch(p_path,name) and true or false
 end
 local filenamelogger=false
 function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+  filenamelogger=type(l)=="function" and l or false
 end
 local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
-  local asked=collapsepath(expandname(name))
-  local okay=lpegmatch(p_validroot,asked)
-  if okay==true then
-   if filenamelogger then
-    filenamelogger(name,"w",asked,true)
-   end
-   return name
-  elseif okay==false then
-   if not what then
-    if filenamelogger then
-     filenamelogger(name,"r",asked,true)
+  if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+    local asked=collapsepath(expandname(name))
+    local okay=lpegmatch(p_validroot,asked)
+    if okay==true then
+      if filenamelogger then
+        filenamelogger(name,"w",asked,true)
+      end
+      return name
+    elseif okay==false then
+      if not what then
+        if filenamelogger then
+          filenamelogger(name,"r",asked,true)
+        end
+        return name
+      elseif lpegmatch(p_write,what) then
+        if filenamelogger then
+          filenamelogger(name,"w",asked,false)
+        end
+        return 
+      else
+        if filenamelogger then
+          filenamelogger(name,"r",asked,true)
+        end
+        return name
+      end
+    elseif filenamelogger then
+      filenamelogger(name,"*",name,false)
     end
+  else
     return name
-   elseif lpegmatch(p_write,what) then
-    if filenamelogger then
-     filenamelogger(name,"w",asked,false)
-    end
-    return 
-   else
-    if filenamelogger then
-     filenamelogger(name,"r",asked,true)
-    end
-    return name
-   end
-  elseif filenamelogger then
-   filenamelogger(name,"*",name,false)
   end
- else
-  return name
- end
 end
 local function readable(name,finalized)
- return validfilename(name,"r")
+  return validfilename(name,"r")
 end
 local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
-  return normalized(valid)
- end
+  local valid=validfilename(name,"r")
+  if valid then
+    return normalized(valid)
+  end
 end
 local function writeable(name,finalized)
- return validfilename(name,"w")
+  return validfilename(name,"w")
 end
 local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
-  return normalized(valid)
- end
+  local valid=validfilename(name,"w")
+  if valid then
+    return normalized(valid)
+  end
 end
 validators.readable=readable
 validators.writeable=normalizedwriteable
@@ -14721,316 +11262,316 @@
 validators.normalizedwriteable=writeable
 validators.filename=readable
 table.setmetatableindex(validators,function(t,k)
- if k then
-  t[k]=readable
- end
- return readable
+  if k then
+    t[k]=readable
+  end
+  return readable
 end)
 function validators.string(s,finalized)
- if finalized and suspicious(s) then
-  return ""
- else
-  return s
- end
+  if finalized and suspicious(s) then
+    return ""
+  else
+    return s
+  end
 end
 function validators.cache(s)
- if finalized then
-  return basename(s)
- else
-  return s
- end
+  if finalized then
+    return basename(s)
+  else
+    return s
+  end
 end
 function validators.url(s)
- if finalized and find("^file:") then
-  return ""
- else
-  return s
- end
+  if finalized and find("^file:") then
+    return ""
+  else
+    return s
+  end
 end
 local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
-  return action(one,...)
- else
- end
+  local checkedone=validfilename(one)
+  if checkedone then
+    return action(one,...)
+  else
+  end
 end
 local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
-  local checkedtwo=validfilename(two)
-  if checkedtwo then
-   return action(one,two,...)
+  local checkedone=validfilename(one)
+  if checkedone then
+    local checkedtwo=validfilename(two)
+    if checkedtwo then
+      return action(one,two,...)
+    else
+    end
   else
   end
- else
- end
 end
 local function iohandler(action,one,...)
- if type(one)=="string" then
-  local checkedone=validfilename(one)
-  if checkedone then
-   return action(one,...)
+  if type(one)=="string" then
+    local checkedone=validfilename(one)
+    if checkedone then
+      return action(one,...)
+    end
+  elseif one then
+    return action(one,...)
+  else
+    return action()
   end
- elseif one then
-  return action(one,...)
- else
-  return action()
- end
 end
 local osexecute=sandbox.original(os.execute)
 local iopopen=sandbox.original(io.popen)
 local reported={}
 local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
-  if variables then
-   for variable,value in next,variables do
-    local checker=validators[checkers[variable]]
-    if checker then
-     value=checker(unquoted(value),strict)
-     if value then
-      variables[variable]=optionalquoted(value)
-     else
-      report("variable %a with value %a fails the check",variable,value)
-      return
-     end
-    else
-     report("variable %a has no checker",variable)
-     return
-    end
-   end
-   for variable,default in next,defaults do
-    local value=variables[variable]
-    if not value or value=="" then
-     local checker=validators[checkers[variable]]
-     if checker then
-      default=checker(unquoted(default),strict)
-      if default then
-       variables[variable]=optionalquoted(default)
-      else
-       report("variable %a with default %a fails the check",variable,default)
-       return
+  if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+    if variables then
+      for variable,value in next,variables do
+        local checker=validators[checkers[variable]]
+        if checker then
+          value=checker(unquoted(value),strict)
+          if value then
+            variables[variable]=optionalquoted(value)
+          else
+            report("variable %a with value %a fails the check",variable,value)
+            return
+          end
+        else
+          report("variable %a has no checker",variable)
+          return
+        end
       end
-     end
+      for variable,default in next,defaults do
+        local value=variables[variable]
+        if not value or value=="" then
+          local checker=validators[checkers[variable]]
+          if checker then
+            default=checker(unquoted(default),strict)
+            if default then
+              variables[variable]=optionalquoted(default)
+            else
+              report("variable %a with default %a fails the check",variable,default)
+              return
+            end
+          end
+        end
+      end
     end
-   end
+    local command=program.." "..replace(template,variables)
+    if reporter then
+      reporter("executing runner %a: %s",name,command)
+    elseif trace then
+      report("executing runner %a: %s",name,command)
+    end
+    return command
+  elseif not reported[name] then
+    report("executing program %a of runner %a is not permitted",program,name)
+    reported[name]=true
   end
-  local command=program.." "..replace(template,variables)
-  if reporter then
-   reporter("executing runner %a: %s",name,command)
-  elseif trace then
-   report("executing runner %a: %s",name,command)
-  end
-  return command
- elseif not reported[name] then
-  report("executing program %a of runner %a is not permitted",program,name)
-  reported[name]=true
- end
 end
 local runners={
- resultof=function(...)
-  local command=validcommand(...)
-  if command then
-   if trace then
-    report("resultof: %s",command)
-   end
-   local handle=iopopen(command,"r") 
-   if handle then
-    local result=handle:read("*all") or ""
-    handle:close()
-    return result
-   end
+  resultof=function(...)
+    local command=validcommand(...)
+    if command then
+      if trace then
+        report("resultof: %s",command)
+      end
+      local handle=iopopen(command,"r") 
+      if handle then
+        local result=handle:read("*all") or ""
+        handle:close()
+        return result
+      end
+    end
+  end,
+  execute=function(...)
+    local command=validcommand(...)
+    if command then
+      if trace then
+        report("execute: %s",command)
+      end
+      return osexecute(command)
+    end
+  end,
+  pipeto=function(...)
+    local command=validcommand(...)
+    if command then
+      if trace then
+        report("pipeto: %s",command)
+      end
+      return iopopen(command,"w") 
+    end
+  end,
+}
+function sandbox.registerrunner(specification)
+  if type(specification)=="string" then
+    local wrapped=validrunners[specification]
+    inspect(table.sortedkeys(validrunners))
+    if wrapped then
+      return wrapped
+    else
+      report("unknown predefined runner %a",specification)
+      return
+    end
   end
- end,
- execute=function(...)
-  local command=validcommand(...)
-  if command then
-   if trace then
-    report("execute: %s",command)
-   end
-   return osexecute(command)
+  if type(specification)~="table" then
+    report("specification should be a table (or string)")
+    return
   end
- end,
- pipeto=function(...)
-  local command=validcommand(...)
-  if command then
-   if trace then
-    report("pipeto: %s",command)
-   end
-   return iopopen(command,"w") 
+  local name=specification.name
+  if type(name)~="string" then
+    report("invalid name, string expected",name)
+    return
   end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
-  local wrapped=validrunners[specification]
-  inspect(table.sortedkeys(validrunners))
-  if wrapped then
-   return wrapped
+  if validrunners[name] then
+    report("invalid name, runner %a already defined")
+    return
+  end
+  local program=specification.program
+  if type(program)=="string" then
+  elseif type(program)=="table" then
+    program=program[platform] or program.default or program.unix
+  end
+  if type(program)~="string" or program=="" then
+    report("invalid runner %a specified for platform %a",name,platform)
+    return
+  end
+  local template=specification.template
+  if not template then
+    report("missing template for runner %a",name)
+    return
+  end
+  local method=specification.method  or "execute"
+  local checkers=specification.checkers or {}
+  local defaults=specification.defaults or {}
+  local runner=runners[method]
+  if runner then
+    local finalized=finalized 
+    local wrapped=function(variables)
+      return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+    end
+    validrunners[name]=wrapped
+    return wrapped
   else
-   report("unknown predefined runner %a",specification)
-   return
+    validrunners[name]=nil
+    report("invalid method for runner %a",name)
   end
- end
- if type(specification)~="table" then
-  report("specification should be a table (or string)")
-  return
- end
- local name=specification.name
- if type(name)~="string" then
-  report("invalid name, string expected",name)
-  return
- end
- if validrunners[name] then
-  report("invalid name, runner %a already defined")
-  return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
-  program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
-  report("invalid runner %a specified for platform %a",name,platform)
-  return
- end
- local template=specification.template
- if not template then
-  report("missing template for runner %a",name)
-  return
- end
- local method=specification.method   or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
-  local finalized=finalized 
-  local wrapped=function(variables)
-   return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
-  end
-  validrunners[name]=wrapped
-  return wrapped
- else
-  validrunners[name]=nil
-  report("invalid method for runner %a",name)
- end
 end
 function sandbox.getrunner(name)
- return name and validrunners[name]
+  return name and validrunners[name]
 end
 local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+  return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
 end
 local function binaryrunner(action,command,...)
- if validbinaries==false then
-  report("no binaries permitted, ignoring command: %s",command)
-  return
- end
- if type(command)~="string" then
-  report("command should be a string")
-  return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
-  report("unable to filter binary from command: %s",command)
-  return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
-  report("binary not permitted, ignoring command: %s",command)
-  return
- elseif suspicious(command) then
-  report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
-  return
- end
- return action(command,...)
+  if validbinaries==false then
+    report("no binaries permitted, ignoring command: %s",command)
+    return
+  end
+  if type(command)~="string" then
+    report("command should be a string")
+    return
+  end
+  local program=lpegmatch(p_split,command)
+  if not program or program=="" then
+    report("unable to filter binary from command: %s",command)
+    return
+  end
+  if validbinaries==true then
+  elseif not validbinaries[program] then
+    report("binary not permitted, ignoring command: %s",command)
+    return
+  elseif suspicious(command) then
+    report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+    return
+  end
+  return action(command,...)
 end
 local function dummyrunner(action,command,...)
- if type(command)=="table" then
-  command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+  if type(command)=="table" then
+    command=concat(command," ",command[0] and 0 or 1)
+  end
+  report("ignoring command: %s",command)
 end
 sandbox.filehandlerone=filehandlerone
 sandbox.filehandlertwo=filehandlertwo
 sandbox.iohandler=iohandler
 function sandbox.disablerunners()
- validbinaries=false
+  validbinaries=false
 end
 function sandbox.disablelibraries()
- validlibraries=false
+  validlibraries=false
 end
 if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
-  validlibraries=false
-  for k,v in next,ffi do
-   if k~="gc" then
-    ffi[k]=nil
-   end
+  function sandbox.disablelibraries()
+    validlibraries=false
+    for k,v in next,ffi do
+      if k~="gc" then
+        ffi[k]=nil
+      end
+    end
   end
- end
- local fiiload=ffi.load
- if fiiload then
-  local reported={}
-  function ffi.load(name,...)
-   if validlibraries==false then
-   elseif validlibraries==true then
-    return fiiload(name,...)
-   elseif validlibraries[nameonly(name)] then
-    return fiiload(name,...)
-   else
-   end
-   if not reported[name] then
-    report("using library %a is not permitted",name)
-    reported[name]=true
-   end
-   return nil
+  local fiiload=ffi.load
+  if fiiload then
+    local reported={}
+    function ffi.load(name,...)
+      if validlibraries==false then
+      elseif validlibraries==true then
+        return fiiload(name,...)
+      elseif validlibraries[nameonly(name)] then
+        return fiiload(name,...)
+      else
+      end
+      if not reported[name] then
+        report("using library %a is not permitted",name)
+        reported[name]=true
+      end
+      return nil
+    end
   end
- end
 end
 local overload=sandbox.overload
 local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile") 
+  overload(loadfile,filehandlerone,"loadfile") 
 if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+  overload(io.open,filehandlerone,"io.open")
+  overload(io.popen,binaryrunner,"io.popen")
+  overload(io.input,iohandler,"io.input")
+  overload(io.output,iohandler,"io.output")
+  overload(io.lines,filehandlerone,"io.lines")
 end
 if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+  overload(os.execute,binaryrunner,"os.execute")
+  overload(os.spawn,dummyrunner,"os.spawn")
+  overload(os.exec,dummyrunner,"os.exec")
+  overload(os.resultof,binaryrunner,"os.resultof")
+  overload(os.pipeto,binaryrunner,"os.pipeto")
+  overload(os.rename,filehandlertwo,"os.rename")
+  overload(os.remove,filehandlerone,"os.remove")
 end
 if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+  overload(lfs.chdir,filehandlerone,"lfs.chdir")
+  overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+  overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+  overload(lfs.isfile,filehandlerone,"lfs.isfile")
+  overload(lfs.isdir,filehandlerone,"lfs.isdir")
+  overload(lfs.attributes,filehandlerone,"lfs.attributes")
+  overload(lfs.dir,filehandlerone,"lfs.dir")
+  overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+  overload(lfs.touch,filehandlerone,"lfs.touch")
+  overload(lfs.link,filehandlertwo,"lfs.link")
+  overload(lfs.setmode,filehandlerone,"lfs.setmode")
+  overload(lfs.readlink,filehandlerone,"lfs.readlink")
+  overload(lfs.shortname,filehandlerone,"lfs.shortname")
+  overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
 end
 if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+  zip.open=register(zip.open,filehandlerone,"zip.open")
 end
 if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+  fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+  fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
 end
 if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+  epdf.open=register(epdf.open,filehandlerone,"epdf.open")
 end
 sandbox.registerroot=registerroot
 sandbox.registerbinary=registerbinary
@@ -15044,14 +11585,14 @@
 
 package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
 
--- original size: 7819, stripped down to: 5881
+-- original size: 7757, stripped down to: 6015
 
 if not modules then modules={} end modules ['util-mrg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local gsub,format=string.gsub,string.format
 local concat=table.concat
@@ -15079,19 +11620,19 @@
 ]]
 local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
 local function self_fake()
- return m_faked
+  return m_faked
 end
 local function self_nothing()
- return ""
+  return ""
 end
 local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
-  report("unknown file %a",name)
- else
-  report("inserting file %a",name)
- end
- return data or ""
+  local data=io.loaddata(name) or ""
+  if data=="" then
+    report("unknown file %a",name)
+  else
+    report("inserting file %a",name)
+  end
+  return data or ""
 end
 local space=patterns.space
 local eol=patterns.newline
@@ -15120,99 +11661,98 @@
 local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
 local lines=emptyline^2/"\n"
 local spaces=(space*space)/" "
-local spaces=(space*space*space*space)/" "
 local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+  ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
 )^1 )
 local strip=Cs((emptyline^2/"\n"+1)^0)
 local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
 function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+  return lpegmatch(strip,lpegmatch(compact,data))
 end
 local function self_compact(data)
- local delta=0
- if merger.strip_comment then
-  local before=#data
-  data=lpegmatch(compact,data)
-  data=lpegmatch(strip,data)
-  local after=#data
-  delta=before-after
-  report("original size %s, compacted to %s, stripped %s",before,after,delta)
-  data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+  local delta=0
+  if merger.strip_comment then
+    local before=#data
+    data=lpegmatch(compact,data)
+    data=lpegmatch(strip,data)
+    local after=#data
+    delta=before-after
+    report("original size %s, compacted to %s, stripped %s",before,after,delta)
+    data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+  end
+  return lpegmatch(stripreturn,data) or data,delta
 end
 local function self_save(name,data)
- if data~="" then
-  io.savedata(name,data)
-  report("saving %s with size %s",name,#data)
- end
+  if data~="" then
+    io.savedata(name,data)
+    report("saving %s with size %s",name,#data)
+  end
 end
 local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+  return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
 end
 local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
- for i=1,#libs do
-  local lib=libs[i]
-  for j=1,#list do
-   local pth=gsub(list[j],"\\","/") 
-   report("checking library path %a",pth)
-   local name=pth.."/"..lib
-   if lfs.isfile(name) then
-    foundpath=pth
-   end
-  end
-  if foundpath then break end
- end
- if foundpath then
-  report("using library path %a",foundpath)
-  local right,wrong,original,stripped={},{},0,0
+  local result,f,frozen,foundpath={},nil,false,nil
+  result[#result+1]="\n"
+  if type(libs)=='string' then libs={ libs } end
+  if type(list)=='string' then list={ list } end
   for i=1,#libs do
-   local lib=libs[i]
-   local fullname=foundpath.."/"..lib
-   if lfs.isfile(fullname) then
-    report("using library %a",fullname)
-    local preloaded=file.nameonly(lib)
-    local data=io.loaddata(fullname,true)
-    original=original+#data
-    local data,delta=self_compact(data)
-    right[#right+1]=lib
-    result[#result+1]=m_begin_closure
-    result[#result+1]=format(m_preloaded,preloaded,preloaded)
-    result[#result+1]=data
-    result[#result+1]=m_end_closure
-    stripped=stripped+delta
-   else
-    report("skipping library %a",fullname)
-    wrong[#wrong+1]=lib
-   end
+    local lib=libs[i]
+    for j=1,#list do
+      local pth=gsub(list[j],"\\","/") 
+      report("checking library path %a",pth)
+      local name=pth.."/"..lib
+      if lfs.isfile(name) then
+        foundpath=pth
+      end
+    end
+    if foundpath then break end
   end
-  right=#right>0 and concat(right," ") or "-"
-  wrong=#wrong>0 and concat(wrong," ") or "-"
-  report("used libraries: %a",right)
-  report("skipped libraries: %a",wrong)
-  report("original bytes: %a",original)
-  report("stripped bytes: %a",stripped)
-  result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
-  report("no valid library path found")
- end
- return concat(result,"\n\n")
+  if foundpath then
+    report("using library path %a",foundpath)
+    local right,wrong,original,stripped={},{},0,0
+    for i=1,#libs do
+      local lib=libs[i]
+      local fullname=foundpath.."/"..lib
+      if lfs.isfile(fullname) then
+        report("using library %a",fullname)
+        local preloaded=file.nameonly(lib)
+        local data=io.loaddata(fullname,true)
+        original=original+#data
+        local data,delta=self_compact(data)
+        right[#right+1]=lib
+        result[#result+1]=m_begin_closure
+        result[#result+1]=format(m_preloaded,preloaded,preloaded)
+        result[#result+1]=data
+        result[#result+1]=m_end_closure
+        stripped=stripped+delta
+      else
+        report("skipping library %a",fullname)
+        wrong[#wrong+1]=lib
+      end
+    end
+    right=#right>0 and concat(right," ") or "-"
+    wrong=#wrong>0 and concat(wrong," ") or "-"
+    report("used libraries: %a",right)
+    report("skipped libraries: %a",wrong)
+    report("original bytes: %a",original)
+    report("stripped bytes: %a",stripped)
+    result[#result+1]=format(m_report,right,wrong,original,stripped)
+  else
+    report("no valid library path found")
+  end
+  return concat(result,"\n\n")
 end
 function merger.selfcreate(libs,list,target)
- if target then
-  self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+  if target then
+    self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+  end
 end
 function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+  self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
 end
 function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+  self_save(name,self_swap(self_load(name),self_nothing()))
 end
 
 
@@ -15222,14 +11762,14 @@
 
 package.loaded["util-env"] = package.loaded["util-env"] or true
 
--- original size: 9738, stripped down to: 5531
+-- original size: 9400, stripped down to: 5499
 
 if not modules then modules={} end modules ['util-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local allocate,mark=utilities.storage.allocate,utilities.storage.mark
 local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -15241,193 +11781,178 @@
 setlocale(nil,nil)
 local report=logs.reporter("system")
 function os.setlocale(a,b)
- if a or b then
-  if report then
-   report()
-   report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
-   report("now on are on your own and without support. Crashes or unexpected side effects")
-   report("can happen but don't bother the luatex and context developer team with it.")
-   report()
-   report=nil
+  if a or b then
+    if report then
+      report()
+      report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+      report("now on are on your own and without support. Crashes or unexpected side effects")
+      report("can happen but don't bother the luatex and context developer team with it.")
+      report()
+      report=nil
+    end
+    setlocale(a,b)
   end
-  setlocale(a,b)
- end
 end
 local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+  ["luatex"]=true,
+  ["luajittex"]=true,
 }
 local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+  ["luatex"]="luatex",
+  ["texlua"]="luatex",
+  ["texluac"]="luatex",
+  ["luajittex"]="luajittex",
+  ["texluajit"]="luajittex",
 }
 local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+  ["lua"]=true,
+  ["luajit"]=true,
 }
 environment.validengines=validengines
 environment.basicengines=basicengines
 if not arg then
- environment.used_as_library=true
+  environment.used_as_library=true
 elseif luaengines[file.removesuffix(arg[-1])] then
 elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
-  arg[-1]=arg[0]
-  arg[ 0]=arg[2]
-  for k=3,#arg do
-   arg[k-2]=arg[k]
+  if arg[1]=="--luaonly" then
+    arg[-1]=arg[0]
+    arg[ 0]=arg[2]
+    for k=3,#arg do
+      arg[k-2]=arg[k]
+    end
+    remove(arg) 
+    remove(arg) 
+  else
   end
-  remove(arg) 
-  remove(arg) 
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+  local originalzero=file.basename(arg[0])
+  local specialmapping={ luatools=="base" }
+  if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
     arg[0]=specialmapping[originalzero] or originalzero
     insert(arg,0,"--script")
     insert(arg,0,"mtxrun")
- end
+  end
 end
 environment.arguments=allocate()
 environment.files=allocate()
 environment.sortedflags=nil
 function environment.initializearguments(arg)
- local arguments={}
- local files={}
- environment.arguments=arguments
- environment.files=files
- environment.sortedflags=nil
- for index=1,#arg do
-  local argument=arg[index]
-  if index>0 then
-   local flag,value=match(argument,"^%-+(.-)=(.-)$")
-   if flag then
-    flag=gsub(flag,"^c:","")
-    arguments[flag]=unquoted(value or "")
-   else
-    flag=match(argument,"^%-+(.+)")
-    if flag then
-     flag=gsub(flag,"^c:","")
-     arguments[flag]=true
-    else
-     files[#files+1]=argument
+  local arguments,files={},{}
+  environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
+  for index=1,#arg do
+    local argument=arg[index]
+    if index>0 then
+      local flag,value=match(argument,"^%-+(.-)=(.-)$")
+      if flag then
+        flag=gsub(flag,"^c:","")
+        arguments[flag]=unquoted(value or "")
+      else
+        flag=match(argument,"^%-+(.+)")
+        if flag then
+          flag=gsub(flag,"^c:","")
+          arguments[flag]=true
+        else
+          files[#files+1]=argument
+        end
+      end
     end
-   end
   end
- end
- if not environment.ownname then
-  if os.selfpath and os.selfname then
-   environment.ownname=file.addsuffix(file.join(os.selfpath,os.selfname),"lua")
-  end
- end
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+  environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
 end
 function environment.setargument(name,value)
- environment.arguments[name]=value
+  environment.arguments[name]=value
 end
 function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
-  return arguments[name]
- elseif partial then
-  if not sortedflags then
-   sortedflags=allocate(table.sortedkeys(arguments))
-   for k=1,#sortedflags do
-    sortedflags[k]="^"..sortedflags[k]
-   end
-   environment.sortedflags=sortedflags
+  local arguments,sortedflags=environment.arguments,environment.sortedflags
+  if arguments[name] then
+    return arguments[name]
+  elseif partial then
+    if not sortedflags then
+      sortedflags=allocate(table.sortedkeys(arguments))
+      for k=1,#sortedflags do
+        sortedflags[k]="^"..sortedflags[k]
+      end
+      environment.sortedflags=sortedflags
+    end
+    for k=1,#sortedflags do
+      local v=sortedflags[k]
+      if find(name,v) then
+        return arguments[sub(v,2,#v)]
+      end
+    end
   end
-  for k=1,#sortedflags do
-   local v=sortedflags[k]
-   if find(name,v) then
-    return arguments[sub(v,2,#v)]
-   end
-  end
- end
- return nil
+  return nil
 end
 environment.argument=environment.getargument
 function environment.splitarguments(separator) 
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
-  local v=originalarguments[k]
-  if not done and v==separator then
-   done=true
-  elseif done then
-   after[#after+1]=v
-  else
-   before[#before+1]=v
+  local done,before,after=false,{},{}
+  local originalarguments=environment.originalarguments
+  for k=1,#originalarguments do
+    local v=originalarguments[k]
+    if not done and v==separator then
+      done=true
+    elseif done then
+      after[#after+1]=v
+    else
+      before[#before+1]=v
+    end
   end
- end
- return before,after
+  return before,after
 end
 function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve 
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
-  return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
-  local result={}
-  for i=1,#arg do
-   result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
+  local resolveprefix=resolvers.resolve 
+  arg=arg or environment.originalarguments
+  if noquote and #arg==1 then
+    return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+  elseif #arg>0 then
+    local result={}
+    for i=1,#arg do
+      result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
+    end
+    return concat(result," ")
+  else
+    return ""
   end
-  return concat(result," ")
- else
-  return ""
- end
 end
 function environment.relativepath(path,root)
- if not path then
-  path=""
- end
- if not file.is_rootbased_path(path) then
-  if not root then
-   root=file.pathpart(environment.ownscript or environment.ownname or ".")
+  if not path then
+    path=""
   end
-  if root=="" then
-   root="."
+  if not file.is_rootbased_path(path) then
+    if not root then
+      root=file.pathpart(environment.ownscript or environment.ownname or ".")
+    end
+    if root=="" then
+      root="."
+    end
+    path=root.."/"..path
   end
-  path=root.."/"..path
- end
- return file.collapsepath(path,true)
+  return file.collapsepath(path,true)
 end
 if arg then
- local newarg,instring={},false
- for index=1,#arg do
-  local argument=arg[index]
-  if find(argument,"^\"") then
-   if find(argument,"\"$") then
-    newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
-    instring=false
-   else
-    newarg[#newarg+1]=gsub(argument,"^\"","")
-    instring=true
-   end
-  elseif find(argument,"\"$") then
-   if instring then
-    newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
-    instring=false
-   else
-    newarg[#newarg+1]=argument
-   end
-  elseif instring then
-   newarg[#newarg]=newarg[#newarg].." "..argument
-  else
-   newarg[#newarg+1]=argument
+  local newarg,instring={},false
+  for index=1,#arg do
+    local argument=arg[index]
+    if find(argument,"^\"") then
+      newarg[#newarg+1]=gsub(argument,"^\"","")
+      if not find(argument,"\"$") then
+        instring=true
+      end
+    elseif find(argument,"\"$") then
+      newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
+      instring=false
+    elseif instring then
+      newarg[#newarg]=newarg[#newarg].." "..argument
+    else
+      newarg[#newarg+1]=argument
+    end
   end
- end
- for i=1,-5,-1 do
-  newarg[i]=arg[i]
- end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={} 
+  for i=1,-5,-1 do
+    newarg[i]=arg[i]
+  end
+  environment.initializearguments(newarg)
+  environment.originalarguments=mark(newarg)
+  environment.rawarguments=mark(arg)
+  arg={} 
 end
 
 
@@ -15437,18 +11962,17 @@
 
 package.loaded["luat-env"] = package.loaded["luat-env"] or true
 
--- original size: 6134, stripped down to: 4118
+-- original size: 5820, stripped down to: 4155
 
  if not modules then modules={} end modules ['luat-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
-local rawset,rawget,loadfile=rawset,rawget,loadfile
-local gsub=string.gsub
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local rawset,rawget,loadfile,assert=rawset,rawget,loadfile,assert
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
 local report_lua=logs.reporter("resolvers","lua")
 local luautilities=utilities.lua
 local luasuffixes=luautilities.suffixes
@@ -15456,146 +11980,133 @@
 environment=environment or {}
 local environment=environment
 local mt={
- __index=function(_,k)
-  if k=="version" then
-   local version=texgettoks and texgettoks("contextversiontoks")
-   if version and version~="" then
-    rawset(environment,"version",version)
-    return version
-   else
-    return "unknown"
-   end
-  elseif k=="kind" then
-   local kind=texgettoks and texgettoks("contextkindtoks")
-   if kind and kind~="" then
-    rawset(environment,"kind",kind)
-    return kind
-   else
-    return "unknown"
-   end
-  elseif k=="jobname" or k=="formatname" then
-   local name=tex and tex[k]
-   if name or name=="" then
-    rawset(environment,k,name)
-    return name
-   else
-    return "unknown"
-   end
-  elseif k=="outputfilename" then
-   local name=environment.jobname
-   rawset(environment,k,name)
-   return name
+  __index=function(_,k)
+    if k=="version" then
+      local version=texgettoks and texgettoks("contextversiontoks")
+      if version and version~="" then
+        rawset(environment,"version",version)
+        return version
+      else
+        return "unknown"
+      end
+    elseif k=="kind" then
+      local kind=texgettoks and texgettoks("contextkindtoks")
+      if kind and kind~="" then
+        rawset(environment,"kind",kind)
+        return kind
+      else
+        return "unknown"
+      end
+    elseif k=="jobname" or k=="formatname" then
+      local name=tex and tex[k]
+      if name or name=="" then
+        rawset(environment,k,name)
+        return name
+      else
+        return "unknown"
+      end
+    elseif k=="outputfilename" then
+      local name=environment.jobname
+      rawset(environment,k,name)
+      return name
+    end
   end
- end
 }
 setmetatable(environment,mt)
 function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+  return resolvers.findfile(filename,'tex')
 end
 function environment.luafile(filename) 
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
-  return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
-  return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
+  local resolved=resolvers.findfile(filename,'tex') or ""
+  if resolved~="" then
+    return resolved
+  end
+  resolved=resolvers.findfile(filename,'texmfscripts') or ""
+  if resolved~="" then
+    return resolved
+  end
+  return resolvers.findfile(filename,'luatexlibs') or ""
 end
-local stripindeed=false  directives.register("system.compile.strip",function(v) stripindeed=v end)
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
 local function strippable(filename)
- if stripindeed then
-  local modu=modules[file.nameonly(filename)]
-  return modu and modu.dataonly
- else
-  return false
- end
+  if stripindeed then
+    local modu=modules[file.nameonly(filename)]
+    return modu and modu.dataonly
+  else
+    return false
+  end
 end
 function environment.luafilechunk(filename,silent,macros) 
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
-  local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
-  if not silent then
-   report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+  filename=file.replacesuffix(filename,"lua")
+  local fullname=environment.luafile(filename)
+  if fullname and fullname~="" then
+    local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+    if not silent then
+      report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+    end
+    return data
+  else
+    if not silent then
+      report_lua("unknown file %a",filename)
+    end
+    return nil
   end
-  return data
- else
-  if not silent then
-   report_lua("unknown file %a",filename)
-  end
-  return nil
- end
 end
 function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
-  luaname=file.addsuffix(basename,luasuffixes.lua)
-  lucname=file.addsuffix(basename,luasuffixes.luc)
- else
-  luaname=filename 
-  lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
-  if trace_locating then
-   report_lua("loading %a",fullname)
+  local lucname,luaname,chunk
+  local basename=file.removesuffix(filename)
+  if basename==filename then
+    luaname=file.addsuffix(basename,luasuffixes.lua)
+    lucname=file.addsuffix(basename,luasuffixes.luc)
+  else
+    luaname=basename 
+    lucname=nil
   end
-  chunk=loadfile(fullname) 
- end
- if chunk then
-  chunk()
-  if version then
-   local v=version 
-   if modules and modules[filename] then
-    v=modules[filename].version 
-   elseif versions and versions[filename] then
-    v=versions[filename]  
-   end
-   if v==version then
-    return true
-   else
+  local fullname=(lucname and environment.luafile(lucname)) or ""
+  if fullname~="" then
     if trace_locating then
-     report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
+      report_lua("loading %a",fullname)
     end
-    environment.loadluafile(filename)
-   end
-  else
-   return true
+    chunk=loadfile(fullname) 
   end
- end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
-  if trace_locating then
-   report_lua("loading %a",fullname)
+  if chunk then
+    assert(chunk)()
+    if version then
+      local v=version 
+      if modules and modules[filename] then
+        v=modules[filename].version 
+      elseif versions and versions[filename] then
+        v=versions[filename]    
+      end
+      if v==version then
+        return true
+      else
+        if trace_locating then
+          report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
+        end
+        environment.loadluafile(filename)
+      end
+    else
+      return true
+    end
   end
-  chunk=loadfile(fullname) 
-  if not chunk then
-   if trace_locating then
-    report_lua("unknown file %a",filename)
-   end
-  else
-   chunk()
-   return true
+  fullname=(luaname and environment.luafile(luaname)) or ""
+  if fullname~="" then
+    if trace_locating then
+      report_lua("loading %a",fullname)
+    end
+    chunk=loadfile(fullname) 
+    if not chunk then
+      if trace_locating then
+        report_lua("unknown file %a",filename)
+      end
+    else
+      assert(chunk)()
+      return true
+    end
   end
- end
- return false
+  return false
 end
-environment.filenames=setmetatable({},{
- __index=function(t,k)
-  local v=environment.files[k]
-  if v then
-   return (gsub(v,"%.+$",""))
-  end
- end,
- __newindex=function(t,k)
- end,
- __len=function(t)
-  return #environment.files
- end,
-} )
 
 
 end -- of closure
@@ -15604,16 +12115,16 @@
 
 package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
 
--- original size: 60383, stripped down to: 35698
+-- original size: 60383, stripped down to: 38562
 
 if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="this module is the basis for the lxml-* ones",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
-local trace_entities=false  trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
 local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
 if lpeg.setmaxstack then lpeg.setmaxstack(1000) end 
 xml=xml or {}
@@ -15631,17 +12142,17 @@
 local check=P(false)
 local parse=check
 function xml.registerns(namespace,pattern) 
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+  check=check+C(P(lower(pattern)))/namespace
+  parse=P { P(check)+1*V(1) }
 end
 function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
-  xml.xmlns[namespace]=ns
- end
+  local ns=lpegmatch(parse,lower(url))
+  if ns and namespace~=ns then
+    xml.xmlns[namespace]=ns
+  end
 end
 function xml.resolvens(url)
-  return lpegmatch(parse,lower(url)) or ""
+   return lpegmatch(parse,lower(url)) or ""
 end
 end
 local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -15659,661 +12170,661 @@
 local handle_any_entity_dtd
 local handle_any_entity_text
 local function preparexmlstate(settings)
- if settings then
-  linenumbers=settings.linenumbers
-  stack={}
-  level=0
-  top={}
-  at={}
-  mt={}
-  dt={}
-  nt=0   
-  xmlns={}
-  errorstr=nil
-  strip=settings.strip_cm_and_dt
-  utfize=settings.utfize_entities
-  resolve=settings.resolve_entities   
-  resolve_predefined=settings.resolve_predefined_entities 
-  unify_predefined=settings.unify_predefined_entities   
-  cleanup=settings.text_cleanup
-  entities=settings.entities or {}
-  currentfilename=settings.currentresource
-  currentline=1
-  parameters={}
-  reported_at_errors={}
-  dcache={}
-  hcache={}
-  acache={}
-  if utfize==nil then
-   settings.utfize_entities=true
-   utfize=true
+  if settings then
+    linenumbers=settings.linenumbers
+    stack={}
+    level=0
+    top={}
+    at={}
+    mt={}
+    dt={}
+    nt=0  
+    xmlns={}
+    errorstr=nil
+    strip=settings.strip_cm_and_dt
+    utfize=settings.utfize_entities
+    resolve=settings.resolve_entities      
+    resolve_predefined=settings.resolve_predefined_entities 
+    unify_predefined=settings.unify_predefined_entities  
+    cleanup=settings.text_cleanup
+    entities=settings.entities or {}
+    currentfilename=settings.currentresource
+    currentline=1
+    parameters={}
+    reported_at_errors={}
+    dcache={}
+    hcache={}
+    acache={}
+    if utfize==nil then
+      settings.utfize_entities=true
+      utfize=true
+    end
+    if resolve_predefined==nil then
+      settings.resolve_predefined_entities=true
+      resolve_predefined=true
+    end
+  else
+    linenumbers=false
+    stack=nil
+    level=nil
+    top=nil
+    at=nil
+    mt=nil
+    dt=nil
+    nt=nil
+    xmlns=nil
+    errorstr=nil
+    strip=nil
+    utfize=nil
+    resolve=nil
+    resolve_predefined=nil
+    unify_predefined=nil
+    cleanup=nil
+    entities=nil
+    parameters=nil
+    reported_at_errors=nil
+    dcache=nil
+    hcache=nil
+    acache=nil
+    currentfilename=nil
+    currentline=1
   end
-  if resolve_predefined==nil then
-   settings.resolve_predefined_entities=true
-   resolve_predefined=true
-  end
- else
-  linenumbers=false
-  stack=nil
-  level=nil
-  top=nil
-  at=nil
-  mt=nil
-  dt=nil
-  nt=nil
-  xmlns=nil
-  errorstr=nil
-  strip=nil
-  utfize=nil
-  resolve=nil
-  resolve_predefined=nil
-  unify_predefined=nil
-  cleanup=nil
-  entities=nil
-  parameters=nil
-  reported_at_errors=nil
-  dcache=nil
-  hcache=nil
-  acache=nil
-  currentfilename=nil
-  currentline=1
- end
 end
 local function initialize_mt(root)
- mt={ __index=root } 
+  mt={ __index=root } 
 end
 function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+  getmetatable(root).__index[k]=v
 end
 function xml.checkerror(top,toclose)
- return "" 
+  return "" 
 end
 local checkns=xml.checkns
 local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
-  value=cleanup(value) 
- end
- if tag=="xmlns" then
-  xmlns[#xmlns+1]=resolvens(value)
-  at[tag]=value
- elseif namespace=="" then
-  at[tag]=value
- elseif namespace=="xmlns" then
-  checkns(tag,value)
-  at["xmlns:"..tag]=value
- else
-  at[namespace..":"..tag]=value
- end
+  if cleanup and value~="" then
+    value=cleanup(value) 
+  end
+  if tag=="xmlns" then
+    xmlns[#xmlns+1]=resolvens(value)
+    at[tag]=value
+  elseif namespace=="" then
+    at[tag]=value
+  elseif namespace=="xmlns" then
+    checkns(tag,value)
+    at["xmlns:"..tag]=value
+  else
+    at[namespace..":"..tag]=value
+  end
 end
 local function add_empty(spacing,namespace,tag)
- if spacing~="" then
-  nt=nt+1
-  dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
-  ns=namespace or "",
-  rn=resolved,
-  tg=tag,
-  at=at,
-  dt={},
-  ni=nt,
-  cf=currentfilename,
-  cl=currentline,
-  __p__=top,
- } or {
-  ns=namespace or "",
-  rn=resolved,
-  tg=tag,
-  at=at,
-  dt={},
-  ni=nt,
-  __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
-  remove(xmlns)
- end
- at={}
+  if spacing~="" then
+    nt=nt+1
+    dt[nt]=spacing
+  end
+  local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+  top=stack[level]
+  dt=top.dt
+  nt=#dt+1
+  local t=linenumbers and {
+    ns=namespace or "",
+    rn=resolved,
+    tg=tag,
+    at=at,
+    dt={},
+    ni=nt,
+    cf=currentfilename,
+    cl=currentline,
+    __p__=top,
+  } or {
+    ns=namespace or "",
+    rn=resolved,
+    tg=tag,
+    at=at,
+    dt={},
+    ni=nt,
+    __p__=top,
+  }
+  dt[nt]=t
+  setmetatable(t,mt)
+  if at.xmlns then
+    remove(xmlns)
+  end
+  at={}
 end
 local function add_begin(spacing,namespace,tag)
- if spacing~="" then
-  nt=nt+1
-  dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
-  ns=namespace or "",
-  rn=resolved,
-  tg=tag,
-  at=at,
-  dt=dt,
-  ni=nil,
-  cf=currentfilename,
-  cl=currentline,
-  __p__=stack[level],
- } or {
-  ns=namespace or "",
-  rn=resolved,
-  tg=tag,
-  at=at,
-  dt=dt,
-  ni=nil,
-  __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+  if spacing~="" then
+    nt=nt+1
+    dt[nt]=spacing
+  end
+  local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+  dt={}
+  top=linenumbers and {
+    ns=namespace or "",
+    rn=resolved,
+    tg=tag,
+    at=at,
+    dt=dt,
+    ni=nil,
+    cf=currentfilename,
+    cl=currentline,
+    __p__=stack[level],
+  } or {
+    ns=namespace or "",
+    rn=resolved,
+    tg=tag,
+    at=at,
+    dt=dt,
+    ni=nil,
+    __p__=stack[level],
+  }
+  setmetatable(top,mt)
+  nt=0
+  level=level+1
+  stack[level]=top
+  at={}
 end
 local function add_end(spacing,namespace,tag)
- if spacing~="" then
-  nt=nt+1
-  dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
-  errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
-  report_xml(errorstr)
- elseif toclose.tg~=tag then 
-  errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
-  report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt 
- if toclose.at.xmlns then
-  remove(xmlns)
- end
+  if spacing~="" then
+    nt=nt+1
+    dt[nt]=spacing
+  end
+  local toclose=stack[level]
+  level=level-1
+  top=stack[level]
+  if level<1 then
+    errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+    report_xml(errorstr)
+  elseif toclose.tg~=tag then 
+    errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+    report_xml(errorstr)
+  end
+  dt=top.dt
+  nt=#dt+1
+  dt[nt]=toclose
+  toclose.ni=nt 
+  if toclose.at.xmlns then
+    remove(xmlns)
+  end
 end
 local function add_text(text)
- if text=="" then
-  return
- end
- if cleanup then
-  if nt>0 then
-   local s=dt[nt]
-   if type(s)=="string" then
-    dt[nt]=s..cleanup(text)
-   else
-    nt=nt+1
-    dt[nt]=cleanup(text)
-   end
+  if text=="" then
+    return
+  end
+  if cleanup then
+    if nt>0 then
+      local s=dt[nt]
+      if type(s)=="string" then
+        dt[nt]=s..cleanup(text)
+      else
+        nt=nt+1
+        dt[nt]=cleanup(text)
+      end
+    else
+      nt=1
+      dt[1]=cleanup(text)
+    end
   else
-   nt=1
-   dt[1]=cleanup(text)
+    if nt>0 then
+      local s=dt[nt]
+      if type(s)=="string" then
+        dt[nt]=s..text
+      else
+        nt=nt+1
+        dt[nt]=text
+      end
+    else
+      nt=1
+      dt[1]=text
+    end
   end
- else
-  if nt>0 then
-   local s=dt[nt]
-   if type(s)=="string" then
-    dt[nt]=s..text
-   else
+end
+local function add_special(what,spacing,text)
+  if spacing~="" then
     nt=nt+1
-    dt[nt]=text
-   end
+    dt[nt]=spacing
+  end
+  if strip and (what=="@cm@" or what=="@dt@") then
   else
-   nt=1
-   dt[1]=text
+    nt=nt+1
+    dt[nt]=linenumbers and {
+      special=true,
+      ns="",
+      tg=what,
+      ni=nil,
+      dt={ text },
+      cf=currentfilename,
+      cl=currentline,
+    } or {
+      special=true,
+      ns="",
+      tg=what,
+      ni=nil,
+      dt={ text },
+    }
   end
- end
 end
-local function add_special(what,spacing,text)
- if spacing~="" then
-  nt=nt+1
-  dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
- else
-  nt=nt+1
-  dt[nt]=linenumbers and {
-   special=true,
-   ns="",
-   tg=what,
-   ni=nil,
-   dt={ text },
-   cf=currentfilename,
-   cl=currentline,
-  } or {
-   special=true,
-   ns="",
-   tg=what,
-   ni=nil,
-   dt={ text },
-  }
- end
-end
 local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+  errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
 end
 local function attribute_value_error(str)
- if not reported_at_errors[str] then
-  report_xml("invalid attribute value %a",str)
-  reported_at_errors[str]=true
-  at._error_=str
- end
- return str
+  if not reported_at_errors[str] then
+    report_xml("invalid attribute value %a",str)
+    reported_at_errors[str]=true
+    at._error_=str
+  end
+  return str
 end
 local function attribute_specification_error(str)
- if not reported_at_errors[str] then
-  report_xml("invalid attribute specification %a",str)
-  reported_at_errors[str]=true
-  at._error_=str
- end
- return str
+  if not reported_at_errors[str] then
+    report_xml("invalid attribute specification %a",str)
+    reported_at_errors[str]=true
+    at._error_=str
+  end
+  return str
 end
 do
- local badentity="&" 
- xml.placeholders={
-  unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
-  unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
-  unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
-  local n=tonumber(s,16)
-  if n then
-   return utfchar(n)
-  else
-   return formatters["h:%s"](s),true
+  local badentity="&" 
+  xml.placeholders={
+    unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+    unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+    unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+  }
+  local function fromhex(s)
+    local n=tonumber(s,16)
+    if n then
+      return utfchar(n)
+    else
+      return formatters["h:%s"](s),true
+    end
   end
- end
- local function fromdec(s)
-  local n=tonumber(s)
-  if n then
-   return utfchar(n)
-  else
-   return formatters["d:%s"](s),true
+  local function fromdec(s)
+    local n=tonumber(s)
+    if n then
+      return utfchar(n)
+    else
+      return formatters["d:%s"](s),true
+    end
   end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
-  [38]="&",
-  [42]=""",
-  [47]="'",
-  [74]="<",
-  [76]=">",
- }
- local predefined_simplified={
-  [38]="&",amp="&",
-  [42]='"',quot='"',
-  [47]="'",apos="'",
-  [74]="<",lt="<",
-  [76]=">",gt=">",
- }
- local nofprivates=0xF0000 
- local privates_u={ 
-  [ [[&]] ]="&",
-  [ [["]] ]=""",
-  [ [[']] ]="'",
-  [ [[<]] ]="<",
-  [ [[>]] ]=">",
- }
- local privates_p={ 
- }
- local privates_s={ 
-  [ [["]] ]="&U+22;",
-  [ [[#]] ]="&U+23;",
-  [ [[$]] ]="&U+24;",
-  [ [[%]] ]="&U+25;",
-  [ [[&]] ]="&U+26;",
-  [ [[']] ]="&U+27;",
-  [ [[<]] ]="&U+3C;",
-  [ [[>]] ]="&U+3E;",
-  [ [[\]] ]="&U+5C;",
-  [ [[{]] ]="&U+7B;",
-  [ [[|]] ]="&U+7C;",
-  [ [[}]] ]="&U+7D;",
-  [ [[~]] ]="&U+7E;",
- }
- local privates_x={ 
-  [ [["]] ]="&U+22;",
-  [ [[#]] ]="&U+23;",
-  [ [[$]] ]="&U+24;",
-  [ [[%]] ]="&U+25;",
-  [ [[']] ]="&U+27;",
-  [ [[\]] ]="&U+5C;",
-  [ [[{]] ]="&U+7B;",
-  [ [[|]] ]="&U+7C;",
-  [ [[}]] ]="&U+7D;",
-  [ [[~]] ]="&U+7E;",
- }
- local privates_n={ 
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
-  local p=privates_n[s]
-  if not p then
-   nofprivates=nofprivates+1
-   p=utfchar(nofprivates)
-   privates_n[s]=p
-   s="&"..s..";" 
-   privates_u[p]=s
-   privates_p[p]=s
-   privates_s[p]=s
+  local p_rest=(1-P(";"))^0
+  local p_many=P(1)^0
+  local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+  xml.parsedentitylpeg=parsedentity
+  local predefined_unified={
+    [38]="&",
+    [42]=""",
+    [47]="'",
+    [74]="<",
+    [76]=">",
+  }
+  local predefined_simplified={
+    [38]="&",amp="&",
+    [42]='"',quot='"',
+    [47]="'",apos="'",
+    [74]="<",lt="<",
+    [76]=">",gt=">",
+  }
+  local nofprivates=0xF0000 
+  local privates_u={ 
+    [ [[&]] ]="&",
+    [ [["]] ]=""",
+    [ [[']] ]="'",
+    [ [[<]] ]="<",
+    [ [[>]] ]=">",
+  }
+  local privates_p={ 
+  }
+  local privates_s={ 
+    [ [["]] ]="&U+22;",
+    [ [[#]] ]="&U+23;",
+    [ [[$]] ]="&U+24;",
+    [ [[%]] ]="&U+25;",
+    [ [[&]] ]="&U+26;",
+    [ [[']] ]="&U+27;",
+    [ [[<]] ]="&U+3C;",
+    [ [[>]] ]="&U+3E;",
+    [ [[\]] ]="&U+5C;",
+    [ [[{]] ]="&U+7B;",
+    [ [[|]] ]="&U+7C;",
+    [ [[}]] ]="&U+7D;",
+    [ [[~]] ]="&U+7E;",
+  }
+  local privates_x={ 
+    [ [["]] ]="&U+22;",
+    [ [[#]] ]="&U+23;",
+    [ [[$]] ]="&U+24;",
+    [ [[%]] ]="&U+25;",
+    [ [[']] ]="&U+27;",
+    [ [[\]] ]="&U+5C;",
+    [ [[{]] ]="&U+7B;",
+    [ [[|]] ]="&U+7C;",
+    [ [[}]] ]="&U+7D;",
+    [ [[~]] ]="&U+7E;",
+  }
+  local privates_n={ 
+  }
+  local escaped=utf.remapper(privates_u,"dynamic")
+  local unprivatized=utf.remapper(privates_p,"dynamic")
+  local unspecialized=utf.remapper(privates_s,"dynamic")
+  local despecialized=utf.remapper(privates_x,"dynamic")
+  xml.unprivatized=unprivatized
+  xml.unspecialized=unspecialized
+  xml.despecialized=despecialized
+  xml.escaped=escaped
+  local function unescaped(s)
+    local p=privates_n[s]
+    if not p then
+      nofprivates=nofprivates+1
+      p=utfchar(nofprivates)
+      privates_n[s]=p
+      s="&"..s..";" 
+      privates_u[p]=s
+      privates_p[p]=s
+      privates_s[p]=s
+    end
+    return p
   end
-  return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
-  privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
-  local h=hcache[str]
-  if not h then
-   local n=tonumber(str,16)
-   h=unify_predefined and predefined_unified[n]
-   if h then
-    if trace_entities then
-     report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+  xml.privatetoken=unescaped
+  xml.privatecodes=privates_n
+  xml.specialcodes=privates_s
+  function xml.addspecialcode(key,value)
+    privates_s[key]=value or "&"..s..";"
+  end
+  handle_hex_entity=function(str)
+    local h=hcache[str]
+    if not h then
+      local n=tonumber(str,16)
+      h=unify_predefined and predefined_unified[n]
+      if h then
+        if trace_entities then
+          report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+        end
+      elseif utfize then
+        h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+        if not n then
+          report_xml("utfize, ignoring hex entity &#x%s;",str)
+        elseif trace_entities then
+          report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+        end
+      else
+        if trace_entities then
+          report_xml("found entity &#x%s;",str)
+        end
+        h="&#x"..str..";"
+      end
+      hcache[str]=h
     end
-   elseif utfize then
-    h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
-    if not n then
-     report_xml("utfize, ignoring hex entity &#x%s;",str)
-    elseif trace_entities then
-     report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
-    end
-   else
-    if trace_entities then
-     report_xml("found entity &#x%s;",str)
-    end
-    h="&#x"..str..";"
-   end
-   hcache[str]=h
+    return h
   end
-  return h
- end
- handle_dec_entity=function(str)
-  local d=dcache[str]
-  if not d then
-   local n=tonumber(str)
-   d=unify_predefined and predefined_unified[n]
-   if d then
-    if trace_entities then
-     report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+  handle_dec_entity=function(str)
+    local d=dcache[str]
+    if not d then
+      local n=tonumber(str)
+      d=unify_predefined and predefined_unified[n]
+      if d then
+        if trace_entities then
+          report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+        end
+      elseif utfize then
+        d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+        if not n then
+          report_xml("utfize, ignoring dec entity &#%s;",str)
+        elseif trace_entities then
+          report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+        end
+      else
+        if trace_entities then
+          report_xml("found entity &#%s;",str)
+        end
+        d="&#"..str..";"
+      end
+      dcache[str]=d
     end
-   elseif utfize then
-    d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
-    if not n then
-     report_xml("utfize, ignoring dec entity &#%s;",str)
-    elseif trace_entities then
-     report_xml("utfize, converting dec entity &#%s; into %a",str,d)
-    end
-   else
-    if trace_entities then
-     report_xml("found entity &#%s;",str)
-    end
-    d="&#"..str..";"
-   end
-   dcache[str]=d
+    return d
   end
-  return d
- end
- handle_any_entity_dtd=function(str)
-  if resolve then
-   local a=resolve_predefined and predefined_simplified[str] 
-   if a then
-    if trace_entities then
-     report_xml("resolving entity &%s; to predefined %a",str,a)
-    end
-   else
-    if type(resolve)=="function" then
-     a=resolve(str,entities) or entities[str]
+  handle_any_entity_dtd=function(str)
+    if resolve then
+      local a=resolve_predefined and predefined_simplified[str] 
+      if a then
+        if trace_entities then
+          report_xml("resolving entity &%s; to predefined %a",str,a)
+        end
+      else
+        if type(resolve)=="function" then
+          a=resolve(str,entities) or entities[str]
+        else
+          a=entities[str]
+        end
+        if a then
+          if type(a)=="function" then
+            if trace_entities then
+              report_xml("expanding entity &%s; to function call",str)
+            end
+            a=a(str) or ""
+          end
+          a=lpegmatch(parsedentity,a) or a 
+          if trace_entities then
+            report_xml("resolving entity &%s; to internal %a",str,a)
+          end
+        else
+          local unknown_any_entity=placeholders.unknown_any_entity
+          if unknown_any_entity then
+            a=unknown_any_entity(str) or ""
+          end
+          if a then
+            if trace_entities then
+              report_xml("resolving entity &%s; to external %s",str,a)
+            end
+          else
+            if trace_entities then
+              report_xml("keeping entity &%s;",str)
+            end
+            if str=="" then
+              a=badentity
+            else
+              a="&"..str..";"
+            end
+          end
+        end
+      end
+      return a
     else
-     a=entities[str]
+      local a=acache[str]
+      if not a then
+        a=resolve_predefined and predefined_simplified[str]
+        if a then
+          acache[str]=a
+          if trace_entities then
+            report_xml("entity &%s; becomes %a",str,a)
+          end
+        elseif str=="" then
+          if trace_entities then
+            report_xml("invalid entity &%s;",str)
+          end
+          a=badentity
+          acache[str]=a
+        else
+          if trace_entities then
+            report_xml("entity &%s; is made private",str)
+          end
+          a=unescaped(str)
+          acache[str]=a
+        end
+      end
+      return a
     end
-    if a then
-     if type(a)=="function" then
-      if trace_entities then
-       report_xml("expanding entity &%s; to function call",str)
+  end
+  handle_any_entity_text=function(str)
+    if resolve then
+      local a=resolve_predefined and predefined_simplified[str]
+      if a then
+        if trace_entities then
+          report_xml("resolving entity &%s; to predefined %a",str,a)
+        end
+      else
+        if type(resolve)=="function" then
+          a=resolve(str,entities) or entities[str]
+        else
+          a=entities[str]
+        end
+        if a then
+          if type(a)=="function" then
+            if trace_entities then
+              report_xml("expanding entity &%s; to function call",str)
+            end
+            a=a(str) or ""
+          end
+          a=lpegmatch(grammar_parsed_text_two,a) or a
+          if type(a)=="number" then
+            return ""
+          else
+            a=lpegmatch(parsedentity,a) or a 
+            if trace_entities then
+              report_xml("resolving entity &%s; to internal %a",str,a)
+            end
+          end
+          if trace_entities then
+            report_xml("resolving entity &%s; to internal %a",str,a)
+          end
+        else
+          local unknown_any_entity=placeholders.unknown_any_entity
+          if unknown_any_entity then
+            a=unknown_any_entity(str) or ""
+          end
+          if a then
+            if trace_entities then
+              report_xml("resolving entity &%s; to external %s",str,a)
+            end
+          else
+            if trace_entities then
+              report_xml("keeping entity &%s;",str)
+            end
+            if str=="" then
+              a=badentity
+            else
+              a="&"..str..";"
+            end
+          end
+        end
       end
-      a=a(str) or ""
-     end
-     a=lpegmatch(parsedentity,a) or a 
-     if trace_entities then
-      report_xml("resolving entity &%s; to internal %a",str,a)
-     end
+      return a
     else
-     local unknown_any_entity=placeholders.unknown_any_entity
-     if unknown_any_entity then
-      a=unknown_any_entity(str) or ""
-     end
-     if a then
-      if trace_entities then
-       report_xml("resolving entity &%s; to external %s",str,a)
+      local a=acache[str]
+      if not a then
+        a=resolve_predefined and predefined_simplified[str]
+        if a then
+          acache[str]=a
+          if trace_entities then
+            report_xml("entity &%s; becomes %a",str,a)
+          end
+        elseif str=="" then
+          if trace_entities then
+            report_xml("invalid entity &%s;",str)
+          end
+          a=badentity
+          acache[str]=a
+        else
+          if trace_entities then
+            report_xml("entity &%s; is made private",str)
+          end
+          a=unescaped(str)
+          acache[str]=a
+        end
       end
-     else
-      if trace_entities then
-       report_xml("keeping entity &%s;",str)
-      end
-      if str=="" then
-       a=badentity
-      else
-       a="&"..str..";"
-      end
-     end
+      return a
     end
-   end
-   return a
-  else
-   local a=acache[str]
-   if not a then
-    a=resolve_predefined and predefined_simplified[str]
-    if a then
-     acache[str]=a
-     if trace_entities then
-      report_xml("entity &%s; becomes %a",str,a)
-     end
-    elseif str=="" then
-     if trace_entities then
-      report_xml("invalid entity &%s;",str)
-     end
-     a=badentity
-     acache[str]=a
+  end
+  local p_rest=(1-P(";"))^1
+  local spec={
+    [0x23]="\\Ux{23}",
+    [0x24]="\\Ux{24}",
+    [0x25]="\\Ux{25}",
+    [0x5C]="\\Ux{5C}",
+    [0x7B]="\\Ux{7B}",
+    [0x7C]="\\Ux{7C}",
+    [0x7D]="\\Ux{7D}",
+    [0x7E]="\\Ux{7E}",
+  }
+  local hash=table.setmetatableindex(spec,function(t,k)
+    local v=utfchar(k)
+    t[k]=v
+    return v
+  end)
+  local function fromuni(s)
+    local n=tonumber(s,16)
+    if n then
+      return hash[n]
     else
-     if trace_entities then
-      report_xml("entity &%s; is made private",str)
-     end
-     a=unescaped(str)
-     acache[str]=a
+      return formatters["u:%s"](s),true
     end
-   end
-   return a
   end
- end
- handle_any_entity_text=function(str)
-  if resolve then
-   local a=resolve_predefined and predefined_simplified[str]
-   if a then
-    if trace_entities then
-     report_xml("resolving entity &%s; to predefined %a",str,a)
+  local function fromhex(s)
+    local n=tonumber(s,16)
+    if n then
+      return hash[n]
+    else
+      return formatters["h:%s"](s),true
     end
-   else
-    if type(resolve)=="function" then
-     a=resolve(str,entities) or entities[str]
+  end
+  local function fromdec(s)
+    local n=tonumber(s)
+    if n then
+      return hash[n]
     else
-     a=entities[str]
+      return formatters["d:%s"](s),true
     end
-    if a then
-     if type(a)=="function" then
-      if trace_entities then
-       report_xml("expanding entity &%s; to function call",str)
-      end
-      a=a(str) or ""
-     end
-     a=lpegmatch(grammar_parsed_text_two,a) or a
-     if type(a)=="number" then
-      return ""
-     else
-      a=lpegmatch(parsedentity,a) or a 
-      if trace_entities then
-       report_xml("resolving entity &%s; to internal %a",str,a)
-      end
-     end
-     if trace_entities then
-      report_xml("resolving entity &%s; to internal %a",str,a)
-     end
+  end
+  local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+      P("x")*(p_rest/fromhex)+p_rest/fromdec
+    )
+  local hash=table.setmetatableindex(function(t,k)
+    local v=utfchar(k)
+    t[k]=v
+    return v
+  end)
+  local function fromuni(s)
+    local n=tonumber(s,16)
+    if n then
+      return hash[n]
     else
-     local unknown_any_entity=placeholders.unknown_any_entity
-     if unknown_any_entity then
-      a=unknown_any_entity(str) or ""
-     end
-     if a then
-      if trace_entities then
-       report_xml("resolving entity &%s; to external %s",str,a)
-      end
-     else
-      if trace_entities then
-       report_xml("keeping entity &%s;",str)
-      end
-      if str=="" then
-       a=badentity
-      else
-       a="&"..str..";"
-      end
-     end
+      return formatters["u:%s"](s),true
     end
-   end
-   return a
-  else
-   local a=acache[str]
-   if not a then
-    a=resolve_predefined and predefined_simplified[str]
-    if a then
-     acache[str]=a
-     if trace_entities then
-      report_xml("entity &%s; becomes %a",str,a)
-     end
-    elseif str=="" then
-     if trace_entities then
-      report_xml("invalid entity &%s;",str)
-     end
-     a=badentity
-     acache[str]=a
+  end
+  local function fromhex(s)
+    local n=tonumber(s,16)
+    if n then
+      return hash[n]
     else
-     if trace_entities then
-      report_xml("entity &%s; is made private",str)
-     end
-     a=unescaped(str)
-     acache[str]=a
+      return formatters["h:%s"](s),true
     end
-   end
-   return a
   end
- end
- local p_rest=(1-P(";"))^1
- local spec={
-  [0x23]="\\Ux{23}",
-  [0x24]="\\Ux{24}",
-  [0x25]="\\Ux{25}",
-  [0x5C]="\\Ux{5C}",
-  [0x7B]="\\Ux{7B}",
-  [0x7C]="\\Ux{7C}",
-  [0x7D]="\\Ux{7D}",
-  [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
-  local v=utfchar(k)
-  t[k]=v
-  return v
- end)
- local function fromuni(s)
-  local n=tonumber(s,16)
-  if n then
-   return hash[n]
-  else
-   return formatters["u:%s"](s),true
+  local function fromdec(s)
+    local n=tonumber(s)
+    if n then
+      return hash[n]
+    else
+      return formatters["d:%s"](s),true
+    end
   end
- end
- local function fromhex(s)
-  local n=tonumber(s,16)
-  if n then
-   return hash[n]
-  else
-   return formatters["h:%s"](s),true
-  end
- end
- local function fromdec(s)
-  local n=tonumber(s)
-  if n then
-   return hash[n]
-  else
-   return formatters["d:%s"](s),true
-  end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
-   P("x")*(p_rest/fromhex)+p_rest/fromdec
-  )
- local hash=table.setmetatableindex(function(t,k)
-  local v=utfchar(k)
-  t[k]=v
-  return v
- end)
- local function fromuni(s)
-  local n=tonumber(s,16)
-  if n then
-   return hash[n]
-  else
-   return formatters["u:%s"](s),true
-  end
- end
- local function fromhex(s)
-  local n=tonumber(s,16)
-  if n then
-   return hash[n]
-  else
-   return formatters["h:%s"](s),true
-  end
- end
- local function fromdec(s)
-  local n=tonumber(s)
-  if n then
-   return hash[n]
-  else
-   return formatters["d:%s"](s),true
-  end
- end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
-   P("x")*(p_rest/fromhex)+p_rest/fromdec
-  )
- xml.reparsedentitylpeg=reparsedentity   
- xml.unescapedentitylpeg=unescapedentity  
+  local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+      P("x")*(p_rest/fromhex)+p_rest/fromdec
+    )
+  xml.reparsedentitylpeg=reparsedentity  
+  xml.unescapedentitylpeg=unescapedentity 
 end
 local escaped=xml.escaped
 local unescaped=xml.unescaped
 local placeholders=xml.placeholders
 local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+  report_xml("error in entity, %a found without ending %a",str,";")
+  return str
 end
 local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+  report_xml("error in parsing, unexpected %a found ",chr)
+  add_text(chr)
+  return chr
 end
 local function handlenewline()
- currentline=currentline+1
+  currentline=currentline+1
 end
 local spacetab=S(' \t')
 local space=S(' \r\n\t')
@@ -16338,141 +12849,141 @@
 local spacing_nl=Cs((space_nl)^0)
 local anything_nl=newline+P(1)
 local function weirdentity(k,v)
- if trace_entities then
-  report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+  if trace_entities then
+    report_xml("registering %s entity %a as %a","weird",k,v)
+  end
+  parameters[k]=v
 end
 local function normalentity(k,v)
- if trace_entities then
-  report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+  if trace_entities then
+    report_xml("registering %s entity %a as %a","normal",k,v)
+  end
+  entities[k]=v
 end
 local function systementity(k,v,n)
- if trace_entities then
-  report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+  if trace_entities then
+    report_xml("registering %s entity %a as %a","system",k,v)
+  end
+  entities[k]=v
 end
 local function publicentity(k,v,n)
- if trace_entities then
-  report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+  if trace_entities then
+    report_xml("registering %s entity %a as %a","public",k,v)
+  end
+  entities[k]=v
 end
 local function entityfile(pattern,k,v,n)
- if n then
-  local okay,data
-  if resolvers then
-   okay,data=resolvers.loadbinfile(n)
-  else
-   data=io.loaddata(n)
-   okay=data and data~=""
+  if n then
+    local okay,data
+    if resolvers then
+      okay,data=resolvers.loadbinfile(n)
+    else
+      data=io.loaddata(n)
+      okay=data and data~=""
+    end
+    if okay then
+      if trace_entities then
+        report_xml("loading public entities %a as %a from %a",k,v,n)
+      end
+      lpegmatch(pattern,data)
+      return
+    end
   end
-  if okay then
-   if trace_entities then
-    report_xml("loading public entities %a as %a from %a",k,v,n)
-   end
-   lpegmatch(pattern,data)
-   return
-  end
- end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+  report_xml("ignoring public entities %a as %a from %a",k,v,n)
 end
 local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
-         P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
-        )+(anyentitycontent/handle_any_entity_dtd) 
- local parsedentity_text=P("#")/""*(
-         P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
-        )+(anyentitycontent/handle_any_entity_text) 
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote) 
- local endofattributes=slash*close+close 
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed   
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" } 
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata   )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
-  entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
-  lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
-  lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1 
- local somedoctype=C((somespace*(
+  local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+  local hexentitycontent=R("AF","af","09")^1
+  local decentitycontent=R("09")^1
+  local parsedentity=P("#")/""*(
+                  P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+                )+(anyentitycontent/handle_any_entity_dtd) 
+  local parsedentity_text=P("#")/""*(
+                  P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+                )+(anyentitycontent/handle_any_entity_text) 
+  local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+  local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+  local text_unparsed=Cs((anything-open)^1)
+  local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+  local somespace=(spacenewline)^1
+  local optionalspace=(spacenewline)^0
+  local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote) 
+  local endofattributes=slash*close+close 
+  local whatever=space*name*optionalspace*equal
+  local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+  local attributevalue=value+wrongvalue
+  local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+  local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+  local parsedtext=text_parsed  
+  local unparsedtext=text_unparsed/add_text
+  local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" } 
+  local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+  local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+  local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+  local begincomment=open*P("!--")
+  local endcomment=P("--")*close
+  local begininstruction=open*P("?")
+  local endinstruction=P("?")*close
+  local begincdata=open*P("![CDATA[")
+  local endcdata=P("]]")*close
+  local someinstruction=C((anything-endinstruction)^0)
+  local somecomment=C((anything-endcomment  )^0)
+  local somecdata=C((anything-endcdata   )^0)
+  local begindoctype=open*P("!DOCTYPE")
+  local enddoctype=close
+  local beginset=P("[")
+  local endset=P("]")
+  local wrdtypename=C((anything-somespace-P(";"))^1)
+  local doctypename=C((anything-somespace-close)^0)
+  local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+  local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+  local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+  local normalentitytype=(doctypename*somespace*value)/normalentity
+  local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+  local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+  local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+  local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+    entityfile(entitydoctype,...)
+  end
+  local function weirdresolve(s)
+    lpegmatch(entitydoctype,parameters[s])
+  end
+  local function normalresolve(s)
+    lpegmatch(entitydoctype,entities[s])
+  end
+  local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+  entitydoctype=entitydoctype+entityresolve
+  local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+  local definitiondoctype=doctypename*somespace*doctypeset
+  local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+  local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+  local simpledoctype=(anything-close)^1 
+  local somedoctype=C((somespace*(
 publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata   )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed     )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
-  preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
-  followup=V("parent")*trailer,
-  parent=beginelement*V("children")^0*endelement,
-  children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
-  preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
-  parent=beginelement*V("children")^0*endelement,
-  children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+  local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+  local comment=(spacing*begincomment*somecomment*endcomment  )/function(...) add_special("@cm@",...) end
+  local cdata=(spacing*begincdata*somecdata*endcdata   )/function(...) add_special("@cd@",...) end
+  local doctype=(spacing*begindoctype*somedoctype*enddoctype  )/function(...) add_special("@dt@",...) end
+  local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+  local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+  local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+  local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+  local unparsedcrap=Cs((crap_unparsed       )^1)/handle_crap_error
+  local trailer=space^0*(text_unparsed/set_message)^0
+  local grammar_parsed_text_one=P { "preamble",
+    preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+  }
+  local grammar_parsed_text_two=P { "followup",
+    followup=V("parent")*trailer,
+    parent=beginelement*V("children")^0*endelement,
+    children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+  }
+  local grammar_unparsed_text=P { "preamble",
+    preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+    parent=beginelement*V("children")^0*endelement,
+    children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+  }
+  return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
 end
 grammar_parsed_text_one_nop,
 grammar_parsed_text_two_nop,
@@ -16481,450 +12992,450 @@
 grammar_parsed_text_two_yes,
 grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
 local function _xmlconvert_(data,settings,detail)
- settings=settings or {} 
- preparexmlstate(settings)
- if settings.linenumbers then
-  grammar_parsed_text_one=grammar_parsed_text_one_yes
-  grammar_parsed_text_two=grammar_parsed_text_two_yes
-  grammar_unparsed_text=grammar_unparsed_text_yes
- else
-  grammar_parsed_text_one=grammar_parsed_text_one_nop
-  grammar_parsed_text_two=grammar_parsed_text_two_nop
-  grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
-  data=preprocessor(data,settings) or data 
- end
- if settings.parent_root then
-  mt=getmetatable(settings.parent_root)
- else
-  initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
-  errorstr="empty xml file"
- elseif data==true then
-  errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
-  local m=lpegmatch(grammar_parsed_text_one,data)
-  if m then
-   m=lpegmatch(grammar_parsed_text_two,data,m)
+  settings=settings or {} 
+  preparexmlstate(settings)
+  if settings.linenumbers then
+    grammar_parsed_text_one=grammar_parsed_text_one_yes
+    grammar_parsed_text_two=grammar_parsed_text_two_yes
+    grammar_unparsed_text=grammar_unparsed_text_yes
+  else
+    grammar_parsed_text_one=grammar_parsed_text_one_nop
+    grammar_parsed_text_two=grammar_parsed_text_two_nop
+    grammar_unparsed_text=grammar_unparsed_text_nop
   end
-  if m then
+  local preprocessor=settings.preprocessor
+  if data and data~="" and type(preprocessor)=="function" then
+    data=preprocessor(data,settings) or data 
+  end
+  if settings.parent_root then
+    mt=getmetatable(settings.parent_root)
   else
-   errorstr="invalid xml file - parsed text"
+    initialize_mt(top)
   end
- elseif type(data)=="string" then
-  if lpegmatch(grammar_unparsed_text,data) then
-   errorstr=""
+  level=level+1
+  stack[level]=top
+  top.dt={}
+  dt=top.dt
+  nt=0
+  if not data or data=="" then
+    errorstr="empty xml file"
+  elseif data==true then
+    errorstr=detail or "problematic xml file"
+  elseif utfize or resolve then
+    local m=lpegmatch(grammar_parsed_text_one,data)
+    if m then
+      m=lpegmatch(grammar_parsed_text_two,data,m)
+    end
+    if m then
+    else
+      errorstr="invalid xml file - parsed text"
+    end
+  elseif type(data)=="string" then
+    if lpegmatch(grammar_unparsed_text,data) then
+      errorstr=""
+    else
+      errorstr="invalid xml file - unparsed text"
+    end
   else
-   errorstr="invalid xml file - unparsed text"
+    errorstr="invalid xml file - no text at all"
   end
- else
-  errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
-  result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
-  setmetatable(result,mt)
-  setmetatable(result.dt[1],mt)
-  setmetatable(stack,mt)
-  local errorhandler=settings.error_handler
-  if errorhandler==false then
-  else
-   errorhandler=errorhandler or xml.errorhandler
-   if errorhandler then
-    local currentresource=settings.currentresource
-    if currentresource and currentresource~="" then
-     xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
+  local result
+  if errorstr and errorstr~="" then
+    result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+    setmetatable(result,mt)
+    setmetatable(result.dt[1],mt)
+    setmetatable(stack,mt)
+    local errorhandler=settings.error_handler
+    if errorhandler==false then
     else
-     xml.errorhandler(formatters["load error: %s"](errorstr))
+      errorhandler=errorhandler or xml.errorhandler
+      if errorhandler then
+        local currentresource=settings.currentresource
+        if currentresource and currentresource~="" then
+          xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
+        else
+          xml.errorhandler(formatters["load error: %s"](errorstr))
+        end
+      end
     end
-   end
+  else
+    result=stack[1]
   end
- else
-  result=stack[1]
- end
- if not settings.no_root then
-  result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
-  setmetatable(result,mt)
-  local rdt=result.dt
-  for k=1,#rdt do
-   local v=rdt[k]
-   if type(v)=="table" and not v.special then 
-    result.ri=k 
-    v.__p__=result  
-    break
-   end
+  if not settings.no_root then
+    result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+    setmetatable(result,mt)
+    local rdt=result.dt
+    for k=1,#rdt do
+      local v=rdt[k]
+      if type(v)=="table" and not v.special then 
+        result.ri=k 
+        v.__p__=result 
+        break
+      end
+    end
   end
- end
- if errorstr and errorstr~="" then
-  result.error=true
- else
-  errorstr=nil
- end
- result.statistics={
-  errormessage=errorstr,
-  entities={
-   decimals=dcache,
-   hexadecimals=hcache,
-   names=acache,
-   intermediates=parameters,
+  if errorstr and errorstr~="" then
+    result.error=true
+  else
+    errorstr=nil
+  end
+  result.statistics={
+    errormessage=errorstr,
+    entities={
+      decimals=dcache,
+      hexadecimals=hcache,
+      names=acache,
+      intermediates=parameters,
+    }
   }
- }
- preparexmlstate() 
- return result
+  preparexmlstate() 
+  return result
 end
 local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
-  return result
- elseif type(result)=="string" then
-  return _xmlconvert_(true,settings,result)
- else
-  return _xmlconvert_(true,settings)
- end
+  local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+  if ok then
+    return result
+  elseif type(result)=="string" then
+    return _xmlconvert_(true,settings,result)
+  else
+    return _xmlconvert_(true,settings)
+  end
 end
 xml.convert=xmlconvert
 function xml.inheritedconvert(data,xmldata) 
- local settings=xmldata.settings
- if settings then
-  settings.parent_root=xmldata 
- end
- local xc=xmlconvert(data,settings)
- return xc
+  local settings=xmldata.settings
+  if settings then
+    settings.parent_root=xmldata 
+  end
+  local xc=xmlconvert(data,settings)
+  return xc
 end
 function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+  return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
 end
 function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+  local ns,tg=match(tag,"^(.-):?([^:]+)$")
+  local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+  setmetatable(t,mt)
+  return t
 end
 function xml.is_valid(root)
- return root and not root.error
+  return root and not root.error
 end
 xml.errorhandler=report_xml
 function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
-  local f=io.open(filename,'r') 
-  if f then
-   data=f:read("*all") 
-   f:close()
+  local data=""
+  if type(filename)=="string" then
+    local f=io.open(filename,'r') 
+    if f then
+      data=f:read("*all") 
+      f:close()
+    end
+  elseif filename then 
+    data=filename:read("*all") 
   end
- elseif filename then 
-  data=filename:read("*all") 
- end
- if settings then
-  settings.currentresource=filename
-  local result=xmlconvert(data,settings)
-  settings.currentresource=nil
-  return result
- else
-  return xmlconvert(data,{ currentresource=filename })
- end
+  if settings then
+    settings.currentresource=filename
+    local result=xmlconvert(data,settings)
+    settings.currentresource=nil
+    return result
+  else
+    return xmlconvert(data,{ currentresource=filename })
+  end
 end
 local no_root={ no_root=true }
 function xml.toxml(data)
- if type(data)=="string" then
-  local root={ xmlconvert(data,no_root) }
-  return (#root>1 and root) or root[1]
- else
-  return data
- end
+  if type(data)=="string" then
+    local root={ xmlconvert(data,no_root) }
+    return (#root>1 and root) or root[1]
+  else
+    return data
+  end
 end
 local function copy(old,p)
- if old then
-  local new={}
-  for k,v in next,old do
-   local t=type(v)=="table"
-   if k=="at" then
-    local t={}
-    for k,v in next,v do
-     t[k]=v
+  if old then
+    local new={}
+    for k,v in next,old do
+      local t=type(v)=="table"
+      if k=="at" then
+        local t={}
+        for k,v in next,v do
+          t[k]=v
+        end
+        new[k]=t
+      elseif k=="dt" then
+        v.__p__=nil
+        v=copy(v,new)
+        new[k]=v
+        v.__p__=p
+      else
+        new[k]=v 
+      end
     end
-    new[k]=t
-   elseif k=="dt" then
-    v.__p__=nil
-    v=copy(v,new)
-    new[k]=v
-    v.__p__=p
-   else
-    new[k]=v 
-   end
+    local mt=getmetatable(old)
+    if mt then
+      setmetatable(new,mt)
+    end
+    return new
+  else
+    return {}
   end
-  local mt=getmetatable(old)
-  if mt then
-   setmetatable(new,mt)
-  end
-  return new
- else
-  return {}
- end
 end
 xml.copy=copy
 function xml.checkbom(root) 
- if root.ri then
-  local dt=root.dt
-  for k=1,#dt do
-   local v=dt[k]
-   if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
-    return
-   end
+  if root.ri then
+    local dt=root.dt
+    for k=1,#dt do
+      local v=dt[k]
+      if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
+        return
+      end
+    end
+    insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+    insert(dt,2,"\n" )
   end
-  insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
-  insert(dt,2,"\n" )
- end
 end
 local f_attribute=formatters['%s=%q']
 local function verbose_element(e,handlers,escape) 
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
-  local n=0
-  for k in next,eat do
-   n=n+1
-   ats[n]=k
+  local handle=handlers.handle
+  local serialize=handlers.serialize
+  local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+  local ats=eat and next(eat) and {}
+  if ats then
+    local n=0
+    for k in next,eat do
+      n=n+1
+      ats[n]=k
+    end
+    if n==1 then
+      local k=ats[1]
+      ats=f_attribute(k,escaped(eat[k]))
+    else
+      sort(ats)
+      for i=1,n do
+        local k=ats[i]
+        ats[i]=f_attribute(k,escaped(eat[k]))
+      end
+      ats=concat(ats," ")
+    end
   end
-  if n==1 then
-   local k=ats[1]
-   ats=f_attribute(k,escaped(eat[k]))
-  else
-   sort(ats)
-   for i=1,n do
-    local k=ats[i]
-    ats[i]=f_attribute(k,escaped(eat[k]))
-   end
-   ats=concat(ats," ")
+  if ern and trace_entities and ern~=ens then
+    ens=ern
   end
- end
- if ern and trace_entities and ern~=ens then
-  ens=ern
- end
- local n=edt and #edt
- if ens~="" then
-  if n and n>0 then
-   if ats then
-    handle("<",ens,":",etg," ",ats,">")
-   else
-    handle("<",ens,":",etg,">")
-   end
-   for i=1,n do
-    local e=edt[i]
-    if type(e)=="string" then
-     handle(escaped(e))
+  local n=edt and #edt
+  if ens~="" then
+    if n and n>0 then
+      if ats then
+        handle("<",ens,":",etg," ",ats,">")
+      else
+        handle("<",ens,":",etg,">")
+      end
+      for i=1,n do
+        local e=edt[i]
+        if type(e)=="string" then
+          handle(escaped(e))
+        else
+          serialize(e,handlers)
+        end
+      end
+      handle("</",ens,":",etg,">")
     else
-     serialize(e,handlers)
+      if ats then
+        handle("<",ens,":",etg," ",ats,"/>")
+      else
+        handle("<",ens,":",etg,"/>")
+      end
     end
-   end
-   handle("</",ens,":",etg,">")
   else
-   if ats then
-    handle("<",ens,":",etg," ",ats,"/>")
-   else
-    handle("<",ens,":",etg,"/>")
-   end
-  end
- else
-  if n and n>0 then
-   if ats then
-    handle("<",etg," ",ats,">")
-   else
-    handle("<",etg,">")
-   end
-   for i=1,n do
-    local e=edt[i]
-    if type(e)=="string" then
-     handle(escaped(e)) 
+    if n and n>0 then
+      if ats then
+        handle("<",etg," ",ats,">")
+      else
+        handle("<",etg,">")
+      end
+      for i=1,n do
+        local e=edt[i]
+        if type(e)=="string" then
+          handle(escaped(e)) 
+        else
+          serialize(e,handlers)
+        end
+      end
+      handle("</",etg,">")
     else
-     serialize(e,handlers)
+      if ats then
+        handle("<",etg," ",ats,"/>")
+      else
+        handle("<",etg,"/>")
+      end
     end
-   end
-   handle("</",etg,">")
-  else
-   if ats then
-    handle("<",etg," ",ats,"/>")
-   else
-    handle("<",etg,"/>")
-   end
   end
- end
 end
 local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+  handlers.handle("<?",e.dt[1],"?>")
 end
 local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+  handlers.handle("<!--",e.dt[1],"-->")
 end
 local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+  handlers.handle("<![CDATA[",e.dt[1],"]]>")
 end
 local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">") 
+  handlers.handle("<!DOCTYPE",e.dt[1],">") 
 end
 local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+  handlers.serialize(e.dt,handlers)
 end
 local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+  handlers.handle(escaped(e))
 end
 local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
-  local ei=e[i]
-  if type(ei)=="string" then
-   functions["@tx@"](ei,handlers)
-  else
-   serialize(ei,handlers)
+  local serialize=handlers.serialize
+  local functions=handlers.functions
+  for i=1,#e do
+    local ei=e[i]
+    if type(ei)=="string" then
+      functions["@tx@"](ei,handlers)
+    else
+      serialize(ei,handlers)
+    end
   end
- end
 end
 local function serialize(e,handlers,...)
- if e then
-  local initialize=handlers.initialize
-  local finalize=handlers.finalize
-  local functions=handlers.functions
-  if initialize then
-   local state=initialize(...)
-   if not state==true then
-    return state
-   end
+  if e then
+    local initialize=handlers.initialize
+    local finalize=handlers.finalize
+    local functions=handlers.functions
+    if initialize then
+      local state=initialize(...)
+      if not state==true then
+        return state
+      end
+    end
+    local etg=e.tg
+    if etg then
+      (functions[etg] or functions["@el@"])(e,handlers)
+    else
+      functions["@dc@"](e,handlers) 
+    end
+    if finalize then
+      return finalize()
+    end
   end
-  local etg=e.tg
-  if etg then
-   (functions[etg] or functions["@el@"])(e,handlers)
-  else
-   functions["@dc@"](e,handlers) 
-  end
-  if finalize then
-   return finalize()
-  end
- end
 end
 local function xserialize(e,handlers)
- if e then
-  local functions=handlers.functions
-  local etg=e.tg
-  if etg then
-   (functions[etg] or functions["@el@"])(e,handlers)
-  else
-   functions["@dc@"](e,handlers)
+  if e then
+    local functions=handlers.functions
+    local etg=e.tg
+    if etg then
+      (functions[etg] or functions["@el@"])(e,handlers)
+    else
+      functions["@dc@"](e,handlers)
+    end
   end
- end
 end
 local handlers={}
 local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {}) 
- if settings then
-  for k,v in next,settings do
-   if type(v)=="table" then
-    local tk=t[k] if not tk then tk={} t[k]=tk end
-    for kk,vv in next,v do
-     tk[kk]=vv
+  local t=table.copy(handlers[settings and settings.parent or "verbose"] or {}) 
+  if settings then
+    for k,v in next,settings do
+      if type(v)=="table" then
+        local tk=t[k] if not tk then tk={} t[k]=tk end
+        for kk,vv in next,v do
+          tk[kk]=vv
+        end
+      else
+        t[k]=v
+      end
     end
-   else
-    t[k]=v
-   end
+    if settings.name then
+      handlers[settings.name]=t
+    end
   end
-  if settings.name then
-   handlers[settings.name]=t
-  end
- end
- utilities.storage.mark(t)
- return t
+  utilities.storage.mark(t)
+  return t
 end
 local nofunction=function() end
 function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+  handler.functions[name]=fnc or nofunction
 end
 function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+  return handler.functions[name]
 end
 function xml.gethandlers(name)
- return handlers[name]
+  return handlers[name]
 end
 newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
-  ["@dc@"]=verbose_document,
-  ["@dt@"]=verbose_doctype,
-  ["@rt@"]=verbose_root,
-  ["@el@"]=verbose_element,
-  ["@pi@"]=verbose_pi,
-  ["@cm@"]=verbose_comment,
-  ["@cd@"]=verbose_cdata,
-  ["@tx@"]=verbose_text,
- }
+  name="verbose",
+  initialize=false,
+  finalize=false,
+  serialize=xserialize,
+  handle=print,
+  functions={
+    ["@dc@"]=verbose_document,
+    ["@dt@"]=verbose_doctype,
+    ["@rt@"]=verbose_root,
+    ["@el@"]=verbose_element,
+    ["@pi@"]=verbose_pi,
+    ["@cm@"]=verbose_comment,
+    ["@cd@"]=verbose_cdata,
+    ["@tx@"]=verbose_text,
+  }
 }
 local result
 local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
-  result=io.open(name,"wb")
-  return result
- end,
- finalize=function()
-  result:close()
-  return true
- end,
- handle=function(...)
-  result:write(...)
- end,
+  name="file",
+  initialize=function(name)
+    result=io.open(name,"wb")
+    return result
+  end,
+  finalize=function()
+    result:close()
+    return true
+  end,
+  handle=function(...)
+    result:write(...)
+  end,
 }
 function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+  serialize(root,xmlfilehandler,name)
 end
 local result,r,threshold={},0,512
 local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
-  r=0
-  return result
- end,
- finalize=function()
-  local done=concat(result,"",1,r)
-  r=0
-  if r>threshold then
-   result={}
-  end
-  return done
- end,
- handle=function(...)
-  for i=1,select("#",...) do
-   r=r+1
-   result[r]=select(i,...)
-  end
- end,
+  name="string",
+  initialize=function()
+    r=0
+    return result
+  end,
+  finalize=function()
+    local done=concat(result,"",1,r)
+    r=0
+    if r>threshold then
+      result={}
+    end
+    return done
+  end,
+  handle=function(...)
+    for i=1,select("#",...) do
+      r=r+1
+      result[r]=select(i,...)
+    end
+  end,
 }
 local function xmltostring(root) 
- if not root then
-  return ""
- elseif type(root)=="string" then
-  return root
- else 
-  return serialize(root,xmlstringhandler) or ""
- end
+  if not root then
+    return ""
+  elseif type(root)=="string" then
+    return root
+  else 
+    return serialize(root,xmlstringhandler) or ""
+  end
 end
 local function __tostring(root) 
- return (root and xmltostring(root)) or ""
+  return (root and xmltostring(root)) or ""
 end
 initialize_mt=function(root) 
- mt={ __tostring=__tostring,__index=root }
+  mt={ __tostring=__tostring,__index=root }
 end
 xml.defaulthandlers=handlers
 xml.newhandlers=newhandlers
@@ -16931,126 +13442,126 @@
 xml.serialize=serialize
 xml.tostring=xmltostring
 local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
-  local edt=e.dt
-  if edt then
-   for i=1,#edt do
-    xmlstring(edt[i],handle)
-   end
+  if not handle or (e.special and e.tg~="@rt@") then
+  elseif e.tg then
+    local edt=e.dt
+    if edt then
+      for i=1,#edt do
+        xmlstring(edt[i],handle)
+      end
+    end
+  else
+    handle(e)
   end
- else
-  handle(e)
- end
 end
 xml.string=xmlstring
 function xml.settings(e)
- while e do
-  local s=e.settings
-  if s then
-   return s
-  else
-   e=e.__p__
+  while e do
+    local s=e.settings
+    if s then
+      return s
+    else
+      e=e.__p__
+    end
   end
- end
- return nil
+  return nil
 end
 function xml.root(e)
- local r=e
- while e do
-  e=e.__p__
-  if e then
-   r=e
+  local r=e
+  while e do
+    e=e.__p__
+    if e then
+      r=e
+    end
   end
- end
- return r
+  return r
 end
 function xml.parent(root)
- return root.__p__
+  return root.__p__
 end
 function xml.body(root)
- return root.ri and root.dt[root.ri] or root 
+  return root.ri and root.dt[root.ri] or root 
 end
 function xml.name(root)
- if not root then
-  return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
-  return tg
- else
-  return ns..":"..tg
- end
+  if not root then
+    return ""
+  end
+  local ns=root.ns
+  local tg=root.tg
+  if ns=="" then
+    return tg
+  else
+    return ns..":"..tg
+  end
 end
 function xml.erase(dt,k)
- if dt then
-  if k then
-   dt[k]=""
-  else for k=1,#dt do
-   dt[1]={ "" }
-  end end
- end
+  if dt then
+    if k then
+      dt[k]=""
+    else for k=1,#dt do
+      dt[1]={ "" }
+    end end
+  end
 end
 function xml.assign(dt,k,root)
- if dt and k then
-  dt[k]=type(root)=="table" and xml.body(root) or root
-  return dt[k]
- else
-  return xml.body(root)
- end
+  if dt and k then
+    dt[k]=type(root)=="table" and xml.body(root) or root
+    return dt[k]
+  else
+    return xml.body(root)
+  end
 end
 function xml.tocdata(e,wrapper) 
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
-  whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+  local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+  if wrapper then
+    whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+  end
+  local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+  setmetatable(t,getmetatable(e))
+  e.dt={ t }
 end
 function xml.makestandalone(root)
- if root.ri then
-  local dt=root.dt
-  for k=1,#dt do
-   local v=dt[k]
-   if type(v)=="table" and v.special and v.tg=="@pi@" then
-    local txt=v.dt[1]
-    if find(txt,"xml.*version=") then
-     v.dt[1]=txt.." standalone='yes'"
-     break
+  if root.ri then
+    local dt=root.dt
+    for k=1,#dt do
+      local v=dt[k]
+      if type(v)=="table" and v.special and v.tg=="@pi@" then
+        local txt=v.dt[1]
+        if find(txt,"xml.*version=") then
+          v.dt[1]=txt.." standalone='yes'"
+          break
+        end
+      end
     end
-   end
   end
- end
- return root
+  return root
 end
 function xml.kind(e)
- local dt=e and e.dt
- if dt then
-  local n=#dt
-  if n==1 then
-   local d=dt[1]
-   if d.special then
-    local tg=d.tg
-    if tg=="@cd@" then
-     return "cdata"
-    elseif tg=="@cm" then
-     return "comment"
-    elseif tg=="@pi@" then
-     return "instruction"
-    elseif tg=="@dt@" then
-     return "declaration"
+  local dt=e and e.dt
+  if dt then
+    local n=#dt
+    if n==1 then
+      local d=dt[1]
+      if d.special then
+        local tg=d.tg
+        if tg=="@cd@" then
+          return "cdata"
+        elseif tg=="@cm" then
+          return "comment"
+        elseif tg=="@pi@" then
+          return "instruction"
+        elseif tg=="@dt@" then
+          return "declaration"
+        end
+      elseif type(d)=="string" then
+        return "text"
+      end
+      return "element"
+    elseif n>0 then
+      return "mixed"
     end
-   elseif type(d)=="string" then
-    return "text"
-   end
-   return "element"
-  elseif n>0 then
-   return "mixed"
   end
- end
- return "empty"
+  return "empty"
 end
 
 
@@ -17060,14 +13571,14 @@
 
 package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
 
--- original size: 55145, stripped down to: 30992
+-- original size: 53301, stripped down to: 32477
 
 if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="this module is the basis for the lxml-* ones",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local concat,remove,insert=table.concat,table.remove,table.insert
 local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -17080,21 +13591,21 @@
 local trace_lprofile=false
 local report_lpath=logs.reporter("xml","lpath")
 if trackers then
- trackers.register("xml.path",function(v)
-  trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
-  trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
-  trace_lpath=v
-  trace_lparse=v
-  trace_lprofile=v
- end)
+  trackers.register("xml.path",function(v)
+    trace_lpath=v
+  end)
+  trackers.register("xml.parse",function(v)
+    trace_lparse=v
+  end)
+  trackers.register("xml.profile",function(v)
+    trace_lpath=v
+    trace_lparse=v
+    trace_lprofile=v
+  end)
 end
 local xml=xml
-local lpathcalls=0  function xml.lpathcalls () return lpathcalls  end
-local lpathcached=0  function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
 xml.functions=xml.functions or {} 
 local functions=xml.functions
 xml.expressions=xml.expressions or {} 
@@ -17108,14 +13619,14 @@
 finalizers.xml=finalizers.xml or {}
 finalizers.tex=finalizers.tex or {}
 local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
-  t[name]=fn
- else
-  report_lpath("unknown sub finalizer %a",name)
-  fn=function() end
- end
- return fn
+  local fn=finalizers[name]
+  if fn then
+    t[name]=fn
+  else
+    report_lpath("unknown sub finalizer %a",name)
+    fn=function() end
+  end
+  return fn
 end
 setmetatableindex(finalizers.xml,fallback)
 setmetatableindex(finalizers.tex,fallback)
@@ -17122,257 +13633,202 @@
 xml.defaultprotocol="xml"
 local apply_axis={}
 apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
-  local ll=list[l]
-  local rt=ll
-  while ll do
-   ll=ll.__p__
-   if ll then
-    rt=ll
-   end
+  local collected={}
+  for l=1,#list do
+    local ll=list[l]
+    local rt=ll
+    while ll do
+      ll=ll.__p__
+      if ll then
+        rt=ll
+      end
+    end
+    collected[l]=rt
   end
-  collected[l]=rt
- end
- return collected
+  return collected
 end
 apply_axis['self']=function(list)
- return list
+  return list
 end
 apply_axis['child']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  local dt=ll.dt
-  if dt then 
-   local n=#dt
-   if n==0 then
-    ll.en=0
-   elseif n==1 then
-    local dk=dt[1]
-    if dk.tg then
-     c=c+1
-     collected[c]=dk
-     dk.ni=1 
-     dk.ei=1
-     ll.en=1
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
+    local dt=ll.dt
+    if dt then 
+      local en=0
+      for k=1,#dt do
+        local dk=dt[k]
+        if dk.tg then
+          c=c+1
+          collected[c]=dk
+          dk.ni=k 
+          en=en+1
+          dk.ei=en
+        end
+      end
+      ll.en=en
     end
-   else
-    local en=0
-    for k=1,#dt do
-     local dk=dt[k]
-     if dk.tg then
-      c=c+1
-      en=en+1
-      collected[c]=dk
-      dk.ni=k 
-      dk.ei=en
-     end
-    end
-    ll.en=en
-   end
   end
- end
- return collected
+  return collected
 end
 local function collect(list,collected,c)
- local dt=list.dt
- if dt then
-  local n=#dt
-  if n==0 then
-   list.en=0
-  elseif n==1 then
-   local dk=dt[1]
-   if dk.tg then
-    c=c+1
-    collected[c]=dk
-    dk.ni=1 
-    dk.ei=1
-    c=collect(dk,collected,c)
-    list.en=1
-   else
-    list.en=0
-   end
-  else
-   local en=0
-   for k=1,n do
-    local dk=dt[k]
-    if dk.tg then
-     c=c+1
-     en=en+1
-     collected[c]=dk
-     dk.ni=k 
-     dk.ei=en
-     c=collect(dk,collected,c)
+  local dt=list.dt
+  if dt then
+    local en=0
+    for k=1,#dt do
+      local dk=dt[k]
+      if dk.tg then
+        c=c+1
+        collected[c]=dk
+        dk.ni=k 
+        en=en+1
+        dk.ei=en
+        c=collect(dk,collected,c)
+      end
     end
-   end
-   list.en=en
+    list.en=en
   end
- end
- return c
+  return c
 end
 apply_axis['descendant']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  c=collect(list[l],collected,c)
- end
- return collected
+  local collected,c={},0
+  for l=1,#list do
+    c=collect(list[l],collected,c)
+  end
+  return collected
 end
 local function collect(list,collected,c)
- local dt=list.dt
- if dt then
-  local n=#dt
-  if n==0 then
-   list.en=0
-  elseif n==1 then
-   local dk=dt[1]
-   if dk.tg then
-    c=c+1
-    collected[c]=dk
-    dk.ni=1 
-    dk.ei=1
-    c=collect(dk,collected,c)
-    list.en=1
-   end
-  else
-   local en=0
-   for k=1,#dt do
-    local dk=dt[k]
-    if dk.tg then
-     c=c+1
-     en=en+1
-     collected[c]=dk
-     dk.ni=k 
-     dk.ei=en
-     c=collect(dk,collected,c)
+  local dt=list.dt
+  if dt then
+    local en=0
+    for k=1,#dt do
+      local dk=dt[k]
+      if dk.tg then
+        c=c+1
+        collected[c]=dk
+        dk.ni=k 
+        en=en+1
+        dk.ei=en
+        c=collect(dk,collected,c)
+      end
     end
-   end
-   list.en=en
+    list.en=en
   end
- end
- return c
+  return c
 end
 apply_axis['descendant-or-self']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  if ll.special~=true then 
-   c=c+1
-   collected[c]=ll
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
+    if ll.special~=true then 
+      c=c+1
+      collected[c]=ll
+    end
+    c=collect(ll,collected,c)
   end
-  c=collect(ll,collected,c)
- end
- return collected
+  return collected
 end
 apply_axis['ancestor']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  while ll do
-   ll=ll.__p__
-   if ll then
-    c=c+1
-    collected[c]=ll
-   end
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
+    while ll do
+      ll=ll.__p__
+      if ll then
+        c=c+1
+        collected[c]=ll
+      end
+    end
   end
- end
- return collected
+  return collected
 end
 apply_axis['ancestor-or-self']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  c=c+1
-  collected[c]=ll
-  while ll do
-   ll=ll.__p__
-   if ll then
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
     c=c+1
     collected[c]=ll
-   end
+    while ll do
+      ll=ll.__p__
+      if ll then
+        c=c+1
+        collected[c]=ll
+      end
+    end
   end
- end
- return collected
+  return collected
 end
 apply_axis['parent']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local pl=list[l].__p__
-  if pl then
-   c=c+1
-   collected[c]=pl
+  local collected,c={},0
+  for l=1,#list do
+    local pl=list[l].__p__
+    if pl then
+      c=c+1
+      collected[c]=pl
+    end
   end
- end
- return collected
+  return collected
 end
 apply_axis['attribute']=function(list)
- return {}
+  return {}
 end
 apply_axis['namespace']=function(list)
- return {}
+  return {}
 end
 apply_axis['following']=function(list)
- return {}
+  return {}
 end
 apply_axis['preceding']=function(list)
- return {}
+  return {}
 end
 apply_axis['following-sibling']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  local p=ll.__p__
-  local d=p.dt
-  for i=ll.ni+1,#d do
-   local di=d[i]
-   if type(di)=="table" then
-    c=c+1
-    collected[c]=di
-   end
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
+    local p=ll.__p__
+    local d=p.dt
+    for i=ll.ni+1,#d do
+      local di=d[i]
+      if type(di)=="table" then
+        c=c+1
+        collected[c]=di
+      end
+    end
   end
- end
- return collected
+  return collected
 end
 apply_axis['preceding-sibling']=function(list)
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  local p=ll.__p__
-  local d=p.dt
-  for i=1,ll.ni-1 do
-   local di=d[i]
-   if type(di)=="table" then
-    c=c+1
-    collected[c]=di
-   end
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
+    local p=ll.__p__
+    local d=p.dt
+    for i=1,ll.ni-1 do
+      local di=d[i]
+      if type(di)=="table" then
+        c=c+1
+        collected[c]=di
+      end
+    end
   end
- end
- return collected
+  return collected
 end
 apply_axis['reverse-sibling']=function(list) 
- local collected={}
- local c=0
- for l=1,#list do
-  local ll=list[l]
-  local p=ll.__p__
-  local d=p.dt
-  for i=ll.ni-1,1,-1 do
-   local di=d[i]
-   if type(di)=="table" then
-    c=c+1
-    collected[c]=di
-   end
+  local collected,c={},0
+  for l=1,#list do
+    local ll=list[l]
+    local p=ll.__p__
+    local d=p.dt
+    for i=ll.ni-1,1,-1 do
+      local di=d[i]
+      if type(di)=="table" then
+        c=c+1
+        collected[c]=di
+      end
+    end
   end
- end
- return collected
+  return collected
 end
 apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
 apply_axis['auto-descendant']=apply_axis['descendant']
@@ -17380,148 +13836,131 @@
 apply_axis['auto-self']=apply_axis['self']
 apply_axis['initial-child']=apply_axis['child']
 local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then 
-  local nns=nodes[2]
-  local ntg=nodes[3]
-  if not nns and not ntg then 
-   if directive then
-    return list
-   else
-    return {}
-   end
-  else
-   local collected={}
-   local c=0
-   local m=0
-   local p=nil
-   if not nns then 
-    for l=1,#list do
-     local ll=list[l]
-     local ltg=ll.tg
-     if ltg then
+  local maxn=#nodes
+  if maxn==3 then 
+    local nns,ntg=nodes[2],nodes[3]
+    if not nns and not ntg then 
       if directive then
-       if ntg==ltg then
-        local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-        c=c+1
-        collected[c]=ll
-        ll.mi=m
-       end
-      elseif ntg~=ltg then
-       local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-       c=c+1
-       collected[c]=ll
-       ll.mi=m
+        return list
+      else
+        return {}
       end
-     end
-    end
-   elseif not ntg then 
-    for l=1,#list do
-     local ll=list[l]
-     local lns=ll.rn or ll.ns
-     if lns then
-      if directive then
-       if lns==nns then
-        local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-        c=c+1
-        collected[c]=ll
-        ll.mi=m
-       end
-      elseif lns~=nns then
-       local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-       c=c+1
-       collected[c]=ll
-       ll.mi=m
+    else
+      local collected,c,m,p={},0,0,nil
+      if not nns then 
+        for l=1,#list do
+          local ll=list[l]
+          local ltg=ll.tg
+          if ltg then
+            if directive then
+              if ntg==ltg then
+                local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+                c=c+1
+                collected[c],ll.mi=ll,m
+              end
+            elseif ntg~=ltg then
+              local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+              c=c+1
+              collected[c],ll.mi=ll,m
+            end
+          end
+        end
+      elseif not ntg then 
+        for l=1,#list do
+          local ll=list[l]
+          local lns=ll.rn or ll.ns
+          if lns then
+            if directive then
+              if lns==nns then
+                local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+                c=c+1
+                collected[c],ll.mi=ll,m
+              end
+            elseif lns~=nns then
+              local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+              c=c+1
+              collected[c],ll.mi=ll,m
+            end
+          end
+        end
+      else 
+        for l=1,#list do
+          local ll=list[l]
+          local ltg=ll.tg
+          if ltg then
+            local lns=ll.rn or ll.ns
+            local ok=ltg==ntg and lns==nns
+            if directive then
+              if ok then
+                local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+                c=c+1
+                collected[c],ll.mi=ll,m
+              end
+            elseif not ok then
+              local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+              c=c+1
+              collected[c],ll.mi=ll,m
+            end
+          end
+        end
       end
-     end
+      return collected
     end
-   else 
+  else
+    local collected,c,m,p={},0,0,nil
     for l=1,#list do
-     local ll=list[l]
-     local ltg=ll.tg
-     if ltg then
-      local lns=ll.rn or ll.ns
-      local ok=ltg==ntg and lns==nns
-      if directive then
-       if ok then
-        local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-        c=c+1
-        collected[c]=ll
-        ll.mi=m
-       end
-      elseif not ok then
-       local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-       c=c+1
-       collected[c]=ll
-       ll.mi=m
+      local ll=list[l]
+      local ltg=ll.tg
+      if ltg then
+        local lns=ll.rn or ll.ns
+        local ok=false
+        for n=1,maxn,3 do
+          local nns,ntg=nodes[n+1],nodes[n+2]
+          ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
+          if ok then
+            break
+          end
+        end
+        if directive then
+          if ok then
+            local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+            c=c+1
+            collected[c],ll.mi=ll,m
+          end
+        elseif not ok then
+          local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+          c=c+1
+          collected[c],ll.mi=ll,m
+        end
       end
-     end
     end
-   end
-   return collected
+    return collected
   end
- else
-  local collected={}
-  local c=0
-  local m=0
-  local p=nil
+end
+local quit_expression=false
+local function apply_expression(list,expression,order)
+  local collected,c={},0
+  quit_expression=false
   for l=1,#list do
-   local ll=list[l]
-   local ltg=ll.tg
-   if ltg then
-    local lns=ll.rn or ll.ns
-    local ok=false
-    for n=1,maxn,3 do
-     local nns=nodes[n+1]
-     local ntg=nodes[n+2]
-     ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
-     if ok then
-      break
-     end
-    end
-    if directive then
-     if ok then
-      local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+    local ll=list[l]
+    if expression(list,ll,l,order) then 
       c=c+1
       collected[c]=ll
-      ll.mi=m
-     end
-    elseif not ok then
-     local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
-     c=c+1
-     collected[c]=ll
-     ll.mi=m
     end
-   end
+    if quit_expression then
+      break
+    end
   end
   return collected
- end
 end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected={}
- local c=0
- quit_expression=false
- for l=1,#list do
-  local ll=list[l]
-  if expression(list,ll,l,order) then 
-   c=c+1
-   collected[c]=ll
+local function apply_selector(list,specification)
+  if xml.applyselector then
+    apply_selector=xml.applyselector
+    return apply_selector(list,specification)
+  else
+    return list
   end
-  if quit_expression then
-   break
-  end
- end
- return collected
 end
-local function apply_selector(list,specification)
- if xml.applyselector then
-  apply_selector=xml.applyselector
-  return apply_selector(list,specification)
- else
-  return list
- end
-end
 local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
 local spaces=S(" \n\r\t\f")^0
 local lp_space=S(" \n\r\t\f")
@@ -17531,24 +13970,24 @@
 local lp_or=P("|")/" or "
 local lp_and=P("&")/" and "
 local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+  text="(ll.dt[1] or '')",
+  content="ll.dt",
+  name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+  tag="ll.tg",
+  position="l",
+  firstindex="1",
+  firstelement="1",
+  first="1",
+  lastindex="(#ll.__p__.dt or 1)",
+  lastelement="(ll.__p__.en or 1)",
+  last="#list",
+  rootposition="order",
+  order="order",
+  element="(ll.ei or 1)",
+  index="(ll.ni or 1)",
+  match="(ll.mi or 1)",
+  namespace="ll.ns",
+  ns="ll.ns",
 }
 local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
 local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -17558,11 +13997,11 @@
 local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
 local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
 local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t) 
- if expressions[t] then
-  return "expr."..t.."("
- else
-  return "expr.error("
- end
+  if expressions[t] then
+    return "expr."..t.."("
+  else
+    return "expr.error("
+  end
 end
 local lparent=P("(")
 local rparent=P(")")
@@ -17575,24 +14014,24 @@
 local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
 local cleaner
 local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
-  s=s and s~="" and lpegmatch(cleaner,s)
-  if s and s~="" then
-   return "expr."..t.."(ll,"..s..")"
+  if expressions[t] then
+    s=s and s~="" and lpegmatch(cleaner,s)
+    if s and s~="" then
+      return "expr."..t.."(ll,"..s..")"
+    else
+      return "expr."..t.."(ll)"
+    end
   else
-   return "expr."..t.."(ll)"
+    return "expr.error("..t..")"
   end
- else
-  return "expr.error("..t..")"
- end
 end
 local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+  lp_child+lp_any
 local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+  lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
 )
 cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+  lp_reserved+lp_number+lp_string+1 )^1 )
 local template_e=[[
     local expr = xml.expressions
     return function(list,ll,l,order)
@@ -17608,75 +14047,75 @@
 local template_f_n=[[
     return xml.finalizers['%s']['%s']
 ]]
-local register_last_match={ kind="axis",axis="last-match"     } 
-local register_self={ kind="axis",axis="self"     } 
-local register_parent={ kind="axis",axis="parent"      } 
-local register_descendant={ kind="axis",axis="descendant"     } 
-local register_child={ kind="axis",axis="child"       } 
+local register_last_match={ kind="axis",axis="last-match"       } 
+local register_self={ kind="axis",axis="self"          } 
+local register_parent={ kind="axis",axis="parent"         } 
+local register_descendant={ kind="axis",axis="descendant"       } 
+local register_child={ kind="axis",axis="child"          } 
 local register_descendant_or_self={ kind="axis",axis="descendant-or-self"   } 
-local register_root={ kind="axis",axis="root"     } 
-local register_ancestor={ kind="axis",axis="ancestor"    } 
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self"  } 
-local register_attribute={ kind="axis",axis="attribute"      } 
-local register_namespace={ kind="axis",axis="namespace"      } 
-local register_following={ kind="axis",axis="following"      } 
+local register_root={ kind="axis",axis="root"          } 
+local register_ancestor={ kind="axis",axis="ancestor"        } 
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self"    } 
+local register_attribute={ kind="axis",axis="attribute"        } 
+local register_namespace={ kind="axis",axis="namespace"        } 
+local register_following={ kind="axis",axis="following"        } 
 local register_following_sibling={ kind="axis",axis="following-sibling"    } 
-local register_preceding={ kind="axis",axis="preceding"      } 
+local register_preceding={ kind="axis",axis="preceding"        } 
 local register_preceding_sibling={ kind="axis",axis="preceding-sibling"    } 
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling"   } 
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling"     } 
 local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" } 
-local register_auto_descendant={ kind="axis",axis="auto-descendant"   } 
-local register_auto_self={ kind="axis",axis="auto-self"      } 
-local register_auto_child={ kind="axis",axis="auto-child"     } 
-local register_initial_child={ kind="axis",axis="initial-child"     } 
+local register_auto_descendant={ kind="axis",axis="auto-descendant"     } 
+local register_auto_self={ kind="axis",axis="auto-self"        } 
+local register_auto_child={ kind="axis",axis="auto-child"       } 
+local register_initial_child={ kind="axis",axis="initial-child"      } 
 local register_all_nodes={ kind="nodes",nodetest=true,nodes={ true,false,false } }
 local skip={}
 local function errorrunner_e(str,cnv)
- if not skip[str] then
-  report_lpath("error in expression: %s => %s",str,cnv)
-  skip[str]=cnv or str
- end
- return false
+  if not skip[str] then
+    report_lpath("error in expression: %s => %s",str,cnv)
+    skip[str]=cnv or str
+  end
+  return false
 end
 local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+  report_lpath("error in finalizer: %s(%s)",str,arg or "")
+  return false
 end
 local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+  return { kind="nodes",nodetest=nodetest,nodes=nodes }
 end
 local function register_selector(specification)
- return { kind="selector",specification=specification }
+  return { kind="selector",specification=specification }
 end
 local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+  local converted=lpegmatch(converter,expression)
+  local runner=load(format(template_e,converted))
+  runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+  return { kind="expression",expression=expression,converted=converted,evaluator=runner }
 end
 local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
-  runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
-  runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+  local runner
+  if arguments and arguments~="" then
+    runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+  else
+    runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+  end
+  runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+  return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
 end
 local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+  ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+  sq="'"*(1-S("'"))^0*"'",
+  dq='"'*(1-S('"'))^0*'"',
 }
 local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+  ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+  nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+  sq=P("'")*(1-P("'"))^0*P("'"),
+  dq=P('"')*(1-P('"'))^0*P('"'),
 }
 local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+  return { kind="error",error=format("unparsed: %s",str) }
 end
 local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes) 
 local special_2=P("/")*Cc(register_auto_self)
@@ -17684,368 +14123,367 @@
 local no_nextcolon=P(-1)+#(1-P(":")) 
 local no_nextlparent=P(-1)+#(1-P("(")) 
 local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
-         (V("special")*spaces*P(-1)               )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
-         ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+  patterns=spaces*V("protocol")*spaces*(
+               (V("special")*spaces*P(-1)                             )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+              ),
+  protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+  step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+  axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+  special=special_1+special_2+special_3,
+  initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+  error=(P(1)^1)/register_error,
+  shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+  shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+  s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+  s_descendant=P("**")*Cc(register_descendant),
+  s_child=P("*")*no_nextcolon*Cc(register_child),
+  s_parent=P("..")*Cc(register_parent),
+  s_self=P("." )*Cc(register_self),
+  s_root=P("^^")*Cc(register_root),
+  s_ancestor=P("^")*Cc(register_ancestor),
+  s_lastmatch=P("=")*Cc(register_last_match),
+  descendant=P("descendant::")*Cc(register_descendant),
+  child=P("child::")*Cc(register_child),
+  parent=P("parent::")*Cc(register_parent),
+  self=P("self::")*Cc(register_self),
+  root=P('root::')*Cc(register_root),
+  ancestor=P('ancestor::')*Cc(register_ancestor),
+  descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+  ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+  following=P('following::')*Cc(register_following),
+  following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+  preceding=P('preceding::')*Cc(register_preceding),
+  preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+  reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+  last_match=P('last-match::')*Cc(register_last_match),
+  selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+  nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+  expressions=expression/register_expression,
+  letters=R("az")^1,
+  name=(1-S("/[]()|:*!"))^1,
+  negate=P("!")*Cc(false),
+  nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+  nodetest=V("negate")+Cc(true),
+  nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+  wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+  nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+  finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
 }
 xmlpatterns.pathparser=pathparser
 local cache={}
 local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
-  local directive,ns,tg=set[i],set[i+1],set[i+2]
-  if not ns or ns=="" then ns="*" end
-  if not tg or tg=="" then tg="*" end
-  tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
-  t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
-  return format("not(%s)",concat(t,"|"))
- else
-  return concat(t,"|")
- end
+  local t={}
+  for i=1,#set,3 do
+    local directive,ns,tg=set[i],set[i+1],set[i+2]
+    if not ns or ns=="" then ns="*" end
+    if not tg or tg=="" then tg="*" end
+    tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+    t[#t+1]=(directive and tg) or format("not(%s)",tg)
+  end
+  if nodetest==false then
+    return format("not(%s)",concat(t,"|"))
+  else
+    return concat(t,"|")
+  end
 end
 local function tagstostring(list)
- if #list==0 then
-  return "no elements"
- else
-  local t={}
-  for i=1,#list do
-   local li=list[i]
-   local ns=li.ns
-   local tg=li.tg
-   if not ns or ns=="" then ns="*" end
-   if not tg or tg=="" then tg="*" end
-   t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+  if #list==0 then
+    return "no elements"
+  else
+    local t={}
+    for i=1,#list do
+      local li=list[i]
+      local ns,tg=li.ns,li.tg
+      if not ns or ns=="" then ns="*" end
+      if not tg or tg=="" then tg="*" end
+      t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+    end
+    return concat(t," ")
   end
-  return concat(t," ")
- end
 end
 xml.nodesettostring=nodesettostring
 local lpath 
 local function lshow(parsed)
- if type(parsed)=="string" then
-  parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
-  table.serialize(parsed,false))
+  if type(parsed)=="string" then
+    parsed=lpath(parsed)
+  end
+  report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+    table.serialize(parsed,false))
 end
 xml.lshow=lshow
 local function add_comment(p,str)
- local pc=p.comment
- if not pc then
-  p.comment={ str }
- else
-  pc[#pc+1]=str
- end
+  local pc=p.comment
+  if not pc then
+    p.comment={ str }
+  else
+    pc[#pc+1]=str
+  end
 end
 lpath=function (pattern) 
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
-  return pattern
- else
-  local parsed=cache[pattern]
-  if parsed then
-   lpathcached=lpathcached+1
+  lpathcalls=lpathcalls+1
+  if type(pattern)=="table" then
+    return pattern
   else
-   parsed=lpegmatch(pathparser,pattern)
-   if parsed then
-    parsed.pattern=pattern
-    local np=#parsed
-    if np==0 then
-     parsed={ pattern=pattern,register_self,state="parsing error" }
-     report_lpath("parsing error in pattern: %s",pattern)
-     lshow(parsed)
+    local parsed=cache[pattern]
+    if parsed then
+      lpathcached=lpathcached+1
     else
-     local pi=parsed[1]
-     if pi.axis=="auto-child" then
-      if false then
-       add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
-       parsed[1]=register_auto_descendant_or_self
+      parsed=lpegmatch(pathparser,pattern)
+      if parsed then
+        parsed.pattern=pattern
+        local np=#parsed
+        if np==0 then
+          parsed={ pattern=pattern,register_self,state="parsing error" }
+          report_lpath("parsing error in pattern: %s",pattern)
+          lshow(parsed)
+        else
+          local pi=parsed[1]
+          if pi.axis=="auto-child" then
+            if false then
+              add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+              parsed[1]=register_auto_descendant_or_self
+            else
+              add_comment(parsed,"auto-child replaced by auto-descendant")
+              parsed[1]=register_auto_descendant
+            end
+          elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+            add_comment(parsed,"initial-child removed") 
+            remove(parsed,1)
+          end
+          local np=#parsed 
+          if np>1 then
+            local pnp=parsed[np]
+            if pnp.kind=="nodes" and pnp.nodetest==true then
+              local nodes=pnp.nodes
+              if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+                add_comment(parsed,"redundant final wildcard filter removed")
+                remove(parsed,np)
+              end
+            end
+          end
+        end
       else
-       add_comment(parsed,"auto-child replaced by auto-descendant")
-       parsed[1]=register_auto_descendant
+        parsed={ pattern=pattern }
       end
-     elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
-      add_comment(parsed,"initial-child removed") 
-      remove(parsed,1)
-     end
-     local np=#parsed 
-     if np>1 then
-      local pnp=parsed[np]
-      if pnp.kind=="nodes" and pnp.nodetest==true then
-       local nodes=pnp.nodes
-       if nodes[1]==true and nodes[2]==false and nodes[3]==false then
-        add_comment(parsed,"redundant final wildcard filter removed")
-        remove(parsed,np)
-       end
+      cache[pattern]=parsed
+      if trace_lparse and not trace_lprofile then
+        lshow(parsed)
       end
-     end
     end
-   else
-    parsed={ pattern=pattern }
-   end
-   cache[pattern]=parsed
-   if trace_lparse and not trace_lprofile then
-    lshow(parsed)
-   end
+    return parsed
   end
-  return parsed
- end
 end
 xml.lpath=lpath
 do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil  
- local keepmatch=nil  
- if directives then
-  directives.register("xml.path.keeplastmatch",function(v)
-   keepmatch=v
-   lastmatch=nil
-  end)
- end
- apply_axis["last-match"]=function()
-  return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
-  local p=profiled[parsed.pattern]
-  if p then
-   p.tested=p.tested+1
-  else
-   p={ tested=1,matched=0,finalized=0 }
-   profiled[parsed.pattern]=p
+  local profiled={}
+  xml.profiled=profiled
+  local lastmatch=nil 
+  local keepmatch=nil 
+  if directives then
+    directives.register("xml.path.keeplastmatch",function(v)
+      keepmatch=v
+      lastmatch=nil
+    end)
   end
-  local collected=list
-  for i=1,nofparsed do
-   local pi=parsed[i]
-   local kind=pi.kind
-   if kind=="axis" then
-    collected=apply_axis[pi.axis](collected)
-   elseif kind=="nodes" then
-    collected=apply_nodes(collected,pi.nodetest,pi.nodes)
-   elseif kind=="expression" then
-    collected=apply_expression(collected,pi.evaluator,order)
-   elseif kind=="selector" then
-    collected=apply_selector(collected,pi.specification)
-   elseif kind=="finalizer" then
-    collected=pi.finalizer(collected) 
-    p.matched=p.matched+1
-    p.finalized=p.finalized+1
+  apply_axis["last-match"]=function()
+    return lastmatch or {}
+  end
+  local function profiled_apply(list,parsed,nofparsed,order)
+    local p=profiled[parsed.pattern]
+    if p then
+      p.tested=p.tested+1
+    else
+      p={ tested=1,matched=0,finalized=0 }
+      profiled[parsed.pattern]=p
+    end
+    local collected=list
+    for i=1,nofparsed do
+      local pi=parsed[i]
+      local kind=pi.kind
+      if kind=="axis" then
+        collected=apply_axis[pi.axis](collected)
+      elseif kind=="nodes" then
+        collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+      elseif kind=="expression" then
+        collected=apply_expression(collected,pi.evaluator,order)
+      elseif kind=="selector" then
+        collected=apply_selector(collected,pi.specification)
+      elseif kind=="finalizer" then
+        collected=pi.finalizer(collected) 
+        p.matched=p.matched+1
+        p.finalized=p.finalized+1
+        return collected
+      end
+      if not collected or #collected==0 then
+        local pn=i<nofparsed and parsed[nofparsed]
+        if pn and pn.kind=="finalizer" then
+          collected=pn.finalizer(collected) 
+          p.finalized=p.finalized+1
+          return collected
+        end
+        return nil
+      end
+    end
+    if collected then
+      p.matched=p.matched+1
+    end
     return collected
-   end
-   if not collected or #collected==0 then
-    local pn=i<nofparsed and parsed[nofparsed]
-    if pn and pn.kind=="finalizer" then
-     collected=pn.finalizer(collected) 
-     p.finalized=p.finalized+1
-     return collected
+  end
+  local function traced_apply(list,parsed,nofparsed,order)
+    if trace_lparse then
+      lshow(parsed)
     end
-    return nil
-   end
+    report_lpath("collecting: %s",parsed.pattern)
+    report_lpath("root tags : %s",tagstostring(list))
+    report_lpath("order     : %s",order or "unset")
+    local collected=list
+    for i=1,nofparsed do
+      local pi=parsed[i]
+      local kind=pi.kind
+      if kind=="axis" then
+        collected=apply_axis[pi.axis](collected)
+        report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+      elseif kind=="nodes" then
+        collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+        report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+      elseif kind=="expression" then
+        collected=apply_expression(collected,pi.evaluator,order)
+        report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+      elseif kind=="selector" then
+        collected=apply_selector(collected,pi.specification)
+        report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+      elseif kind=="finalizer" then
+        collected=pi.finalizer(collected)
+        report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
+        return collected
+      end
+      if not collected or #collected==0 then
+        local pn=i<nofparsed and parsed[nofparsed]
+        if pn and pn.kind=="finalizer" then
+          collected=pn.finalizer(collected)
+          report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+          return collected
+        end
+        return nil
+      end
+    end
+    return collected
   end
-  if collected then
-   p.matched=p.matched+1
+  local function normal_apply(list,parsed,nofparsed,order)
+    local collected=list
+    for i=1,nofparsed do
+      local pi=parsed[i]
+      local kind=pi.kind
+      if kind=="axis" then
+        local axis=pi.axis
+        if axis~="self" then
+          collected=apply_axis[axis](collected)
+        end
+      elseif kind=="nodes" then
+        collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+      elseif kind=="expression" then
+        collected=apply_expression(collected,pi.evaluator,order)
+      elseif kind=="selector" then
+        collected=apply_selector(collected,pi.specification)
+      elseif kind=="finalizer" then
+        return pi.finalizer(collected)
+      end
+      if not collected or #collected==0 then
+        local pf=i<nofparsed and parsed[nofparsed].finalizer
+        if pf then
+          return pf(collected) 
+        end
+        return nil
+      end
+    end
+    return collected
   end
-  return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
-  if trace_lparse then
-   lshow(parsed)
+  local apply=normal_apply
+  if trackers then
+    trackers.register("xml.path,xml.parse,xml.profile",function()
+      if trace_lprofile then
+        apply=profiled_apply
+      elseif trace_lpath then
+        apply=traced_apply
+      else
+        apply=normal_apply
+      end
+    end)
   end
-  report_lpath("collecting: %s",parsed.pattern)
-  report_lpath("root tags : %s",tagstostring(list))
-  report_lpath("order     : %s",order or "unset")
-  local collected=list
-  for i=1,nofparsed do
-   local pi=parsed[i]
-   local kind=pi.kind
-   if kind=="axis" then
-    collected=apply_axis[pi.axis](collected)
-    report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
-   elseif kind=="nodes" then
-    collected=apply_nodes(collected,pi.nodetest,pi.nodes)
-    report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
-   elseif kind=="expression" then
-    collected=apply_expression(collected,pi.evaluator,order)
-    report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
-   elseif kind=="selector" then
-    collected=apply_selector(collected,pi.specification)
-    report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
-   elseif kind=="finalizer" then
-    collected=pi.finalizer(collected)
-    report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
-    return collected
-   end
-   if not collected or #collected==0 then
-    local pn=i<nofparsed and parsed[nofparsed]
-    if pn and pn.kind=="finalizer" then
-     collected=pn.finalizer(collected)
-     report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
-     return collected
+  function xml.applylpath(list,pattern)
+    if not list then
+      lastmatch=nil
+      return
     end
-    return nil
-   end
-  end
-  return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
-  local collected=list
-  for i=1,nofparsed do
-   local pi=parsed[i]
-   local kind=pi.kind
-   if kind=="axis" then
-    local axis=pi.axis
-    if axis~="self" then
-     collected=apply_axis[axis](collected)
+    local parsed=cache[pattern]
+    if parsed then
+      lpathcalls=lpathcalls+1
+      lpathcached=lpathcached+1
+    elseif type(pattern)=="table" then
+      lpathcalls=lpathcalls+1
+      parsed=pattern
+    else
+      parsed=lpath(pattern) or pattern
     end
-   elseif kind=="nodes" then
-    collected=apply_nodes(collected,pi.nodetest,pi.nodes)
-   elseif kind=="expression" then
-    collected=apply_expression(collected,pi.evaluator,order)
-   elseif kind=="selector" then
-    collected=apply_selector(collected,pi.specification)
-   elseif kind=="finalizer" then
-    return pi.finalizer(collected)
-   end
-   if not collected or #collected==0 then
-    local pf=i<nofparsed and parsed[nofparsed].finalizer
-    if pf then
-     return pf(collected) 
+    if not parsed then
+      lastmatch=nil
+      return
     end
-    return nil
-   end
+    local nofparsed=#parsed
+    if nofparsed==0 then
+      lastmatch=nil
+      return 
+    end
+    local collected=apply({ list },parsed,nofparsed,list.mi)
+    lastmatch=keepmatch and collected or nil
+    return collected
   end
-  return collected
- end
- local apply=normal_apply
- if trackers then
-  trackers.register("xml.path,xml.parse,xml.profile",function()
-   if trace_lprofile then
-    apply=profiled_apply
-   elseif trace_lpath then
-    apply=traced_apply
-   else
-    apply=normal_apply
-   end
-  end)
- end
- function xml.applylpath(list,pattern)
-  if not list then
-   lastmatch=nil
-   return
+  function xml.lastmatch()
+    return lastmatch
   end
-  local parsed=cache[pattern]
-  if parsed then
-   lpathcalls=lpathcalls+1
-   lpathcached=lpathcached+1
-  elseif type(pattern)=="table" then
-   lpathcalls=lpathcalls+1
-   parsed=pattern
-  else
-   parsed=lpath(pattern) or pattern
+  local stack={}
+  function xml.pushmatch()
+    insert(stack,lastmatch)
   end
-  if not parsed then
-   lastmatch=nil
-   return
+  function xml.popmatch()
+    lastmatch=remove(stack)
   end
-  local nofparsed=#parsed
-  if nofparsed==0 then
-   lastmatch=nil
-   return 
-  end
-  local collected=apply({ list },parsed,nofparsed,list.mi)
-  lastmatch=keepmatch and collected or nil
-  return collected
- end
- function xml.lastmatch()
-  return lastmatch
- end
- local stack={}
- function xml.pushmatch()
-  insert(stack,lastmatch)
- end
- function xml.popmatch()
-  lastmatch=remove(stack)
- end
 end
 local applylpath=xml.applylpath
 function xml.filter(root,pattern) 
- return applylpath(root,pattern)
+  return applylpath(root,pattern)
 end
 expressions.child=function(e,pattern)
- return applylpath(e,pattern) 
+  return applylpath(e,pattern) 
 end
 expressions.count=function(e,pattern) 
- local collected=applylpath(e,pattern) 
- return pattern and (collected and #collected) or 0
+  local collected=applylpath(e,pattern) 
+  return pattern and (collected and #collected) or 0
 end
 expressions.oneof=function(s,...)
- for i=1,select("#",...) do
-  if s==select(i,...) then
-   return true
+  for i=1,select("#",...) do
+    if s==select(i,...) then
+      return true
+    end
   end
- end
- return false
+  return false
 end
 expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+  xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+  return false
 end
 expressions.undefined=function(s)
- return s==nil
+  return s==nil
 end
 expressions.quit=function(s)
- if s or s==nil then
-  quit_expression=true
- end
- return true
+  if s or s==nil then
+    quit_expression=true
+  end
+  return true
 end
 expressions.print=function(...)
- print(...)
- return true
+  print(...)
+  return true
 end
 expressions.find=find
 expressions.upper=upper
@@ -18053,238 +14491,233 @@
 expressions.number=tonumber
 expressions.boolean=toboolean
 function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
-  if find(str,pattern) then
-   return true
+  local t=type(str)
+  if t=="string" then
+    if find(str,pattern) then
+      return true
+    end
+  elseif t=="table" then
+    for i=1,#str do
+      local d=str[i]
+      if type(d)=="string" and find(d,pattern) then
+        return true
+      end
+    end
   end
- elseif t=="table" then
-  for i=1,#str do
-   local d=str[i]
-   if type(d)=="string" and find(d,pattern) then
-    return true
-   end
-  end
- end
- return false
+  return false
 end
 function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+  return type(str)=="string" and gsub(str,"^#","") or ""
 end
 local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
-  for c=1,#collected do
-   local e=collected[c]
-   local r=e.__p__
-   handle(r,r.dt,e.ni)
+  local collected=applylpath(root,pattern)
+  if collected then
+    for c=1,#collected do
+      local e=collected[c]
+      local r=e.__p__
+      handle(r,r.dt,e.ni)
+    end
   end
- end
 end
 local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
-  if handle then
-   for c=1,#collected do
-    handle(collected[c])
-   end
-  else
-   return collected
+  local collected=applylpath(root,pattern)
+  if collected then
+    if handle then
+      for c=1,#collected do
+        handle(collected[c])
+      end
+    else
+      return collected
+    end
   end
- end
 end
-xml.traverse=traverse     
+xml.traverse=traverse      
 xml.selection=selection
 local function dofunction(collected,fnc,...)
- if collected then
-  local f=functions[fnc]
-  if f then
-   for c=1,#collected do
-    f(collected[c],...)
-   end
-  else
-   report_lpath("unknown function %a",fnc)
+  if collected then
+    local f=functions[fnc]
+    if f then
+      for c=1,#collected do
+        f(collected[c],...)
+      end
+    else
+      report_lpath("unknown function %a",fnc)
+    end
   end
- end
 end
 finalizers.xml["function"]=dofunction
 finalizers.tex["function"]=dofunction
 expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+  local rdt=e.__p__.dt
+  return rdt and rdt[n] or ""
 end
 expressions.name=function(e,n) 
- local found=false
- n=tonumber(n) or 0
- if n==0 then
-  found=type(e)=="table" and e
- elseif n<0 then
-  local d=e.__p__.dt
-  local k=e.ni
-  for i=k-1,1,-1 do
-   local di=d[i]
-   if type(di)=="table" then
-    if n==-1 then
-     found=di
-     break
-    else
-     n=n+1
+  local found=false
+  n=tonumber(n) or 0
+  if n==0 then
+    found=type(e)=="table" and e
+  elseif n<0 then
+    local d,k=e.__p__.dt,e.ni
+    for i=k-1,1,-1 do
+      local di=d[i]
+      if type(di)=="table" then
+        if n==-1 then
+          found=di
+          break
+        else
+          n=n+1
+        end
+      end
     end
-   end
+  else
+    local d,k=e.__p__.dt,e.ni
+    for i=k+1,#d,1 do
+      local di=d[i]
+      if type(di)=="table" then
+        if n==1 then
+          found=di
+          break
+        else
+          n=n-1
+        end
+      end
+    end
   end
- else
-  local d=e.__p__.dt
-  local k=e.ni
-  for i=k+1,#d,1 do
-   local di=d[i]
-   if type(di)=="table" then
-    if n==1 then
-     found=di
-     break
+  if found then
+    local ns,tg=found.rn or found.ns or "",found.tg
+    if ns~="" then
+      return ns..":"..tg
     else
-     n=n-1
+      return tg
     end
-   end
-  end
- end
- if found then
-  local ns=found.rn or found.ns or ""
-  local tg=found.tg
-  if ns~="" then
-   return ns..":"..tg
   else
-   return tg
+    return ""
   end
- else
-  return ""
- end
 end
 expressions.tag=function(e,n) 
- if not e then
-  return ""
- else
-  local found=false
-  n=tonumber(n) or 0
-  if n==0 then
-   found=(type(e)=="table") and e 
-  elseif n<0 then
-   local d=e.__p__.dt
-   local k=e.ni
-   for i=k-1,1,-1 do
-    local di=d[i]
-    if type(di)=="table" then
-     if n==-1 then
-      found=di
-      break
-     else
-      n=n+1
-     end
-    end
-   end
+  if not e then
+    return ""
   else
-   local d=e.__p__.dt
-   local k=e.ni
-   for i=k+1,#d,1 do
-    local di=d[i]
-    if type(di)=="table" then
-     if n==1 then
-      found=di
-      break
-     else
-      n=n-1
-     end
+    local found=false
+    n=tonumber(n) or 0
+    if n==0 then
+      found=(type(e)=="table") and e 
+    elseif n<0 then
+      local d,k=e.__p__.dt,e.ni
+      for i=k-1,1,-1 do
+        local di=d[i]
+        if type(di)=="table" then
+          if n==-1 then
+            found=di
+            break
+          else
+            n=n+1
+          end
+        end
+      end
+    else
+      local d,k=e.__p__.dt,e.ni
+      for i=k+1,#d,1 do
+        local di=d[i]
+        if type(di)=="table" then
+          if n==1 then
+            found=di
+            break
+          else
+            n=n-1
+          end
+        end
+      end
     end
-   end
+    return (found and found.tg) or ""
   end
-  return (found and found.tg) or ""
- end
 end
 local dummy=function() end
 function xml.elements(root,pattern,reverse) 
- local collected=applylpath(root,pattern)
- if not collected then
-  return dummy
- end
- local n=#collected
- if n==0 then
-  return dummy
- end
- if reverse then
-  local c=n+1
-  return function()
-   if c>1 then
-    c=c-1
-    local e=collected[c]
-    local r=e.__p__
-    return r,r.dt,e.ni
-   end
+  local collected=applylpath(root,pattern)
+  if not collected then
+    return dummy
   end
- else
-  local c=0
-  return function()
-   if c<n then
-    c=c+1
-    local e=collected[c]
-    local r=e.__p__
-    return r,r.dt,e.ni
-   end
+  local n=#collected
+  if n==0 then
+    return dummy
   end
- end
+  if reverse then
+    local c=n+1
+    return function()
+      if c>1 then
+        c=c-1
+        local e=collected[c]
+        local r=e.__p__
+        return r,r.dt,e.ni
+      end
+    end
+  else
+    local c=0
+    return function()
+      if c<n then
+        c=c+1
+        local e=collected[c]
+        local r=e.__p__
+        return r,r.dt,e.ni
+      end
+    end
+  end
 end
 function xml.collected(root,pattern,reverse) 
- local collected=applylpath(root,pattern)
- if not collected then
-  return dummy
- end
- local n=#collected
- if n==0 then
-  return dummy
- end
- if reverse then
-  local c=n+1
-  return function()
-   if c>1 then
-    c=c-1
-    return collected[c]
-   end
+  local collected=applylpath(root,pattern)
+  if not collected then
+    return dummy
   end
- else
-  local c=0
-  return function()
-   if c<n then
-    c=c+1
-    return collected[c]
-   end
+  local n=#collected
+  if n==0 then
+    return dummy
   end
- end
+  if reverse then
+    local c=n+1
+    return function()
+      if c>1 then
+        c=c-1
+        return collected[c]
+      end
+    end
+  else
+    local c=0
+    return function()
+      if c<n then
+        c=c+1
+        return collected[c]
+      end
+    end
+  end
 end
 function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
-  report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+  pattern=pattern or "."
+  for e in xml.collected(collection,pattern or ".") do
+    report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+  end
 end
 local function split(e) 
- local dt=e.dt
- if dt then
-  for i=1,#dt do
-   local dti=dt[i]
-   if type(dti)=="string" then
-    dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
-    dti=gsub(dti,"[\n\r]+","\n\n")
-    dt[i]=dti
-   else
-    split(dti)
-   end
+  local dt=e.dt
+  if dt then
+    for i=1,#dt do
+      local dti=dt[i]
+      if type(dti)=="string" then
+        dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+        dti=gsub(dti,"[\n\r]+","\n\n")
+        dt[i]=dti
+      else
+        split(dti)
+      end
+    end
   end
- end
- return e
+  return e
 end
 function xml.finalizers.paragraphs(c)
- for i=1,#c do
-  split(c[i])
- end
- return c
+  for i=1,#c do
+    split(c[i])
+  end
+  return c
 end
 
 
@@ -18294,14 +14727,14 @@
 
 package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
 
--- original size: 3574, stripped down to: 1808
+-- original size: 3574, stripped down to: 1863
 
 if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="this module is the basis for the lxml-* ones",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local xml,lpeg,string=xml,lpeg,string
 local type=type
@@ -18312,26 +14745,26 @@
 lpegpatterns.xml=lpegpatterns.xml or {}
 local xmlpatterns=lpegpatterns.xml
 local function xmlgsub(t,old,new) 
- local dt=t.dt
- if dt then
-  for k=1,#dt do
-   local v=dt[k]
-   if type(v)=="string" then
-    dt[k]=gsub(v,old,new)
-   else
-    xmlgsub(v,old,new)
-   end
+  local dt=t.dt
+  if dt then
+    for k=1,#dt do
+      local v=dt[k]
+      if type(v)=="string" then
+        dt[k]=gsub(v,old,new)
+      else
+        xmlgsub(v,old,new)
+      end
+    end
   end
- end
 end
 function xml.stripleadingspaces(dk,d,k) 
- if d and k then
-  local dkm=d[k-1]
-  if dkm and type(dkm)=="string" then
-   local s=match(dkm,"\n(%s+)")
-   xmlgsub(dk,"\n"..rep(" ",#s),"\n")
+  if d and k then
+    local dkm=d[k-1]
+    if dkm and type(dkm)=="string" then
+      local s=match(dkm,"\n(%s+)")
+      xmlgsub(dk,"\n"..rep(" ",#s),"\n")
+    end
   end
- end
 end
 local normal=(1-S("<&>"))^0
 local special=P("<")/"<"+P(">")/">"+P("&")/"&"
@@ -18343,17 +14776,17 @@
 xmlpatterns.escaped=escaped
 xmlpatterns.unescaped=unescaped
 xmlpatterns.cleansed=cleansed
-function xml.escaped  (str) return lpegmatch(escaped,str)   end
+function xml.escaped (str) return lpegmatch(escaped,str)  end
 function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str)  end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
 function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
-  local n=#e.dt
-  if not check or n==0 or (n==1 and e.dt[1]=="") then
-   e.dt={ str }
+  local e=xml.first(root,pattern)
+  if e then
+    local n=#e.dt
+    if not check or n==0 or (n==1 and e.dt[1]=="") then
+      e.dt={ str }
+    end
   end
- end
 end
 
 
@@ -18363,17 +14796,17 @@
 
 package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
 
--- original size: 30771, stripped down to: 19680
+-- original size: 30650, stripped down to: 21793
 
 if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="this module is the basis for the lxml-* ones",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
-local trace_manipulations=false  trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false  trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
 local report_xml=logs.reporter("xml")
 local xml=xml
 local xmlcopy,xmlname=xml.copy,xml.name
@@ -18386,313 +14819,308 @@
 local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
 local striplinepatterns=utilities.strings.striplinepatterns
 local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+  report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
 end
 local function withelements(e,handle,depth)
- if e and handle then
-  local edt=e.dt
-  if edt then
-   depth=depth or 0
-   for i=1,#edt do
-    local e=edt[i]
-    if type(e)=="table" then
-     handle(e,depth)
-     withelements(e,handle,depth+1)
+  if e and handle then
+    local edt=e.dt
+    if edt then
+      depth=depth or 0
+      for i=1,#edt do
+        local e=edt[i]
+        if type(e)=="table" then
+          handle(e,depth)
+          withelements(e,handle,depth+1)
+        end
+      end
     end
-   end
   end
- end
 end
 xml.withelements=withelements
 function xml.withelement(e,n,handle) 
- if e and n~=0 and handle then
-  local edt=e.dt
-  if edt then
-   if n>0 then
-    for i=1,#edt do
-     local ei=edt[i]
-     if type(ei)=="table" then
-      if n==1 then
-       handle(ei)
-       return
-      else
-       n=n-1
+  if e and n~=0 and handle then
+    local edt=e.dt
+    if edt then
+      if n>0 then
+        for i=1,#edt do
+          local ei=edt[i]
+          if type(ei)=="table" then
+            if n==1 then
+              handle(ei)
+              return
+            else
+              n=n-1
+            end
+          end
+        end
+      elseif n<0 then
+        for i=#edt,1,-1 do
+          local ei=edt[i]
+          if type(ei)=="table" then
+            if n==-1 then
+              handle(ei)
+              return
+            else
+              n=n+1
+            end
+          end
+        end
       end
-     end
     end
-   elseif n<0 then
-    for i=#edt,1,-1 do
-     local ei=edt[i]
-     if type(ei)=="table" then
-      if n==-1 then
-       handle(ei)
-       return
+  end
+end
+function xml.each(root,pattern,handle,reverse)
+  local collected=xmlapplylpath(root,pattern)
+  if collected then
+    if handle then
+      if reverse then
+        for c=#collected,1,-1 do
+          handle(collected[c])
+        end
       else
-       n=n+1
+        for c=1,#collected do
+          handle(collected[c])
+        end
       end
-     end
     end
-   end
+    return collected
   end
- end
 end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
-  if handle then
-   if reverse then
-    for c=#collected,1,-1 do
-     handle(collected[c])
-    end
-   else
+function xml.processattributes(root,pattern,handle)
+  local collected=xmlapplylpath(root,pattern)
+  if collected and handle then
     for c=1,#collected do
-     handle(collected[c])
+      handle(collected[c].at)
     end
-   end
   end
   return collected
- end
 end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
-  for c=1,#collected do
-   handle(collected[c].at)
-  end
- end
- return collected
-end
 function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+  return xmlapplylpath(root,pattern)
 end
 function xml.collecttexts(root,pattern,flatten) 
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
-  local xmltostring=xml.tostring
-  for c=1,#collected do
-   collected[c]=xmltostring(collected[c].dt)
+  local collected=xmlapplylpath(root,pattern)
+  if collected and flatten then
+    local xmltostring=xml.tostring
+    for c=1,#collected do
+      collected[c]=xmltostring(collected[c].dt)
+    end
   end
- end
- return collected or {}
+  return collected or {}
 end
 function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
-  local t={}
-  local n=0
-  for c=1,#collected do
-   local e=collected[c]
-   local ns=e.ns
-   local tg=e.tg
-   n=n+1
-   if nonamespace then
-    t[n]=tg
-   elseif ns=="" then
-    t[n]=tg
-   else
-    t[n]=ns..":"..tg
-   end
+  local collected=xmlapplylpath(root,pattern)
+  if collected then
+    local t,n={},0
+    for c=1,#collected do
+      local e=collected[c]
+      local ns,tg=e.ns,e.tg
+      n=n+1
+      if nonamespace then
+        t[n]=tg
+      elseif ns=="" then
+        t[n]=tg
+      else
+        t[n]=ns..":"..tg
+      end
+    end
+    return t
   end
-  return t
- end
 end
 local no_root={ no_root=true }
 local function redo_ni(d)
- for k=1,#d do
-  local dk=d[k]
-  if type(dk)=="table" then
-   dk.ni=k
+  for k=1,#d do
+    local dk=d[k]
+    if type(dk)=="table" then
+      dk.ni=k
+    end
   end
- end
 end
 xml.reindex=redo_ni
 local function xmltoelement(whatever,root)
- if not whatever then
-  return nil
- end
- local element
- if type(whatever)=="string" then
-  element=xmlinheritedconvert(whatever,root) 
- else
-  element=whatever 
- end
- if element.error then
-  return whatever 
- end
- if element then
- end
- return element
+  if not whatever then
+    return nil
+  end
+  local element
+  if type(whatever)=="string" then
+    element=xmlinheritedconvert(whatever,root) 
+  else
+    element=whatever 
+  end
+  if element.error then
+    return whatever 
+  end
+  if element then
+  end
+  return element
 end
 xml.toelement=xmltoelement
 local function copiedelement(element,newparent)
- if type(element)=="string" then
-  return element
- else
-  element=xmlcopy(element).dt
-  if newparent and type(element)=="table" then
-   element.__p__=newparent
+  if type(element)=="string" then
+    return element
+  else
+    element=xmlcopy(element).dt
+    if newparent and type(element)=="table" then
+      element.__p__=newparent
+    end
+    return element
   end
-  return element
- end
 end
 function xml.delete(root,pattern)
- if not pattern or pattern=="" then
-  local p=root.__p__
-  if p then
-   if trace_manipulations then
-    report('deleting',"--",c,root)
-   end
-   local d=p.dt
-   remove(d,root.ni)
-   redo_ni(d) 
-  end
- else
-  local collected=xmlapplylpath(root,pattern)
-  if collected then
-   for c=1,#collected do
-    local e=collected[c]
-    local p=e.__p__
+  if not pattern or pattern=="" then
+    local p=root.__p__
     if p then
-     if trace_manipulations then
-      report('deleting',pattern,c,e)
-     end
-     local d=p.dt
-     local ni=e.ni
-     if ni<=#d then
-      if false then
-       p.dt[ni]=""
-      else
-       remove(d,ni)
-       redo_ni(d) 
+      if trace_manipulations then
+        report('deleting',"--",c,root)
       end
-     else
-     end
+      local d=p.dt
+      remove(d,root.ni)
+      redo_ni(d) 
     end
-   end
+  else
+    local collected=xmlapplylpath(root,pattern)
+    if collected then
+      for c=1,#collected do
+        local e=collected[c]
+        local p=e.__p__
+        if p then
+          if trace_manipulations then
+            report('deleting',pattern,c,e)
+          end
+          local d=p.dt
+          local ni=e.ni
+          if ni<=#d then
+            if false then
+              p.dt[ni]=""
+            else
+              remove(d,ni)
+              redo_ni(d) 
+            end
+          else
+          end
+        end
+      end
+    end
   end
- end
 end
 function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
-  for c=1,#collected do
-   local e=collected[c]
-   local p=e.__p__
-   if p then
-    if trace_manipulations then
-     report('replacing',pattern,c,e)
+  local element=root and xmltoelement(whatever,root)
+  local collected=element and xmlapplylpath(root,pattern)
+  if collected then
+    for c=1,#collected do
+      local e=collected[c]
+      local p=e.__p__
+      if p then
+        if trace_manipulations then
+          report('replacing',pattern,c,e)
+        end
+        local d=p.dt
+        local n=e.ni
+        local t=copiedelement(element,p)
+        if type(t)=="table" then
+          d[n]=t[1]
+          for i=2,#t do
+            n=n+1
+            insert(d,n,t[i])
+          end
+        else
+          d[n]=t
+        end
+        redo_ni(d) 
+      end
     end
-    local d=p.dt
-    local n=e.ni
-    local t=copiedelement(element,p)
-    if type(t)=="table" then
-     d[n]=t[1]
-     for i=2,#t do
-      n=n+1
-      insert(d,n,t[i])
-     end
-    else
-     d[n]=t
-    end
-    redo_ni(d) 
-   end
   end
- end
 end
 local function wrap(e,wrapper)
- local t={
-  rn=e.rn,
-  tg=e.tg,
-  ns=e.ns,
-  at=e.at,
-  dt=e.dt,
-  __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+  local t={
+    rn=e.rn,
+    tg=e.tg,
+    ns=e.ns,
+    at=e.at,
+    dt=e.dt,
+    __p__=e,
+  }
+  setmetatable(t,getmetatable(e))
+  e.rn=wrapper.rn or e.rn or ""
+  e.tg=wrapper.tg or e.tg or ""
+  e.ns=wrapper.ns or e.ns or ""
+  e.at=fastcopy(wrapper.at)
+  e.dt={ t }
 end
 function xml.wrap(root,pattern,whatever)
- if whatever then
-  local wrapper=xmltoelement(whatever,root)
-  local collected=xmlapplylpath(root,pattern)
-  if collected then
-   for c=1,#collected do
-    local e=collected[c]
-    if trace_manipulations then
-     report('wrapping',pattern,c,e)
+  if whatever then
+    local wrapper=xmltoelement(whatever,root)
+    local collected=xmlapplylpath(root,pattern)
+    if collected then
+      for c=1,#collected do
+        local e=collected[c]
+        if trace_manipulations then
+          report('wrapping',pattern,c,e)
+        end
+        wrap(e,wrapper)
+      end
     end
-    wrap(e,wrapper)
-   end
+  else
+    wrap(root,xmltoelement(pattern))
   end
- else
-  wrap(root,xmltoelement(pattern))
- end
 end
 local function inject_element(root,pattern,whatever,prepend)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function inject_e(e)
-  local r=e.__p__
-  local d=r.dt
-  local k=e.ni
-  local rri=r.ri
-  local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
-  if edt then
-   local be,af
-   local cp=copiedelement(element,e)
-   if prepend then
-    be,af=cp,edt
-   else
-    be,af=edt,cp
-   end
-   local bn=#be
-   for i=1,#af do
-    bn=bn+1
-    be[bn]=af[i]
-   end
-   if rri then
-    r.dt[rri].dt=be
-   else
-    d[k].dt=be
-   end
-   redo_ni(d)
+  local element=root and xmltoelement(whatever,root)
+  local collected=element and xmlapplylpath(root,pattern)
+  local function inject_e(e)
+    local r=e.__p__
+    local d,k,rri=r.dt,e.ni,r.ri
+    local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
+    if edt then
+      local be,af
+      local cp=copiedelement(element,e)
+      if prepend then
+        be,af=cp,edt
+      else
+        be,af=edt,cp
+      end
+      local bn=#be
+      for i=1,#af do
+        bn=bn+1
+        be[bn]=af[i]
+      end
+      if rri then
+        r.dt[rri].dt=be
+      else
+        d[k].dt=be
+      end
+      redo_ni(d)
+    end
   end
- end
- if not collected then
- elseif collected.tg then
-  inject_e(collected)
- else
-  for c=1,#collected do
-   inject_e(collected[c])
+  if not collected then
+  elseif collected.tg then
+    inject_e(collected)
+  else
+    for c=1,#collected do
+      inject_e(collected[c])
+    end
   end
- end
 end
 local function insert_element(root,pattern,whatever,before) 
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
-  local r=e.__p__
-  local d=r.dt
-  local k=e.ni
-  if not before then
-   k=k+1
+  local element=root and xmltoelement(whatever,root)
+  local collected=element and xmlapplylpath(root,pattern)
+  local function insert_e(e)
+    local r=e.__p__
+    local d,k=r.dt,e.ni
+    if not before then
+      k=k+1
+    end
+    insert(d,k,copiedelement(element,r))
+    redo_ni(d)
   end
-  insert(d,k,copiedelement(element,r))
-  redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
-  insert_e(collected)
- else
-  for c=1,#collected do
-   insert_e(collected[c])
+  if not collected then
+  elseif collected.tg then
+    insert_e(collected)
+  else
+    for c=1,#collected do
+      insert_e(collected[c])
+    end
   end
- end
 end
 xml.insert_element=insert_element
 xml.insertafter=insert_element
@@ -18700,124 +15128,124 @@
 xml.injectafter=inject_element
 xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
 local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
-  if not level then
-   level=1
-  end
-  for c=1,#collected do
-   local ek=collected[c]
-   local name=nil
-   local ekdt=ek.dt
-   if ekdt then
-    local ekat=ek.at
-    local ekrt=ek.__p__
-    if ekrt then
-     local epdt=ekrt.dt
-     if not attribute or attribute=="" then
-      name=(type(ekdt)=="table" and ekdt[1]) or ekdt 
-     end
-     if not name then
-      for a in gmatch(attribute or "href","([^|]+)") do
-       name=ekat[a]
-       if name then
-        break
-       end
-      end
-     end
-     local data=nil
-     if name and name~="" then
-      local d,n=loaddata(name)
-      data=d or ""
-      name=n or name
-      if trace_inclusions then
-       report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
-      end
-     end
-     if not data or data=="" then
-      epdt[ek.ni]="" 
-     elseif ekat["parse"]=="text" then
-      epdt[ek.ni]=xml.escaped(data) 
-     else
+  pattern=pattern or 'include'
+  loaddata=loaddata or io.loaddata
+  local collected=xmlapplylpath(xmldata,pattern)
+  if collected then
+    if not level then
+      level=1
+    end
+    for c=1,#collected do
+      local ek=collected[c]
+      local name=nil
+      local ekdt=ek.dt
+      if ekdt then
+        local ekat=ek.at
+        local ekrt=ek.__p__
+        if ekrt then
+          local epdt=ekrt.dt
+          if not attribute or attribute=="" then
+            name=(type(ekdt)=="table" and ekdt[1]) or ekdt 
+          end
+          if not name then
+            for a in gmatch(attribute or "href","([^|]+)") do
+              name=ekat[a]
+              if name then
+                break
+              end
+            end
+          end
+          local data=nil
+          if name and name~="" then
+            local d,n=loaddata(name)
+            data=d or ""
+            name=n or name
+            if trace_inclusions then
+              report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+            end
+          end
+          if not data or data=="" then
+            epdt[ek.ni]="" 
+          elseif ekat["parse"]=="text" then
+            epdt[ek.ni]=xml.escaped(data) 
+          else
 local settings=xmldata.settings
 local savedresource=settings.currentresource
 settings.currentresource=name
-      local xi=xmlinheritedconvert(data,xmldata)
-      if not xi then
-       epdt[ek.ni]="" 
-      else
-       if recursive then
-        include(xi,pattern,attribute,recursive,loaddata,level+1)
-       end
-       local child=xml.body(xi) 
-       child.__p__=ekrt
-       child.__f__=name 
+            local xi=xmlinheritedconvert(data,xmldata)
+            if not xi then
+              epdt[ek.ni]="" 
+            else
+              if recursive then
+                include(xi,pattern,attribute,recursive,loaddata,level+1)
+              end
+              local child=xml.body(xi) 
+              child.__p__=ekrt
+              child.__f__=name 
 child.cf=name
-       epdt[ek.ni]=child
-       local settings=xmldata.settings
-       local inclusions=settings and settings.inclusions
-       if inclusions then
-        inclusions[#inclusions+1]=name
-       elseif settings then
-        settings.inclusions={ name }
-       else
-        settings={ inclusions={ name } }
-        xmldata.settings=settings
-       end
-       if child.er then
-        local badinclusions=settings.badinclusions
-        if badinclusions then
-         badinclusions[#badinclusions+1]=name
-        else
-         settings.badinclusions={ name }
+              epdt[ek.ni]=child
+              local settings=xmldata.settings
+              local inclusions=settings and settings.inclusions
+              if inclusions then
+                inclusions[#inclusions+1]=name
+              elseif settings then
+                settings.inclusions={ name }
+              else
+                settings={ inclusions={ name } }
+                xmldata.settings=settings
+              end
+              if child.er then
+                local badinclusions=settings.badinclusions
+                if badinclusions then
+                  badinclusions[#badinclusions+1]=name
+                else
+                  settings.badinclusions={ name }
+                end
+              end
+            end
+settings.currentresource=savedresource
+          end
         end
-       end
       end
-settings.currentresource=savedresource
-     end
     end
-   end
   end
- end
 end
 xml.include=include
 function xml.inclusion(e,default)
- while e do
-  local f=e.__f__
-  if f then
-   return f
-  else
-   e=e.__p__
+  while e do
+    local f=e.__f__
+    if f then
+      return f
+    else
+      e=e.__p__
+    end
   end
- end
- return default
+  return default
 end
 local function getinclusions(key,e,sorted)
- while e do
-  local settings=e.settings
-  if settings then
-   local inclusions=settings[key]
-   if inclusions then
-    inclusions=table.unique(inclusions) 
-    if sorted then
-     table.sort(inclusions) 
+  while e do
+    local settings=e.settings
+    if settings then
+      local inclusions=settings[key]
+      if inclusions then
+        inclusions=table.unique(inclusions) 
+        if sorted then
+          table.sort(inclusions) 
+        end
+        return inclusions 
+      else
+        e=e.__p__
+      end
+    else
+      e=e.__p__
     end
-    return inclusions 
-   else
-    e=e.__p__
-   end
-  else
-   e=e.__p__
   end
- end
 end
 function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+  return getinclusions("inclusions",e,sorted)
 end
 function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+  return getinclusions("badinclusions",e,sorted)
 end
 local b_collapser=lpegpatterns.b_collapser
 local m_collapser=lpegpatterns.m_collapser
@@ -18826,194 +15254,194 @@
 local m_stripper=lpegpatterns.m_stripper
 local e_stripper=lpegpatterns.e_stripper
 local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
-  local n=#edt
-  if n==0 then
-   return e 
-  elseif anywhere then
-   local t={}
-   local m=0
-   for e=1,n do
-    local str=edt[e]
-    if type(str)~="string" then
-     m=m+1
-     t[m]=str
-    elseif str~="" then
-     if nolines then
-      str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
-     else
-      str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
-     end
-     if str~="" then
-      m=m+1
-      t[m]=str
-     end
-    end
-   end
-   e.dt=t
-  else
-   local str=edt[1]
-   if type(str)=="string" then
-    if str~="" then
-     str=lpegmatch(nolines and b_collapser or b_stripper,str)
-    end
-    if str=="" then
-     remove(edt,1)
-     n=n-1
+  local edt=e.dt
+  if edt then
+    local n=#edt
+    if n==0 then
+      return e 
+    elseif anywhere then
+      local t={}
+      local m=0
+      for e=1,n do
+        local str=edt[e]
+        if type(str)~="string" then
+          m=m+1
+          t[m]=str
+        elseif str~="" then
+          if nolines then
+            str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+          else
+            str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+          end
+          if str~="" then
+            m=m+1
+            t[m]=str
+          end
+        end
+      end
+      e.dt=t
     else
-     edt[1]=str
-    end
-   end
-   if n>0 then
-    str=edt[n]
-    if type(str)=="string" then
-     if str=="" then
-      remove(edt)
-     else
-      str=lpegmatch(nolines and e_collapser or e_stripper,str)
-      if str=="" then
-       remove(edt)
-      else
-       edt[n]=str
+      local str=edt[1]
+      if type(str)=="string" then
+        if str~="" then
+          str=lpegmatch(nolines and b_collapser or b_stripper,str)
+        end
+        if str=="" then
+          remove(edt,1)
+          n=n-1
+        else
+          edt[1]=str
+        end
       end
-     end
+      if n>0 then
+        str=edt[n]
+        if type(str)=="string" then
+          if str=="" then
+            remove(edt)
+          else
+            str=lpegmatch(nolines and e_collapser or e_stripper,str)
+            if str=="" then
+              remove(edt)
+            else
+              edt[n]=str
+            end
+          end
+        end
+      end
     end
-   end
   end
- end
- return e 
+  return e 
 end
 xml.stripelement=stripelement
 function xml.strip(root,pattern,nolines,anywhere) 
- local collected=xmlapplylpath(root,pattern) 
- if collected then
-  for i=1,#collected do
-   stripelement(collected[i],nolines,anywhere)
+  local collected=xmlapplylpath(root,pattern) 
+  if collected then
+    for i=1,#collected do
+      stripelement(collected[i],nolines,anywhere)
+    end
   end
- end
 end
 local function renamespace(root,oldspace,newspace) 
- local ndt=#root.dt
- for i=1,ndt or 0 do
-  local e=root[i]
-  if type(e)=="table" then
-   if e.ns==oldspace then
-    e.ns=newspace
-    if e.rn then
-     e.rn=newspace
+  local ndt=#root.dt
+  for i=1,ndt or 0 do
+    local e=root[i]
+    if type(e)=="table" then
+      if e.ns==oldspace then
+        e.ns=newspace
+        if e.rn then
+          e.rn=newspace
+        end
+      end
+      local edt=e.dt
+      if edt then
+        renamespace(edt,oldspace,newspace)
+      end
     end
-   end
-   local edt=e.dt
-   if edt then
-    renamespace(edt,oldspace,newspace)
-   end
   end
- end
 end
 xml.renamespace=renamespace
 function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
-  for c=1,#collected do
-   collected[c].tg=newtg
+  local collected=xmlapplylpath(root,pattern)
+  if collected then
+    for c=1,#collected do
+      collected[c].tg=newtg
+    end
   end
- end
 end
 function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
-  for c=1,#collected do
-   collected[c].ns=newns
+  local collected=xmlapplylpath(root,pattern)
+  if collected then
+    for c=1,#collected do
+      collected[c].ns=newns
+    end
   end
- end
 end
 function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
-  for c=1,#collected do
-   local e=collected[c]
-   if (not e.rn or e.rn=="") and e.ns=="" then
-    e.rn=newns
-   end
+  local collected=xmlapplylpath(root,pattern)
+  if collected then
+    for c=1,#collected do
+      local e=collected[c]
+      if (not e.rn or e.rn=="") and e.ns=="" then
+        e.rn=newns
+      end
+    end
   end
- end
 end
 function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
-  for c=1,#collected do
-   local e=collected[c]
-   e.tg,e.ns,e.rn=newtg,newns,newrn
+  local collected=xmlapplylpath(root,pattern)
+  if collected then
+    for c=1,#collected do
+      local e=collected[c]
+      e.tg,e.ns,e.rn=newtg,newns,newrn
+    end
   end
- end
 end
 function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
-  local first=dt[1]
-  if first.tg=="@cd@" then
-   e.dt=first.dt
+  local dt=e.dt
+  if #dt==1 then
+    local first=dt[1]
+    if first.tg=="@cd@" then
+      e.dt=first.dt
+    end
+  else
   end
- else
- end
 end
 function xml.texttocdata(e) 
- local dt=e.dt
- local s=xml.tostring(dt) 
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+  local dt=e.dt
+  local s=xml.tostring(dt) 
+  e.tg="@cd@"
+  e.special=true
+  e.ns=""
+  e.rn=""
+  e.dt={ s }
+  e.at=nil
 end
 function xml.elementtocdata(e) 
- local dt=e.dt
- local s=xml.tostring(e) 
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+  local dt=e.dt
+  local s=xml.tostring(e) 
+  e.tg="@cd@"
+  e.special=true
+  e.ns=""
+  e.rn=""
+  e.dt={ s }
+  e.at=nil
 end
 xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" } 
 local entities=characters and characters.entities or nil
 local builtinentities=xml.builtinentities
 function xml.addentitiesdoctype(root,option) 
- if not entities then
-  require("char-ent")
-  entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
-  local list={}
-  local hexify=option=="hexadecimal"
-  for k,v in table.sortedhash(root.statistics.entities.names) do
-   if not builtinentities[k] then
-    local e=entities[k]
-    if not e then
-     e=format("[%s]",k)
-    elseif hexify then
-     e=format("&#%05X;",utfbyte(k))
+  if not entities then
+    require("char-ent")
+    entities=characters.entities
+  end
+  if entities and root and root.tg=="@rt@" and root.statistics then
+    local list={}
+    local hexify=option=="hexadecimal"
+    for k,v in table.sortedhash(root.statistics.entities.names) do
+      if not builtinentities[k] then
+        local e=entities[k]
+        if not e then
+          e=format("[%s]",k)
+        elseif hexify then
+          e=format("&#%05X;",utfbyte(k))
+        end
+        list[#list+1]=format("  <!ENTITY %s %q >",k,e)
+      end
     end
-    list[#list+1]=format("  <!ENTITY %s %q >",k,e)
-   end
+    local dt=root.dt
+    local n=dt[1].tg=="@pi@" and 2 or 1
+    if #list>0 then
+      insert(dt,n,{ "\n" })
+      insert(dt,n,{
+        tg="@dt@",
+        dt={ format("Something [\n%s\n] ",concat(list)) },
+        ns="",
+        special=true,
+      })
+      insert(dt,n,{ "\n\n" })
+    else
+    end
   end
-  local dt=root.dt
-  local n=dt[1].tg=="@pi@" and 2 or 1
-  if #list>0 then
-   insert(dt,n,{ "\n" })
-   insert(dt,n,{
-      tg="@dt@",
-      dt={ format("Something [\n%s\n] ",concat(list)) },
-      ns="",
-      special=true,
-   })
-   insert(dt,n,{ "\n\n" })
-  else
-  end
- end
 end
 xml.all=xml.each
 xml.insert=xml.insertafter
@@ -19023,241 +15451,239 @@
 xml.process=xml.each
 xml.obsolete=xml.obsolete or {}
 local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip     obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect      obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete    obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace      obsolete.replace_element=xml.replace
-xml.each_element=xml.each      obsolete.each_element=xml.each
-xml.process_elements=xml.process      obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter     obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore    obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter     obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore    obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes  obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts    obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject    obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag     obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname    obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace  obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip         obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect        obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete        obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace        obsolete.replace_element=xml.replace
+xml.each_element=xml.each         obsolete.each_element=xml.each
+xml.process_elements=xml.process        obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter      obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore     obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter      obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore     obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes   obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts     obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject        obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag       obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname       obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace    obsolete.remap_namespace=xml.remapnamespace
 function xml.cdata(e)
- if e then
-  local dt=e.dt
-  if dt and #dt==1 then
-   local first=dt[1]
-   return first.tg=="@cd@" and first.dt[1] or ""
+  if e then
+    local dt=e.dt
+    if dt and #dt==1 then
+      local first=dt[1]
+      return first.tg=="@cd@" and first.dt[1] or ""
+    end
   end
- end
- return ""
+  return ""
 end
 function xml.finalizers.xml.cdata(collected)
- if collected then
-  local e=collected[1]
-  if e then
-   local dt=e.dt
-   if dt and #dt==1 then
-    local first=dt[1]
-    return first.tg=="@cd@" and first.dt[1] or ""
-   end
+  if collected then
+    local e=collected[1]
+    if e then
+      local dt=e.dt
+      if dt and #dt==1 then
+        local first=dt[1]
+        return first.tg=="@cd@" and first.dt[1] or ""
+      end
+    end
   end
- end
- return ""
+  return ""
 end
 function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
-  tg="@cm@",
-  ns="",
-  special=true,
-  at={},
-  dt={ str },
- })
+  insert(e.dt,n or 1,{
+    tg="@cm@",
+    ns="",
+    special=true,
+    at={},
+    dt={ str },
+  })
 end
 function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
-  tg="@cd@",
-  ns="",
-  special=true,
-  at={},
-  dt={ str },
- })
+  insert(e.dt,n or 1,{
+    tg="@cd@",
+    ns="",
+    special=true,
+    at={},
+    dt={ str },
+  })
 end
 function xml.setcomment(e,str,n)
- e.dt={ {
-  tg="@cm@",
-  ns="",
-  special=true,
-  at={},
-  dt={ str },
- } }
+  e.dt={ {
+    tg="@cm@",
+    ns="",
+    special=true,
+    at={},
+    dt={ str },
+  } }
 end
 function xml.setcdata(e,str)
- e.dt={ {
-  tg="@cd@",
-  ns="",
-  special=true,
-  at={},
-  dt={ str },
- } }
+  e.dt={ {
+    tg="@cd@",
+    ns="",
+    special=true,
+    at={},
+    dt={ str },
+  } }
 end
 function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
-  for c=1,#collected do
-   local e=collected[c]
-   local d=e.dt
-   if d==x then
-    report_xml("warning: xml.separate changes root")
-    x=d
-   end
-   local t={ "\n" }
-   local n=1
-   local i=1
-   local nd=#d
-   while i<=nd do
-    while i<=nd do
-     local di=d[i]
-     if type(di)=="string" then
-      if di=="\n" or find(di,"^%s+$") then 
-       i=i+1
-      else
-       d[i]=strip(di)
-       break
+  local collected=xmlapplylpath(x,pattern)
+  if collected then
+    for c=1,#collected do
+      local e=collected[c]
+      local d=e.dt
+      if d==x then
+        report_xml("warning: xml.separate changes root")
+        x=d
       end
-     else
-      break
-     end
+      local t,n={ "\n" },1
+      local i,nd=1,#d
+      while i<=nd do
+        while i<=nd do
+          local di=d[i]
+          if type(di)=="string" then
+            if di=="\n" or find(di,"^%s+$") then 
+              i=i+1
+            else
+              d[i]=strip(di)
+              break
+            end
+          else
+            break
+          end
+        end
+        if i>nd then
+          break
+        end
+        t[n+1]="\n"
+        t[n+2]=d[i]
+        t[n+3]="\n"
+        n=n+3
+        i=i+1
+      end
+      t[n+1]="\n"
+      setmetatable(t,getmetatable(d))
+      e.dt=t
     end
-    if i>nd then
-     break
-    end
-    t[n+1]="\n"
-    t[n+2]=d[i]
-    t[n+3]="\n"
-    n=n+3
-    i=i+1
-   end
-   t[n+1]="\n"
-   setmetatable(t,getmetatable(d))
-   e.dt=t
   end
- end
- return x
+  return x
 end
 local helpers=xml.helpers or {}
 xml.helpers=helpers
 local function normal(e,action)
- local edt=e.dt
- if edt then
-  for i=1,#edt do
-   local str=edt[i]
-   if type(str)=="string" and str~="" then
-    edt[i]=action(str)
-   end
+  local edt=e.dt
+  if edt then
+    for i=1,#edt do
+      local str=edt[i]
+      if type(str)=="string" and str~="" then
+        edt[i]=action(str)
+      end
+    end
   end
- end
 end
 local function recurse(e,action)
- local edt=e.dt
- if edt then
-  for i=1,#edt do
-   local str=edt[i]
-   if type(str)~="string" then
-    recurse(str,action) 
-   elseif str~="" then
-    edt[i]=action(str)
-   end
+  local edt=e.dt
+  if edt then
+    for i=1,#edt do
+      local str=edt[i]
+      if type(str)~="string" then
+        recurse(str,action) 
+      elseif str~="" then
+        edt[i]=action(str)
+      end
+    end
   end
- end
 end
 function helpers.recursetext(collected,action,recursive)
- if recursive then
-  for i=1,#collected do
-   recurse(collected[i],action)
+  if recursive then
+    for i=1,#collected do
+      recurse(collected[i],action)
+    end
+  else
+    for i=1,#collected do
+      normal(collected[i],action)
+    end
   end
- else
-  for i=1,#collected do
-     normal(collected[i],action)
-  end
- end
 end
 local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+  ["@rt@"]="root",
+  ["@pi@"]="instruction",
+  ["@cm@"]="comment",
+  ["@dt@"]="declaration",
+  ["@cd@"]="cdata",
 }
 local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
-  [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
-  _namespace=ns~="" and ns or nil,
-  _tag=not x.special and tg or nil,
-  _type=specials[tg] or "_element",
- }
- if at then
-  for k,v in next,at do
-   node[k]=v
+  local ns=x.ns
+  local tg=x.tg
+  local at=x.at
+  local dt=x.dt
+  local node=flat and {
+    [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+  } or {
+    _namespace=ns~="" and ns or nil,
+    _tag=not x.special and tg or nil,
+    _type=specials[tg] or "_element",
+  }
+  if at then
+    for k,v in next,at do
+      node[k]=v
+    end
   end
- end
- local n=0
- for i=1,#dt do
-  local di=dt[i]
-  if type(di)=="table" then
-   if flat and di.special then
-   else
-    di=convert(di,strip,flat)
-    if di then
-     n=n+1
-     node[n]=di
+  local n=0
+  for i=1,#dt do
+    local di=dt[i]
+    if type(di)=="table" then
+      if flat and di.special then
+      else
+        di=convert(di,strip,flat)
+        if di then
+          n=n+1
+          node[n]=di
+        end
+      end
+    elseif strip then
+      di=lpegmatch(strip,di)
+      if di~="" then
+        n=n+1
+        node[n]=di
+      end
+    else
+      n=n+1
+      node[n]=di
     end
-   end
-  elseif strip then
-   di=lpegmatch(strip,di)
-   if di~="" then
-    n=n+1
-    node[n]=di
-   end
-  else
-   n=n+1
-   node[n]=di
   end
- end
- if next(node) then
-  return node
- end
+  if next(node) then
+    return node
+  end
 end
 function xml.totable(x,strip,flat)
- if type(x)=="table" then
-  if strip then
-   strip=striplinepatterns[strip]
+  if type(x)=="table" then
+    if strip then
+      strip=striplinepatterns[strip]
+    end
+    return convert(x,strip,flat)
   end
-  return convert(x,strip,flat)
- end
 end
 function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
-  return
- end
- if type(name)=="table" then
-  attributes=name
-  name=namespace
-  namespace=""
- elseif type(name)~="string" then
-  attributes={}
-  name=namespace
-  namespace=""
- end
- if type(attributes)~="table" then
-  attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+  if type(e)~="table" or not e.tg then
+    return
+  end
+  if type(name)=="table" then
+    attributes=name
+    name=namespace
+    namespace=""
+  elseif type(name)~="string" then
+    attributes={}
+    name=namespace
+    namespace=""
+  end
+  if type(attributes)~="table" then
+    attributes={}
+  end
+  e.ns=namespace
+  e.rn=namespace
+  e.tg=name
+  e.at=attributes
 end
 
 
@@ -19267,14 +15693,14 @@
 
 package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
 
--- original size: 11096, stripped down to: 7702
+-- original size: 11096, stripped down to: 8243
 
 if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="this module is the basis for the lxml-* ones",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local tonumber,next=tonumber,next
 local concat=table.concat
@@ -19286,241 +15712,241 @@
 local xmlserialize=xml.serialize
 local xmlcollected=xml.collected
 local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg   
+local reparsedentity=xml.reparsedentitylpeg  
 local unescapedentity=xml.unescapedentitylpeg
 local parsedentity=reparsedentity
 local function first(collected) 
- return collected and collected[1]
+  return collected and collected[1]
 end
 local function last(collected)
- return collected and collected[#collected]
+  return collected and collected[#collected]
 end
 local function all(collected)
- return collected
+  return collected
 end
 local reverse=table.reversed
 local function attribute(collected,name)
- if collected and #collected>0 then
-  local at=collected[1].at
-  return at and at[name]
- end
+  if collected and #collected>0 then
+    local at=collected[1].at
+    return at and at[name]
+  end
 end
 local function att(id,name)
- local at=id.at
- return at and at[name]
+  local at=id.at
+  return at and at[name]
 end
 local function count(collected)
- return collected and #collected or 0
+  return collected and #collected or 0
 end
 local function position(collected,n)
- if not collected then
-  return 0
- end
- local nc=#collected
- if nc==0 then
-  return 0
- end
- n=tonumber(n) or 0
- if n<0 then
-  return collected[nc+n+1]
- elseif n>0 then
-  return collected[n]
- else
-  return collected[1].mi or 0
- end
+  if not collected then
+    return 0
+  end
+  local nc=#collected
+  if nc==0 then
+    return 0
+  end
+  n=tonumber(n) or 0
+  if n<0 then
+    return collected[nc+n+1]
+  elseif n>0 then
+    return collected[n]
+  else
+    return collected[1].mi or 0
+  end
 end
 local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0 
+  return collected and #collected>0 and collected[1].mi or 0 
 end
 local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0 
+  return collected and #collected>0 and collected[1].ni or 0 
 end
 local function attributes(collected,arguments)
- if collected and #collected>0 then
-  local at=collected[1].at
-  if arguments then
-   return at[arguments]
-  elseif next(at) then
-   return at 
+  if collected and #collected>0 then
+    local at=collected[1].at
+    if arguments then
+      return at[arguments]
+    elseif next(at) then
+      return at 
+    end
   end
- end
 end
 local function chainattribute(collected,arguments) 
- if collected and #collected>0 then
-  local e=collected[1]
-  while e do
-   local at=e.at
-   if at then
-    local a=at[arguments]
-    if a then
-     return a
+  if collected and #collected>0 then
+    local e=collected[1]
+    while e do
+      local at=e.at
+      if at then
+        local a=at[arguments]
+        if a then
+          return a
+        end
+      else
+        break 
+      end
+      e=e.__p__
     end
-   else
-    break 
-   end
-   e=e.__p__
   end
- end
- return ""
+  return ""
 end
 local function raw(collected) 
- if collected and #collected>0 then
-  local e=collected[1] or collected
-  return e and xmltostring(e) or "" 
- else
-  return ""
- end
+  if collected and #collected>0 then
+    local e=collected[1] or collected
+    return e and xmltostring(e) or "" 
+  else
+    return ""
+  end
 end
 local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
-  result={}
-  return result
- end,
- finalize=function()
-  return concat(result)
- end,
- handle=function(...)
-  result[#result+1]=concat {... }
- end,
- escape=false,
+  name="string",
+  initialize=function()
+    result={}
+    return result
+  end,
+  finalize=function()
+    return concat(result)
+  end,
+  handle=function(...)
+    result[#result+1]=concat {... }
+  end,
+  escape=false,
 }
 local function xmltotext(root)
- local dt=root.dt
- if not dt then
-  return ""
- end
- local nt=#dt 
- if nt==0 then
-  return ""
- elseif nt==1 and type(dt[1])=="string" then
-  return dt[1] 
- else
-  return xmlserialize(root,xmltexthandler) or ""
- end
+  local dt=root.dt
+  if not dt then
+    return ""
+  end
+  local nt=#dt 
+  if nt==0 then
+    return ""
+  elseif nt==1 and type(dt[1])=="string" then
+    return dt[1] 
+  else
+    return xmlserialize(root,xmltexthandler) or ""
+  end
 end
 function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+  return root and xmlserialize(root,xmltexthandler) or ""
 end
 local function text(collected) 
- if collected then 
-  local e=collected[1] or collected 
-  return e and xmltotext(e) or ""
- else
-  return ""
- end
+  if collected then 
+    local e=collected[1] or collected 
+    return e and xmltotext(e) or ""
+  else
+    return ""
+  end
 end
 local function texts(collected)
- if not collected then
-  return {} 
- end
- local nc=#collected
- if nc==0 then
-  return {} 
- end
- local t,n={},0
- for c=1,nc do
-  local e=collected[c]
-  if e and e.dt then
-   n=n+1
-   t[n]=e.dt
+  if not collected then
+    return {} 
   end
- end
- return t
+  local nc=#collected
+  if nc==0 then
+    return {} 
+  end
+  local t,n={},0
+  for c=1,nc do
+    local e=collected[c]
+    if e and e.dt then
+      n=n+1
+      t[n]=e.dt
+    end
+  end
+  return t
 end
 local function tag(collected,n)
- if not collected then
-  return
- end
- local nc=#collected
- if nc==0 then
-  return
- end
- local c
- if n==0 or not n then
-  c=collected[1]
- elseif n>1 then
-  c=collected[n]
- else
-  c=collected[nc-n+1]
- end
- return c and c.tg
+  if not collected then
+    return
+  end
+  local nc=#collected
+  if nc==0 then
+    return
+  end
+  local c
+  if n==0 or not n then
+    c=collected[1]
+  elseif n>1 then
+    c=collected[n]
+  else
+    c=collected[nc-n+1]
+  end
+  return c and c.tg
 end
 local function name(collected,n)
- if not collected then
-  return
- end
- local nc=#collected
- if nc==0 then
-  return
- end
- local c
- if n==0 or not n then
-  c=collected[1]
- elseif n>1 then
-  c=collected[n]
- else
-  c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
-  return c.tg
- else
-  return c.ns..":"..c.tg
- end
+  if not collected then
+    return
+  end
+  local nc=#collected
+  if nc==0 then
+    return
+  end
+  local c
+  if n==0 or not n then
+    c=collected[1]
+  elseif n>1 then
+    c=collected[n]
+  else
+    c=collected[nc-n+1]
+  end
+  if not c then
+  elseif c.ns=="" then
+    return c.tg
+  else
+    return c.ns..":"..c.tg
+  end
 end
 local function tags(collected,nonamespace)
- if not collected then
-  return
- end
- local nc=#collected
- if nc==0 then
-  return
- end
- local t,n={},0
- for c=1,nc do
-  local e=collected[c]
-  local ns,tg=e.ns,e.tg
-  n=n+1
-  if nonamespace or ns=="" then
-   t[n]=tg
-  else
-   t[n]=ns..":"..tg
+  if not collected then
+    return
   end
- end
- return t
+  local nc=#collected
+  if nc==0 then
+    return
+  end
+  local t,n={},0
+  for c=1,nc do
+    local e=collected[c]
+    local ns,tg=e.ns,e.tg
+    n=n+1
+    if nonamespace or ns=="" then
+      t[n]=tg
+    else
+      t[n]=ns..":"..tg
+    end
+  end
+  return t
 end
 local function empty(collected,spacesonly)
- if not collected then
-  return true
- end
- local nc=#collected
- if nc==0 then
-  return true
- end
- for c=1,nc do
-  local e=collected[c]
-  if e then
-   local edt=e.dt
-   if edt then
-    local n=#edt
-    if n==1 then
-     local edk=edt[1]
-     local typ=type(edk)
-     if typ=="table" then
-      return false
-     elseif edk~="" then
-      return false
-     elseif spacesonly and not find(edk,"%S") then
-      return false
-     end
-    elseif n>1 then
-     return false
+  if not collected then
+    return true
+  end
+  local nc=#collected
+  if nc==0 then
+    return true
+  end
+  for c=1,nc do
+    local e=collected[c]
+    if e then
+      local edt=e.dt
+      if edt then
+        local n=#edt
+        if n==1 then
+          local edk=edt[1]
+          local typ=type(edk)
+          if typ=="table" then
+            return false
+          elseif edk~="" then
+            return false
+          elseif spacesonly and not find(edk,"%S") then
+            return false
+          end
+        elseif n>1 then
+          return false
+        end
+      end
     end
-   end
   end
- end
- return true
+  return true
 end
 finalizers.first=first
 finalizers.last=last
@@ -19543,124 +15969,124 @@
 finalizers.tags=tags
 finalizers.empty=empty
 function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+  return first(xmlfilter(id,pattern))
 end
 function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+  return last(xmlfilter(id,pattern))
 end
 function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+  return count(xmlfilter(id,pattern))
 end
 function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+  return attribute(xmlfilter(id,pattern),a,default)
 end
 function xml.raw(id,pattern)
- if pattern then
-  return raw(xmlfilter(id,pattern))
- else
-  return raw(id)
- end
+  if pattern then
+    return raw(xmlfilter(id,pattern))
+  else
+    return raw(id)
+  end
 end
 function xml.text(id,pattern) 
- if pattern then
-  local collected=xmlfilter(id,pattern)
-  return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
-  return xmltotext(id) or ""
- else
-  return ""
- end
+  if pattern then
+    local collected=xmlfilter(id,pattern)
+    return collected and #collected>0 and xmltotext(collected[1]) or ""
+  elseif id then
+    return xmltotext(id) or ""
+  else
+    return ""
+  end
 end
 function xml.pure(id,pattern)
- if pattern then
-  local collected=xmlfilter(id,pattern)
-  if collected and #collected>0 then
-   parsedentity=unescapedentity
-   local s=collected and #collected>0 and xmltotext(collected[1]) or ""
-   parsedentity=reparsedentity
-   return s
+  if pattern then
+    local collected=xmlfilter(id,pattern)
+    if collected and #collected>0 then
+      parsedentity=unescapedentity
+      local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+      parsedentity=reparsedentity
+      return s
+    else
+      return ""
+    end
   else
-   return ""
+    parsedentity=unescapedentity
+    local s=xmltotext(id) or ""
+    parsedentity=reparsedentity
+    return s
   end
- else
-  parsedentity=unescapedentity
-  local s=xmltotext(id) or ""
-  parsedentity=reparsedentity
-  return s
- end
 end
 xml.content=text
 function xml.position(id,pattern,n) 
- return position(xmlfilter(id,pattern),n)
+  return position(xmlfilter(id,pattern),n)
 end
 function xml.match(id,pattern) 
- return match(xmlfilter(id,pattern))
+  return match(xmlfilter(id,pattern))
 end
 function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+  return empty(xmlfilter(id,pattern),spacesonly)
 end
 xml.all=xml.filter
 xml.index=xml.position
 xml.found=xml.filter
 local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
-  t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+  local t={}
+  for e in xmlcollected(x[1] or x,"/*") do
+    t[e.tg]=xmltostring(e.dt) or ""
+  end
+  return next(t) and t or nil
 end
 xml.table=totable
 finalizers.table=totable
 local function textonly(e,t)
- if e then
-  local edt=e.dt
-  if edt then
-   for i=1,#edt do
-    local e=edt[i]
-    if type(e)=="table" then
-     textonly(e,t)
-    else
-     t[#t+1]=e
+  if e then
+    local edt=e.dt
+    if edt then
+      for i=1,#edt do
+        local e=edt[i]
+        if type(e)=="table" then
+          textonly(e,t)
+        else
+          t[#t+1]=e
+        end
+      end
     end
-   end
   end
- end
- return t
+  return t
 end
 function xml.textonly(e) 
- return concat(textonly(e,{}))
+  return concat(textonly(e,{}))
 end
 function finalizers.lowerall(collected)
- for c=1,#collected do
-  local e=collected[c]
-  if not e.special then
-   e.tg=lower(e.tg)
-   local eat=e.at
-   if eat then
-    local t={}
-    for k,v in next,eat do
-     t[lower(k)]=v
+  for c=1,#collected do
+    local e=collected[c]
+    if not e.special then
+      e.tg=lower(e.tg)
+      local eat=e.at
+      if eat then
+        local t={}
+        for k,v in next,eat do
+          t[lower(k)]=v
+        end
+        e.at=t
+      end
     end
-    e.at=t
-   end
   end
- end
 end
 function finalizers.upperall(collected)
- for c=1,#collected do
-  local e=collected[c]
-  if not e.special then
-   e.tg=upper(e.tg)
-   local eat=e.at
-   if eat then
-    local t={}
-    for k,v in next,eat do
-     t[upper(k)]=v
+  for c=1,#collected do
+    local e=collected[c]
+    if not e.special then
+      e.tg=upper(e.tg)
+      local eat=e.at
+      if eat then
+        local t={}
+        for k,v in next,eat do
+          t[upper(k)]=v
+        end
+        e.at=t
+      end
     end
-    e.at=t
-   end
   end
- end
 end
 
 
@@ -19670,14 +16096,14 @@
 
 package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
 
--- original size: 6407, stripped down to: 4640
+-- original size: 6407, stripped down to: 4965
 
 if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to trac-log.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local formatters=string.formatters
 local reporters=logs.reporters
@@ -19686,152 +16112,152 @@
 local xmltext=xml.text
 local xmlfirst=xml.first
 local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
-  return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
-  local categoryname=category.at.name or ""
-  if wantedcategories==true or wantedcategories[categoryname] then
-   if nofcategories>1 then
-    report("%s options:",categoryname)
-    report()
-   end
-   for subcategory in xmlcollected(category,"/subcategory") do
-    for flag in xmlcollected(subcategory,"/flag") do
-     local name=flag.at.name
-     local value=flag.at.value
-     local short=xmltext(xmlfirst(flag,"/short"))
-     if value then
-      report("--%-20s %s",formatters["%s=%s"](name,value),short)
-     else
-      report("--%-20s %s",name,short)
-     end
+  local root=xml.convert(specification.helpinfo or "")
+  if not root then
+    return
+  end
+  local xs=xml.gethandlers("string")
+  xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+  xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+  local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+  local nofcategories=xml.count(root,"/application/flags/category")
+  local report=specification.report
+  for category in xmlcollected(root,"/application/flags/category") do
+    local categoryname=category.at.name or ""
+    if wantedcategories==true or wantedcategories[categoryname] then
+      if nofcategories>1 then
+        report("%s options:",categoryname)
+        report()
+      end
+      for subcategory in xmlcollected(category,"/subcategory") do
+        for flag in xmlcollected(subcategory,"/flag") do
+          local name=flag.at.name
+          local value=flag.at.value
+          local short=xmltext(xmlfirst(flag,"/short"))
+          if value then
+            report("--%-20s %s",formatters["%s=%s"](name,value),short)
+          else
+            report("--%-20s %s",name,short)
+          end
+        end
+        report()
+      end
     end
-    report()
-   end
   end
- end
- for category in xmlcollected(root,"/application/examples/category") do
-  local title=xmltext(xmlfirst(category,"/title"))
-  if title and title~="" then
-   report()
-   report(title)
-   report()
+  for category in xmlcollected(root,"/application/examples/category") do
+    local title=xmltext(xmlfirst(category,"/title"))
+    if title and title~="" then
+      report()
+      report(title)
+      report()
+    end
+    for subcategory in xmlcollected(category,"/subcategory") do
+      for example in xmlcollected(subcategory,"/example") do
+        local command=xmltext(xmlfirst(example,"/command"))
+        local comment=xmltext(xmlfirst(example,"/comment"))
+        report(command)
+      end
+      report()
+    end
   end
-  for subcategory in xmlcollected(category,"/subcategory") do
-   for example in xmlcollected(subcategory,"/example") do
-    local command=xmltext(xmlfirst(example,"/command"))
-    local comment=xmltext(xmlfirst(example,"/comment"))
-    report(command)
-   end
-   report()
+  for comment in xmlcollected(root,"/application/comments/comment") do
+    local comment=xmltext(comment)
+    report()
+    report(comment)
+    report()
   end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
-  local comment=xmltext(comment)
-  report()
-  report(comment)
-  report()
- end
 end
 local reporthelp=reporters.help
 local exporthelp=reporters.export
 local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
-  return false
- end
- if type(helpinfo)~="string" then
-  helpinfo="Warning: no helpinfo found."
-  t.helpinfo=helpinfo
-  return false
- end
- if string.find(helpinfo,".xml$") then
-  local ownscript=environment.ownscript
-  local helpdata=false
-  if ownscript then
-   local helpfile=file.join(file.pathpart(ownscript),helpinfo)
-   helpdata=io.loaddata(helpfile)
-   if helpdata=="" then
-    helpdata=false
-   end
+  local helpinfo=t.helpinfo
+  if type(helpinfo)=="table" then
+    return false
   end
-  if not helpdata then
-   local helpfile=resolvers.findfile(helpinfo,"tex")
-   helpdata=helpfile and io.loaddata(helpfile)
+  if type(helpinfo)~="string" then
+    helpinfo="Warning: no helpinfo found."
+    t.helpinfo=helpinfo
+    return false
   end
-  if helpdata and helpdata~="" then
-   helpinfo=helpdata
-  else
-   helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
+  if string.find(helpinfo,".xml$") then
+    local ownscript=environment.ownscript
+    local helpdata=false
+    if ownscript then
+      local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+      helpdata=io.loaddata(helpfile)
+      if helpdata=="" then
+        helpdata=false
+      end
+    end
+    if not helpdata then
+      local helpfile=resolvers.findfile(helpinfo,"tex")
+      helpdata=helpfile and io.loaddata(helpfile)
+    end
+    if helpdata and helpdata~="" then
+      helpinfo=helpdata
+    else
+      helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
+    end
   end
- end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+  t.helpinfo=helpinfo
+  return string.find(t.helpinfo,"^<%?xml") and true or false
 end
 function reporters.help(t,...)
- if xmlfound(t) then
-  showhelp(t,...)
- else
-  reporthelp(t,...)
- end
+  if xmlfound(t) then
+    showhelp(t,...)
+  else
+    reporthelp(t,...)
+  end
 end
 function reporters.export(t,methods,filename)
- if not xmlfound(t) then
-  return exporthelp(t)
- end
- if not methods or methods=="" then
-  methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
-  filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
-  return exporthelp(t)
- end
- if methods=="all" then
-  methods=table.keys(exporters)
- elseif type(methods)=="string" then
-  methods=utilities.parsers.settings_to_array(methods)
- else
-  return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
-  filename=false
- elseif file.pathpart(filename)=="" then
-  t.report("export file %a will not be saved on the current path (safeguard)",filename)
-  return
- end
- for i=1,#methods do
-  local method=methods[i]
-  local exporter=exporters[method]
-  if exporter then
-   local result=exporter(t,method)
-   if result and result~="" then
-    if filename then
-     local fullname=file.replacesuffix(filename,method)
-     t.report("saving export in %a",fullname)
-     dir.mkdirs(file.pathpart(fullname))
-     io.savedata(fullname,result)
+  if not xmlfound(t) then
+    return exporthelp(t)
+  end
+  if not methods or methods=="" then
+    methods=environment.arguments["exporthelp"]
+  end
+  if not filename or filename=="" then
+    filename=environment.files[1]
+  end
+  dofile(resolvers.findfile("trac-exp.lua","tex"))
+  local exporters=logs.exporters
+  if not exporters or not methods then
+    return exporthelp(t)
+  end
+  if methods=="all" then
+    methods=table.keys(exporters)
+  elseif type(methods)=="string" then
+    methods=utilities.parsers.settings_to_array(methods)
+  else
+    return exporthelp(t)
+  end
+  if type(filename)~="string" or filename=="" then
+    filename=false
+  elseif file.pathpart(filename)=="" then
+    t.report("export file %a will not be saved on the current path (safeguard)",filename)
+    return
+  end
+  for i=1,#methods do
+    local method=methods[i]
+    local exporter=exporters[method]
+    if exporter then
+      local result=exporter(t,method)
+      if result and result~="" then
+        if filename then
+          local fullname=file.replacesuffix(filename,method)
+          t.report("saving export in %a",fullname)
+          dir.mkdirs(file.pathpart(fullname))
+          io.savedata(fullname,result)
+        else
+          reporters.lines(t,result)
+        end
+      else
+        t.report("no output from exporter %a",method)
+      end
     else
-     reporters.lines(t,result)
+      t.report("unknown exporter %a",method)
     end
-   else
-    t.report("no output from exporter %a",method)
-   end
-  else
-   t.report("unknown exporter %a",method)
   end
- end
 end
 
 
@@ -19841,14 +16267,14 @@
 
 package.loaded["data-ini"] = package.loaded["data-ini"] or true
 
--- original size: 11099, stripped down to: 7152
+-- original size: 11099, stripped down to: 7516
 
 if not modules then modules={} end modules ['data-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files",
 }
 local next,type,getmetatable,rawset=next,type,getmetatable,rawset
 local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
@@ -19855,9 +16281,9 @@
 local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
 local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
 local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false  trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false  trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
 local report_initialization=logs.reporter("resolvers","initialization")
 resolvers=resolvers or {}
 local resolvers=resolvers
@@ -19864,126 +16290,126 @@
 texconfig.kpse_init=false
 texconfig.shell_escape='t'
 if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+  local default_texmfcnf=kpse.default_texmfcnf()
+  default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+  default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+  default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+  default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+  environment.default_texmfcnf=default_texmfcnf
 end
 kpse={ original=kpse }
 setmetatable(kpse,{
- __index=function(kp,name)
-  report_initialization("fatal error: kpse library is accessed (key: %s)",name)
-  os.exit()
- end
+  __index=function(kp,name)
+    report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+    os.exit()
+  end
 } )
 do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
-  ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
-  ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+  local osfontdir=osgetenv("OSFONTDIR")
+  if osfontdir and osfontdir~="" then
+  elseif osname=="windows" then
+    ossetenv("OSFONTDIR","c:/windows/fonts//")
+  elseif osname=="macosx" then
+    ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+  end
 end
 do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
-  homedir=char(127) 
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir) 
- ossetenv("USERPROFILE",homedir) 
- environment.homedir=homedir
+  local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+  if not homedir or homedir=="" then
+    homedir=char(127) 
+  end
+  homedir=file.collapsepath(homedir)
+  ossetenv("HOME",homedir) 
+  ossetenv("USERPROFILE",homedir) 
+  environment.homedir=homedir
 end
 do
- local args=environment.originalarguments or arg 
- if not environment.ownmain then
-  environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin  or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
-  ownpath=args[-1] or arg[-1]
-  ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
-  if not ownpath or ownpath=="" then
-   ownpath=args[-0] or arg[-0]
-   ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+  local args=environment.originalarguments or arg 
+  if not environment.ownmain then
+    environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
   end
-  local binary=ownbin
-  if not ownpath or ownpath=="" then
-   ownpath=ownpath and filedirname(binary)
-  end
-  if not ownpath or ownpath=="" then
-   if os.binsuffix~="" then
-    binary=file.replacesuffix(binary,os.binsuffix)
-   end
-   local path=osgetenv("PATH")
-   if path then
-    for p in gmatch(path,"[^"..io.pathseparator.."]+") do
-     local b=filejoin(p,binary)
-     if lfs.isfile(b) then
-      local olddir=lfs.currentdir()
-      if lfs.chdir(p) then
-       local pp=lfs.currentdir()
-       if trace_locating and p~=pp then
-        report_initialization("following symlink %a to %a",p,pp)
-       end
-       ownpath=pp
-       lfs.chdir(olddir)
-      else
-       if trace_locating then
-        report_initialization("unable to check path %a",p)
-       end
-       ownpath=p
+  local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+  local ownpath=environment.ownpath or os.selfdir
+  ownbin=file.collapsepath(ownbin)
+  ownpath=file.collapsepath(ownpath)
+  if not ownpath or ownpath=="" or ownpath=="unset" then
+    ownpath=args[-1] or arg[-1]
+    ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+    if not ownpath or ownpath=="" then
+      ownpath=args[-0] or arg[-0]
+      ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+    end
+    local binary=ownbin
+    if not ownpath or ownpath=="" then
+      ownpath=ownpath and filedirname(binary)
+    end
+    if not ownpath or ownpath=="" then
+      if os.binsuffix~="" then
+        binary=file.replacesuffix(binary,os.binsuffix)
       end
-      break
-     end
+      local path=osgetenv("PATH")
+      if path then
+        for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+          local b=filejoin(p,binary)
+          if lfs.isfile(b) then
+            local olddir=lfs.currentdir()
+            if lfs.chdir(p) then
+              local pp=lfs.currentdir()
+              if trace_locating and p~=pp then
+                report_initialization("following symlink %a to %a",p,pp)
+              end
+              ownpath=pp
+              lfs.chdir(olddir)
+            else
+              if trace_locating then
+                report_initialization("unable to check path %a",p)
+              end
+              ownpath=p
+            end
+            break
+          end
+        end
+      end
     end
-   end
+    if not ownpath or ownpath=="" then
+      ownpath="."
+      report_initialization("forcing fallback to ownpath %a",ownpath)
+    elseif trace_locating then
+      report_initialization("using ownpath %a",ownpath)
+    end
   end
-  if not ownpath or ownpath=="" then
-   ownpath="."
-   report_initialization("forcing fallback to ownpath %a",ownpath)
-  elseif trace_locating then
-   report_initialization("using ownpath %a",ownpath)
-  end
- end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+  environment.ownbin=ownbin
+  environment.ownpath=ownpath
 end
 resolvers.ownpath=environment.ownpath
 function resolvers.getownpath()
- return environment.ownpath
+  return environment.ownpath
 end
 do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
-  ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
-  ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
-  ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
-  report_initialization("error: unable to locate ownpath")
-  os.exit()
- end
+  local ownpath=environment.ownpath or dir.current()
+  if ownpath then
+    ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+    ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+    ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+  else
+    report_initialization("error: unable to locate ownpath")
+    os.exit()
+  end
 end
-local texos=environment.texos   or osgetenv("TEXOS")
+local texos=environment.texos  or osgetenv("TEXOS")
 local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
 if not texos or texos=="" then
- texos=file.basename(texmfos)
+  texos=file.basename(texmfos)
 end
 ossetenv('TEXMFOS',texmfos)   
-ossetenv('TEXOS',texos)  
-ossetenv('SELFAUTOSYSTEM',os.platform)  
+ossetenv('TEXOS',texos)    
+ossetenv('SELFAUTOSYSTEM',os.platform) 
 environment.texos=texos
 environment.texmfos=texmfos
 local texroot=environment.texroot or osgetenv("TEXROOT")
 if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+  texroot=osgetenv('SELFAUTOPARENT')
+  ossetenv('TEXROOT',texroot)
 end
 environment.texroot=file.collapsepath(texroot)
 local prefixes=utilities.storage.allocate()
@@ -19992,30 +16418,30 @@
 local abstract={}
 local dynamic={}
 function resolvers.resetresolve(str)
- resolved,abstract={},{}
+  resolved,abstract={},{}
 end
 function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
-  for i=1,#all do
-   all[i]=all[i]..":"
+  local all=table.sortedkeys(prefixes)
+  if separator then
+    for i=1,#all do
+      all[i]=all[i]..":"
+    end
   end
- end
- return all
+  return all
 end
 local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
-  return action(target)
- else
-  return method..":"..target
- end
+  local action=prefixes[method]
+  if action then
+    return action(target)
+  else
+    return method..":"..target
+  end
 end
 function resolvers.unresolve(str)
- return abstract[str] or str
+  return abstract[str] or str
 end
 function resolvers.setdynamic(str)
- dynamic[str]=true
+  dynamic[str]=true
 end
 local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
 local prefix=C(R("az")^2)*P(":")
@@ -20024,65 +16450,65 @@
 local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
 local p_simple=prefix*P(-1)
 local function resolve(str) 
- if type(str)=="table" then
-  local res={}
-  for i=1,#str do
-   res[i]=resolve(str[i])
+  if type(str)=="table" then
+    local res={}
+    for i=1,#str do
+      res[i]=resolve(str[i])
+    end
+    return res
   end
-  return res
- end
- local res=resolved[str]
- if res then
-  return res
- end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
-  local res=action(res)
-  if not dynamic[simple] then
-   resolved[simple]=res
-   abstract[res]=simple
+  local res=resolved[str]
+  if res then
+    return res
   end
+  local simple=lpegmatch(p_simple,str)
+  local action=prefixes[simple]
+  if action then
+    local res=action(res)
+    if not dynamic[simple] then
+      resolved[simple]=res
+      abstract[res]=simple
+    end
+    return res
+  end
+  res=lpegmatch(p_resolve,str)
+  resolved[str]=res
+  abstract[res]=str
   return res
- end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
- return res
 end
 resolvers.resolve=resolve
 if type(osuname)=="function" then
- for k,v in next,osuname() do
-  if not prefixes[k] then
-   prefixes[k]=function() return v end
+  for k,v in next,osuname() do
+    if not prefixes[k] then
+      prefixes[k]=function() return v end
+    end
   end
- end
 end
 if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
-  if t then
-   rawset(t,k,v)
+  local pattern
+  local function makepattern(t,k,v)
+    if t then
+      rawset(t,k,v)
+    end
+    local colon=P(":")
+    for k,v in table.sortedpairs(prefixes) do
+      if p then
+        p=P(k)+p
+      else
+        p=P(k)
+      end
+    end
+    pattern=Cs((p*colon+colon/";"+P(1))^0)
   end
-  local colon=P(":")
-  for k,v in table.sortedpairs(prefixes) do
-   if p then
-    p=P(k)+p
-   else
-    p=P(k)
-   end
+  makepattern()
+  table.setmetatablenewindex(prefixes,makepattern)
+  function resolvers.repath(str)
+    return lpegmatch(pattern,str)
   end
-  pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
-  return lpegmatch(pattern,str)
- end
 else 
- function resolvers.repath(str)
-  return str
- end
+  function resolvers.repath(str)
+    return str
+  end
 end
 
 
@@ -20092,14 +16518,14 @@
 
 package.loaded["data-exp"] = package.loaded["data-exp"] or true
 
--- original size: 18105, stripped down to: 10389
+-- original size: 18105, stripped down to: 11207
 
 if not modules then modules={} end modules ['data-exp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files",
 }
 local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
 local concat,sort=table.concat,table.sort
@@ -20109,21 +16535,21 @@
 local type,next=type,next
 local isdir=lfs.isdir
 local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false  trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true   trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true  trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
 local report_expansions=logs.reporter("resolvers","expansions")
 local report_globbing=logs.reporter("resolvers","globbing")
 local resolvers=resolvers
 local resolveprefix=resolvers.resolve
 local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do     
-  for sa in gmatch(a,"[^,]+") do    
-   n=n+1;t[n]=sa..sb
+  local t,n={},0
+  for sb in gmatch(b,"[^,]+") do       
+    for sa in gmatch(a,"[^,]+") do     
+      n=n+1;t[n]=sa..sb
+    end
   end
- end
- return concat(t,",")
+  return concat(t,",")
 end
 local comma=P(",")
 local nocomma=(1-comma)^1
@@ -20133,7 +16559,7 @@
 local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
 local function f_first (a,b) return lpegmatch(after,b,1,a) end
 local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both  (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
 local left=P("{")
 local right=P("}")
 local var=P((1-S("{}" ))^0)
@@ -20146,141 +16572,141 @@
 local stripper_1=lpeg.stripper ("{}@")
 local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
 local function splitpathexpr(str,newlist,validate) 
- if trace_expansions then
-  report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
- repeat
-  local old=str
+  if trace_expansions then
+    report_expansions("expanding variable %a",str)
+  end
+  local t,ok,done=newlist or {},false,false
+  local n=#t
+  str=lpegmatch(replacer_1,str)
   repeat
-   local old=str
-   str=lpegmatch(l_first,str)
-  until old==str
-  repeat
-   local old=str
-   str=lpegmatch(l_second,str)
-  until old==str
-  repeat
-   local old=str
-   str=lpegmatch(l_both,str)
-  until old==str
-  repeat
-   local old=str
-   str=lpegmatch(l_rest,str)
-  until old==str
- until old==str 
- str=lpegmatch(stripper_1,str)
- if validate then
-  for s in gmatch(str,"[^,]+") do
-   s=validate(s)
-   if s then
-    n=n+1
-    t[n]=s
-   end
+    local old=str
+    repeat
+      local old=str
+      str=lpegmatch(l_first,str)
+    until old==str
+    repeat
+      local old=str
+      str=lpegmatch(l_second,str)
+    until old==str
+    repeat
+      local old=str
+      str=lpegmatch(l_both,str)
+    until old==str
+    repeat
+      local old=str
+      str=lpegmatch(l_rest,str)
+    until old==str
+  until old==str 
+  str=lpegmatch(stripper_1,str)
+  if validate then
+    for s in gmatch(str,"[^,]+") do
+      s=validate(s)
+      if s then
+        n=n+1
+        t[n]=s
+      end
+    end
+  else
+    for s in gmatch(str,"[^,]+") do
+      n=n+1
+      t[n]=s
+    end
   end
- else
-  for s in gmatch(str,"[^,]+") do
-   n=n+1
-   t[n]=s
+  if trace_expansions then
+    for k=1,#t do
+      report_expansions("% 4i: %s",k,t[k])
+    end
   end
- end
- if trace_expansions then
-  for k=1,#t do
-   report_expansions("% 4i: %s",k,t[k])
-  end
- end
- return t
+  return t
 end
 local function validate(s)
- s=collapsepath(s) 
- return s~="" and not find(s,"^!*unset/*$") and s
+  s=collapsepath(s) 
+  return s~="" and not find(s,"^!*unset/*$") and s
 end
 resolvers.validatedpath=validate 
 function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
-  splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+  local newlist={}
+  for k=1,#pathlist do
+    splitpathexpr(pathlist[k],newlist,validate)
+  end
+  return newlist
 end
 local usedhomedir=nil
-local donegation=(P("!")/""  )^0
+local donegation=(P("!")/""   )^0
 local doslashes=(P("\\")/"/"+1)^0
 local function expandedhome()
- if not usedhomedir then
-  usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
-  if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
-   if trace_expansions then
-    report_expansions("no home dir set, ignoring dependent path using current path")
-   end
-   usedhomedir="."
+  if not usedhomedir then
+    usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+    if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+      if trace_expansions then
+        report_expansions("no home dir set, ignoring dependent path using current path")
+      end
+      usedhomedir="."
+    end
   end
- end
- return usedhomedir
+  return usedhomedir
 end
 local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
 local cleanup=Cs(donegation*dohome*doslashes)
 resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+  return str and lpegmatch(cleanup,str) or ""
 end
 local expandhome=P("~")/"$HOME"
 local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
 local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1     )^0
+local dostring=(expandhome+1       )^0
 local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+  lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
 )
 function resolvers.checkedvariable(str) 
- return type(str)=="string" and lpegmatch(stripper,str) or str
+  return type(str)=="string" and lpegmatch(stripper,str) or str
 end
 local cache={}
 local splitter=lpeg.tsplitat(";") 
 local backslashswapper=lpeg.replacer("\\","/")
 local function splitconfigurationpath(str) 
- if str then
-  local found=cache[str]
-  if not found then
-   if str=="" then
-    found={}
-   else
-    local split=lpegmatch(splitter,lpegmatch(backslashswapper,str)) 
-    found={}
-    local noffound=0
-    for i=1,#split do
-     local s=split[i]
-     if not find(s,"^{*unset}*") then
-      noffound=noffound+1
-      found[noffound]=s
-     end
+  if str then
+    local found=cache[str]
+    if not found then
+      if str=="" then
+        found={}
+      else
+        local split=lpegmatch(splitter,lpegmatch(backslashswapper,str)) 
+        found={}
+        local noffound=0
+        for i=1,#split do
+          local s=split[i]
+          if not find(s,"^{*unset}*") then
+            noffound=noffound+1
+            found[noffound]=s
+          end
+        end
+        if trace_expansions then
+          report_expansions("splitting path specification %a",str)
+          for k=1,noffound do
+            report_expansions("% 4i: %s",k,found[k])
+          end
+        end
+        cache[str]=found
+      end
     end
-    if trace_expansions then
-     report_expansions("splitting path specification %a",str)
-     for k=1,noffound do
-      report_expansions("% 4i: %s",k,found[k])
-     end
-    end
-    cache[str]=found
-   end
+    return found
   end
-  return found
- end
 end
 resolvers.splitconfigurationpath=splitconfigurationpath
 function resolvers.splitpath(str)
- if type(str)=='table' then
-  return str
- else
-  return splitconfigurationpath(str)
- end
+  if type(str)=='table' then
+    return str
+  else
+    return splitconfigurationpath(str)
+  end
 end
 function resolvers.joinpath(str)
- if type(str)=='table' then
-  return joinpath(str)
- else
-  return str
- end
+  if type(str)=='table' then
+    return joinpath(str)
+  else
+    return str
+  end
 end
 local attributes,directory=lfs.attributes,lfs.dir
 local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -20293,201 +16719,201 @@
 local nofsharedscans=0
 local addcasecraptoo=true
 local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
-  if not lpegmatch(pattern,name) then
-   local mode=attributes(full..name,"mode")
-   if mode=="file" then
-    n=n+1
-    noffiles=noffiles+1
-    filelist[noffiles]=name
-   elseif mode=="directory" then
-    m=m+1
-    nofdirs=nofdirs+1
-    if path~="" then
-     dirlist[nofdirs]=path.."/"..name
-    else
-     dirlist[nofdirs]=name
+  local full=path=="" and spec or (spec..path..'/')
+  local dirlist={}
+  local nofdirs=0
+  local pattern=tolerant and lessweird or weird
+  local filelist={}
+  local noffiles=0
+  for name in directory(full) do
+    if not lpegmatch(pattern,name) then
+      local mode=attributes(full..name,"mode")
+      if mode=="file" then
+        n=n+1
+        noffiles=noffiles+1
+        filelist[noffiles]=name
+      elseif mode=="directory" then
+        m=m+1
+        nofdirs=nofdirs+1
+        if path~="" then
+          dirlist[nofdirs]=path.."/"..name
+        else
+          dirlist[nofdirs]=name
+        end
+      end
     end
-   end
   end
- end
- if noffiles>0 then
-  sort(filelist)
-  for i=1,noffiles do
-   local name=filelist[i]
-   local lower=lower(name)
-   local paths=files[lower]
-   if paths then
-    if onlyone then
-    else
-     if name~=lower then
-      local rl=remap[lower]
-      if not rl then
-       remap[lower]=name
-       r=r+1
-      elseif trace_globbing and rl~=name then
-       report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+  if noffiles>0 then
+    sort(filelist)
+    for i=1,noffiles do
+      local name=filelist[i]
+      local lower=lower(name)
+      local paths=files[lower]
+      if paths then
+        if onlyone then
+        else
+          if name~=lower then
+            local rl=remap[lower]
+            if not rl then
+              remap[lower]=name
+              r=r+1
+            elseif trace_globbing and rl~=name then
+              report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+            end
+            if addcasecraptoo then
+              local paths=files[name]
+              if not paths then
+                files[name]=path
+              elseif type(paths)=="string" then
+                files[name]={ paths,path }
+              else
+                paths[#paths+1]=path
+              end
+            end
+          end
+          if type(paths)=="string" then
+            files[lower]={ paths,path }
+          else
+            paths[#paths+1]=path
+          end
+        end
+      else 
+        files[lower]=path
+        if name~=lower then
+          local rl=remap[lower]
+          if not rl then
+            remap[lower]=name
+            r=r+1
+          elseif trace_globbing and rl~=name then
+            report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+          end
+        end
       end
-      if addcasecraptoo then
-       local paths=files[name]
-       if not paths then
-        files[name]=path
-       elseif type(paths)=="string" then
-        files[name]={ paths,path }
-       else
-        paths[#paths+1]=path
-       end
-      end
-     end
-     if type(paths)=="string" then
-      files[lower]={ paths,path }
-     else
-      paths[#paths+1]=path
-     end
     end
-   else 
-    files[lower]=path
-    if name~=lower then
-     local rl=remap[lower]
-     if not rl then
-      remap[lower]=name
-      r=r+1
-     elseif trace_globbing and rl~=name then
-      report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
-     end
+  end
+  if nofdirs>0 then
+    sort(dirlist)
+    for i=1,nofdirs do
+      files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
     end
-   end
   end
- end
- if nofdirs>0 then
-  sort(dirlist)
-  for i=1,nofdirs do
-   files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
-  end
- end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+  scancache[sub(full,1,-2)]=files
+  return files,remap,n,m,r
 end
 function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
-  local content=fullcache[realpath]
-  if content then
-   if trace_locating then
-    report_expansions("using cached scan of path %a, branch %a",path,branch or path)
-   end
-   nofsharedscans=nofsharedscans+1
-   return content
+  local realpath=resolveprefix(path)
+  if usecache then
+    local content=fullcache[realpath]
+    if content then
+      if trace_locating then
+        report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+      end
+      nofsharedscans=nofsharedscans+1
+      return content
+    end
   end
- end
- statistics.starttiming(timer)
- if trace_locating then
-  report_expansions("scanning path %a, branch %a",path,branch or path)
- end
- local content
- if isdir(realpath) then
-  local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
-  content={
-   metadata={
-    path=path,
-    files=n,
-    directories=m,
-    remappings=r,
-   },
-   files=files,
-   remap=remap,
-  }
+  statistics.starttiming(timer)
   if trace_locating then
-   report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
+    report_expansions("scanning path %a, branch %a",path,branch or path)
   end
- else
-  content={
-   metadata={
-    path=path,
-    files=0,
-    directories=0,
-    remappings=0,
-   },
-   files={},
-   remap={},
-  }
-  if trace_locating then
-   report_expansions("invalid path %a",realpath)
+  local content
+  if isdir(realpath) then
+    local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+    content={
+      metadata={
+        path=path,
+        files=n,
+        directories=m,
+        remappings=r,
+      },
+      files=files,
+      remap=remap,
+    }
+    if trace_locating then
+      report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
+    end
+  else
+    content={
+      metadata={
+        path=path,
+        files=0,
+        directories=0,
+        remappings=0,
+      },
+      files={},
+      remap={},
+    }
+    if trace_locating then
+      report_expansions("invalid path %a",realpath)
+    end
   end
- end
- if usecache then
-  scanned[#scanned+1]=realpath
-  fullcache[realpath]=content
- end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+  if usecache then
+    scanned[#scanned+1]=realpath
+    fullcache[realpath]=content
+  end
+  nofscans=nofscans+1
+  statistics.stoptiming(timer)
+  return content
 end
 function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true) 
+  return resolvers.scanfiles(path,branch,usecache,true,true) 
 end
 function resolvers.scandata()
- table.sort(scanned)
- return {
-  n=nofscans,
-  shared=nofsharedscans,
-  time=statistics.elapsedtime(timer),
-  paths=scanned,
- }
+  table.sort(scanned)
+  return {
+    n=nofscans,
+    shared=nofsharedscans,
+    time=statistics.elapsedtime(timer),
+    paths=scanned,
+  }
 end
 function resolvers.get_from_content(content,path,name) 
- if not content then
-  return
- end
- local files=content.files
- if not files then
-  return
- end
- local remap=content.remap
- if not remap then
-  return
- end
- if name then
-  local used=lower(name)
-  return path,remap[used] or used
- else
-  local name=path
-  local used=lower(name)
-  local path=files[used]
-  if path then
-   return path,remap[used] or used
+  if not content then
+    return
   end
- end
+  local files=content.files
+  if not files then
+    return
+  end
+  local remap=content.remap
+  if not remap then
+    return
+  end
+  if name then
+    local used=lower(name)
+    return path,remap[used] or used
+  else
+    local name=path
+    local used=lower(name)
+    local path=files[used]
+    if path then
+      return path,remap[used] or used
+    end
+  end
 end
 local nothing=function() end
 function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
-  local pattern=lower(pattern)
-  local files=content.files 
-  local remap=content.remap
-  if files and remap then
-   local f=sortedkeys(files)
-   local n=#f
-   local i=0
-   local function iterator()
-    while i<n do
-     i=i+1
-     local k=f[i]
-     if find(k,pattern) then
-      return files[k],remap and remap[k] or k
-     end
+  if content and type(pattern)=="string" then
+    local pattern=lower(pattern)
+    local files=content.files 
+    local remap=content.remap
+    if files and remap then
+      local f=sortedkeys(files)
+      local n=#f
+      local i=0
+      local function iterator()
+        while i<n do
+          i=i+1
+          local k=f[i]
+          if find(k,pattern) then
+            return files[k],remap and remap[k] or k
+          end
+        end
+      end
+      return iterator
     end
-   end
-   return iterator
   end
- end
- return nothing
+  return nothing
 end
 
 
@@ -20497,14 +16923,14 @@
 
 package.loaded["data-env"] = package.loaded["data-env"] or true
 
--- original size: 9360, stripped down to: 6312
+-- original size: 9360, stripped down to: 6903
 
 if not modules then modules={} end modules ['data-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files",
 }
 local lower,gsub=string.lower,string.gsub
 local next=next
@@ -20524,255 +16950,255 @@
 resolvers.usertypes=usertypes
 local luasuffixes=utilities.lua.suffixes
 local relations=allocate { 
- core={
-  ofm={ 
-   names={ "ofm","omega font metric","omega font metrics" },
-   variable='OFMFONTS',
-   suffixes={ 'ofm','tfm' },
+  core={
+    ofm={ 
+      names={ "ofm","omega font metric","omega font metrics" },
+      variable='OFMFONTS',
+      suffixes={ 'ofm','tfm' },
+    },
+    ovf={ 
+      names={ "ovf","omega virtual font","omega virtual fonts" },
+      variable='OVFFONTS',
+      suffixes={ 'ovf','vf' },
+    },
+    tfm={
+      names={ "tfm","tex font metric","tex font metrics" },
+      variable='TFMFONTS',
+      suffixes={ 'tfm' },
+    },
+    vf={
+      names={ "vf","virtual font","virtual fonts" },
+      variable='VFFONTS',
+      suffixes={ 'vf' },
+    },
+    otf={
+      names={ "otf","opentype","opentype font","opentype fonts"},
+      variable='OPENTYPEFONTS',
+      suffixes={ 'otf' },
+    },
+    ttf={
+      names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+      variable='TTFONTS',
+      suffixes={ 'ttf','ttc','dfont' },
+    },
+    afm={
+      names={ "afm","adobe font metric","adobe font metrics" },
+      variable="AFMFONTS",
+      suffixes={ "afm" },
+    },
+    pfb={
+      names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+      variable='T1FONTS',
+      suffixes={ 'pfb','pfa' },
+    },
+    fea={
+      names={ "fea","font feature","font features","font feature file","font feature files" },
+      variable='FONTFEATURES',
+      suffixes={ 'fea' },
+    },
+    cid={
+      names={ "cid","cid map","cid maps","cid file","cid files" },
+      variable='FONTCIDMAPS',
+      suffixes={ 'cid','cidmap' },
+    },
+    fmt={
+      names={ "fmt","format","tex format" },
+      variable='TEXFORMATS',
+      suffixes={ 'fmt' },
+    },
+    mem={ 
+      names={ 'mem',"metapost format" },
+      variable='MPMEMS',
+      suffixes={ 'mem' },
+    },
+    mp={
+      names={ "mp" },
+      variable='MPINPUTS',
+      suffixes={ 'mp','mpvi','mpiv','mpii' },
+      usertype=true,
+    },
+    tex={
+      names={ "tex" },
+      variable='TEXINPUTS',
+      suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+      usertype=true,
+    },
+    icc={
+      names={ "icc","icc profile","icc profiles" },
+      variable='ICCPROFILES',
+      suffixes={ 'icc' },
+    },
+    texmfscripts={
+      names={ "texmfscript","texmfscripts","script","scripts" },
+      variable='TEXMFSCRIPTS',
+      suffixes={ 'lua','rb','pl','py' },
+    },
+    lua={
+      names={ "lua" },
+      variable='LUAINPUTS',
+      suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+      usertype=true,
+    },
+    lib={
+      names={ "lib" },
+      variable='CLUAINPUTS',
+      suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
+    },
+    bib={
+      names={ 'bib' },
+      variable='BIBINPUTS',
+      suffixes={ 'bib' },
+      usertype=true,
+    },
+    bst={
+      names={ 'bst' },
+      variable='BSTINPUTS',
+      suffixes={ 'bst' },
+      usertype=true,
+    },
+    fontconfig={
+      names={ 'fontconfig','fontconfig file','fontconfig files' },
+      variable='FONTCONFIG_PATH',
+    },
+    pk={
+      names={ "pk" },
+      variable='PKFONTS',
+      suffixes={ 'pk' },
+    },
   },
-  ovf={ 
-   names={ "ovf","omega virtual font","omega virtual fonts" },
-   variable='OVFFONTS',
-   suffixes={ 'ovf','vf' },
+  obsolete={
+    enc={
+      names={ "enc","enc files","enc file","encoding files","encoding file" },
+      variable='ENCFONTS',
+      suffixes={ 'enc' },
+    },
+    map={
+      names={ "map","map files","map file" },
+      variable='TEXFONTMAPS',
+      suffixes={ 'map' },
+    },
+    lig={
+      names={ "lig files","lig file","ligature file","ligature files" },
+      variable='LIGFONTS',
+      suffixes={ 'lig' },
+    },
+    opl={
+      names={ "opl" },
+      variable='OPLFONTS',
+      suffixes={ 'opl' },
+    },
+    ovp={
+      names={ "ovp" },
+      variable='OVPFONTS',
+      suffixes={ 'ovp' },
+    },
   },
-  tfm={
-   names={ "tfm","tex font metric","tex font metrics" },
-   variable='TFMFONTS',
-   suffixes={ 'tfm' },
+  kpse={ 
+    base={
+      names={ 'base',"metafont format" },
+      variable='MFBASES',
+      suffixes={ 'base','bas' },
+    },
+    cmap={
+      names={ 'cmap','cmap files','cmap file' },
+      variable='CMAPFONTS',
+      suffixes={ 'cmap' },
+    },
+    cnf={
+      names={ 'cnf' },
+      suffixes={ 'cnf' },
+    },
+    web={
+      names={ 'web' },
+      suffixes={ 'web','ch' }
+    },
+    cweb={
+      names={ 'cweb' },
+      suffixes={ 'w','web','ch' },
+    },
+    gf={
+      names={ 'gf' },
+      suffixes={ '<resolution>gf' },
+    },
+    mf={
+      names={ 'mf' },
+      variable='MFINPUTS',
+      suffixes={ 'mf' },
+    },
+    mft={
+      names={ 'mft' },
+      suffixes={ 'mft' },
+    },
+    pk={
+      names={ 'pk' },
+      suffixes={ '<resolution>pk' },
+    },
   },
-  vf={
-   names={ "vf","virtual font","virtual fonts" },
-   variable='VFFONTS',
-   suffixes={ 'vf' },
-  },
-  otf={
-   names={ "otf","opentype","opentype font","opentype fonts"},
-   variable='OPENTYPEFONTS',
-   suffixes={ 'otf' },
-  },
-  ttf={
-   names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
-   variable='TTFONTS',
-   suffixes={ 'ttf','ttc','dfont' },
-  },
-  afm={
-   names={ "afm","adobe font metric","adobe font metrics" },
-   variable="AFMFONTS",
-   suffixes={ "afm" },
-  },
-  pfb={
-   names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
-   variable='T1FONTS',
-   suffixes={ 'pfb','pfa' },
-  },
-  fea={
-   names={ "fea","font feature","font features","font feature file","font feature files" },
-   variable='FONTFEATURES',
-   suffixes={ 'fea' },
-  },
-  cid={
-   names={ "cid","cid map","cid maps","cid file","cid files" },
-   variable='FONTCIDMAPS',
-   suffixes={ 'cid','cidmap' },
-  },
-  fmt={
-   names={ "fmt","format","tex format" },
-   variable='TEXFORMATS',
-   suffixes={ 'fmt' },
-  },
-  mem={ 
-   names={ 'mem',"metapost format" },
-   variable='MPMEMS',
-   suffixes={ 'mem' },
-  },
-  mp={
-   names={ "mp" },
-   variable='MPINPUTS',
-   suffixes={ 'mp','mpvi','mpiv','mpii' },
-   usertype=true,
-  },
-  tex={
-   names={ "tex" },
-   variable='TEXINPUTS',
-   suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
-   usertype=true,
-  },
-  icc={
-   names={ "icc","icc profile","icc profiles" },
-   variable='ICCPROFILES',
-   suffixes={ 'icc' },
-  },
-  texmfscripts={
-   names={ "texmfscript","texmfscripts","script","scripts" },
-   variable='TEXMFSCRIPTS',
-   suffixes={ 'lua','rb','pl','py' },
-  },
-  lua={
-   names={ "lua" },
-   variable='LUAINPUTS',
-   suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
-   usertype=true,
-  },
-  lib={
-   names={ "lib" },
-   variable='CLUAINPUTS',
-   suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
-  },
-  bib={
-   names={ 'bib' },
-   variable='BIBINPUTS',
-   suffixes={ 'bib' },
-   usertype=true,
-  },
-  bst={
-   names={ 'bst' },
-   variable='BSTINPUTS',
-   suffixes={ 'bst' },
-   usertype=true,
-  },
-  fontconfig={
-   names={ 'fontconfig','fontconfig file','fontconfig files' },
-   variable='FONTCONFIG_PATH',
-  },
-  pk={
-   names={ "pk" },
-   variable='PKFONTS',
-   suffixes={ 'pk' },
-  },
- },
- obsolete={
-  enc={
-   names={ "enc","enc files","enc file","encoding files","encoding file" },
-   variable='ENCFONTS',
-   suffixes={ 'enc' },
-  },
-  map={
-   names={ "map","map files","map file" },
-   variable='TEXFONTMAPS',
-   suffixes={ 'map' },
-  },
-  lig={
-   names={ "lig files","lig file","ligature file","ligature files" },
-   variable='LIGFONTS',
-   suffixes={ 'lig' },
-  },
-  opl={
-   names={ "opl" },
-   variable='OPLFONTS',
-   suffixes={ 'opl' },
-  },
-  ovp={
-   names={ "ovp" },
-   variable='OVPFONTS',
-   suffixes={ 'ovp' },
-  },
- },
- kpse={ 
-  base={
-   names={ 'base',"metafont format" },
-   variable='MFBASES',
-   suffixes={ 'base','bas' },
-  },
-  cmap={
-   names={ 'cmap','cmap files','cmap file' },
-   variable='CMAPFONTS',
-   suffixes={ 'cmap' },
-  },
-  cnf={
-   names={ 'cnf' },
-   suffixes={ 'cnf' },
-  },
-  web={
-   names={ 'web' },
-   suffixes={ 'web','ch' }
-  },
-  cweb={
-   names={ 'cweb' },
-   suffixes={ 'w','web','ch' },
-  },
-  gf={
-   names={ 'gf' },
-   suffixes={ '<resolution>gf' },
-  },
-  mf={
-   names={ 'mf' },
-   variable='MFINPUTS',
-   suffixes={ 'mf' },
-  },
-  mft={
-   names={ 'mft' },
-   suffixes={ 'mft' },
-  },
-  pk={
-   names={ 'pk' },
-   suffixes={ '<resolution>pk' },
-  },
- },
 }
 resolvers.relations=relations
 function resolvers.updaterelations()
- for category,categories in next,relations do
-  for name,relation in next,categories do
-   local rn=relation.names
-   local rv=relation.variable
-   if rn and rv then
-    local rs=relation.suffixes
-    local ru=relation.usertype
-    for i=1,#rn do
-     local rni=lower(gsub(rn[i]," ",""))
-     formats[rni]=rv
-     if rs then
-      suffixes[rni]=rs
-      for i=1,#rs do
-       local rsi=rs[i]
-       suffixmap[rsi]=rni
+  for category,categories in next,relations do
+    for name,relation in next,categories do
+      local rn=relation.names
+      local rv=relation.variable
+      if rn and rv then
+        local rs=relation.suffixes
+        local ru=relation.usertype
+        for i=1,#rn do
+          local rni=lower(gsub(rn[i]," ",""))
+          formats[rni]=rv
+          if rs then
+            suffixes[rni]=rs
+            for i=1,#rs do
+              local rsi=rs[i]
+              suffixmap[rsi]=rni
+            end
+          end
+        end
+        if ru then
+          usertypes[name]=true
+        end
       end
-     end
     end
-    if ru then
-     usertypes[name]=true
-    end
-   end
   end
- end
 end
 resolvers.updaterelations() 
 local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+  return k and rawget(t,lower(gsub(k," ",""))) or nil
 end
 setmetatableindex(formats,simplified)
 setmetatableindex(suffixes,simplified)
 setmetatableindex(suffixmap,simplified)
 function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+  local s=suffixes[str]
+  return s and s[1] or ""
 end
 function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+  return suffixes[str] or {}
 end
 for name,format in next,formats do
- dangerous[name]=true 
+  dangerous[name]=true 
 end
 dangerous.tex=nil
 function resolvers.formatofvariable(str)
- return formats[str] or ''
+  return formats[str] or ''
 end
 function resolvers.formatofsuffix(str) 
- return suffixmap[suffixonly(str)] or 'tex' 
+  return suffixmap[suffixonly(str)] or 'tex' 
 end
 function resolvers.variableofformat(str)
- return formats[str] or ''
+  return formats[str] or ''
 end
 function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
-  return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
-  return formats[v]
- end
- return ''
+  local v=formats[str]
+  if v then
+    return v
+  end
+  v=suffixmap[suffixonly(str)]
+  if v then
+    return formats[v]
+  end
+  return ''
 end
 
 
@@ -20782,14 +17208,14 @@
 
 package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
 
--- original size: 16116, stripped down to: 10782
+-- original size: 16116, stripped down to: 11459
 
 if not modules then modules={} end modules ['data-tmp']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.100,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local format,lower,gsub,concat=string.format,string.lower,string.gsub,table.concat
 local concat=table.concat
@@ -20797,19 +17223,19 @@
 local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
 local formatters=string.formatters
 local next,type=next,type
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false  trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
 local report_caches=logs.reporter("resolvers","caches")
 local report_resolvers=logs.reporter("resolvers","caching")
 local resolvers=resolvers
 local cleanpath=resolvers.cleanpath
-local directive_cleanup=false  directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false  directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
 local compile=utilities.lua.compile
 function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip   end
- return compile(luafile,lucfile,cleanup,strip)
+  if cleanup==nil then cleanup=directive_cleanup end
+  if strip==nil then strip=directive_strip  end
+  return compile(luafile,lucfile,cleanup,strip)
 end
 caches=caches or {}
 local caches=caches
@@ -20824,324 +17250,324 @@
 caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
 local writable,readables,usedreadables=nil,{},{}
 local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE") 
- if texmfcaches then
-  for k=1,#texmfcaches do
-   local cachepath=texmfcaches[k]
-   if cachepath~="" then
-    cachepath=resolvers.resolve(cachepath)
-    cachepath=resolvers.cleanpath(cachepath)
-    cachepath=file.collapsepath(cachepath)
-    local valid=isdir(cachepath)
-    if valid then
-     if is_readable(cachepath) then
-      readables[#readables+1]=cachepath
-      if not writable and is_writable(cachepath) then
-       writable=cachepath
+  local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE") 
+  if texmfcaches then
+    for k=1,#texmfcaches do
+      local cachepath=texmfcaches[k]
+      if cachepath~="" then
+        cachepath=resolvers.resolve(cachepath)
+        cachepath=resolvers.cleanpath(cachepath)
+        cachepath=file.collapsepath(cachepath)
+        local valid=isdir(cachepath)
+        if valid then
+          if is_readable(cachepath) then
+            readables[#readables+1]=cachepath
+            if not writable and is_writable(cachepath) then
+              writable=cachepath
+            end
+          end
+        elseif not writable and caches.force then
+          local cacheparent=file.dirname(cachepath)
+          if is_writable(cacheparent) and true then 
+            if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+              mkdirs(cachepath)
+              if isdir(cachepath) and is_writable(cachepath) then
+                report_caches("path %a created",cachepath)
+                writable=cachepath
+                readables[#readables+1]=cachepath
+              end
+            end
+          end
+        end
       end
-     end
-    elseif not writable and caches.force then
-     local cacheparent=file.dirname(cachepath)
-     if is_writable(cacheparent) and true then 
-      if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
-       mkdirs(cachepath)
-       if isdir(cachepath) and is_writable(cachepath) then
-        report_caches("path %a created",cachepath)
-        writable=cachepath
-        readables[#readables+1]=cachepath
-       end
+    end
+  end
+  local texmfcaches=caches.defaults
+  if texmfcaches then
+    for k=1,#texmfcaches do
+      local cachepath=texmfcaches[k]
+      cachepath=resolvers.expansion(cachepath) 
+      if cachepath~="" then
+        cachepath=resolvers.resolve(cachepath)
+        cachepath=resolvers.cleanpath(cachepath)
+        local valid=isdir(cachepath)
+        if valid and is_readable(cachepath) then
+          if not writable and is_writable(cachepath) then
+            readables[#readables+1]=cachepath
+            writable=cachepath
+            break
+          end
+        end
       end
-     end
     end
-   end
   end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
-  for k=1,#texmfcaches do
-   local cachepath=texmfcaches[k]
-   cachepath=resolvers.expansion(cachepath) 
-   if cachepath~="" then
-    cachepath=resolvers.resolve(cachepath)
-    cachepath=resolvers.cleanpath(cachepath)
-    local valid=isdir(cachepath)
-    if valid and is_readable(cachepath) then
-     if not writable and is_writable(cachepath) then
-      readables[#readables+1]=cachepath
-      writable=cachepath
-      break
-     end
+  if not writable then
+    report_caches("fatal error: there is no valid writable cache path defined")
+    os.exit()
+  elseif #readables==0 then
+    report_caches("fatal error: there is no valid readable cache path defined")
+    os.exit()
+  end
+  writable=dir.expandname(resolvers.cleanpath(writable))
+  local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash() 
+  if tree then
+    caches.tree=tree
+    writable=mkdirs(writable,base,more,tree)
+    for i=1,#readables do
+      readables[i]=file.join(readables[i],base,more,tree)
     end
-   end
+  else
+    writable=mkdirs(writable,base,more)
+    for i=1,#readables do
+      readables[i]=file.join(readables[i],base,more)
+    end
   end
- end
- if not writable then
-  report_caches("fatal error: there is no valid writable cache path defined")
-  os.exit()
- elseif #readables==0 then
-  report_caches("fatal error: there is no valid readable cache path defined")
-  os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash() 
- if tree then
-  caches.tree=tree
-  writable=mkdirs(writable,base,more,tree)
-  for i=1,#readables do
-   readables[i]=file.join(readables[i],base,more,tree)
+  if trace_cache then
+    for i=1,#readables do
+      report_caches("using readable path %a (order %s)",readables[i],i)
+    end
+    report_caches("using writable path %a",writable)
   end
- else
-  writable=mkdirs(writable,base,more)
-  for i=1,#readables do
-   readables[i]=file.join(readables[i],base,more)
+  identify=function()
+    return writable,readables
   end
- end
- if trace_cache then
-  for i=1,#readables do
-   report_caches("using readable path %a (order %s)",readables[i],i)
-  end
-  report_caches("using writable path %a",writable)
- end
- identify=function()
   return writable,readables
- end
- return writable,readables
 end
 function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
-  local result={}
-  local done={}
-  for i=1,#readables do
-   local readable=readables[i]
-   if readable==writable then
-    done[readable]=true
-    result[#result+1]=formatters["readable+writable: %a"](readable)
-   elseif usedreadables[i] then
-    done[readable]=true
-    result[#result+1]=formatters["readable: %a"](readable)
-   end
+  local writable,readables=identify()
+  if #readables>1 then
+    local result={}
+    local done={}
+    for i=1,#readables do
+      local readable=readables[i]
+      if readable==writable then
+        done[readable]=true
+        result[#result+1]=formatters["readable+writable: %a"](readable)
+      elseif usedreadables[i] then
+        done[readable]=true
+        result[#result+1]=formatters["readable: %a"](readable)
+      end
+    end
+    if not done[writable] then
+      result[#result+1]=formatters["writable: %a"](writable)
+    end
+    return concat(result,separator or " | ")
+  else
+    return writable or "?"
   end
-  if not done[writable] then
-   result[#result+1]=formatters["writable: %a"](writable)
-  end
-  return concat(result,separator or " | ")
- else
-  return writable or "?"
- end
 end
 function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+  return concat(resolvers.configurationfiles(),";")
 end
 function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
-  report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+  tree=gsub(tree,"[\\/]+$","")
+  tree=lower(tree)
+  local hash=md5.hex(tree)
+  if trace_cache or trace_locating then
+    report_caches("hashing tree %a, hash %a",tree,hash)
+  end
+  return hash
 end
 function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
-  return false
- else
-  return caches.hashed(tree)
- end
+  local tree=caches.configfiles()
+  if not tree or tree=="" then
+    return false
+  else
+    return caches.hashed(tree)
+  end
 end
 local r_cache,w_cache={},{} 
 local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
-  local writable,readables=identify() 
-  if #tags>0 then
-   done={}
-   for i=1,#readables do
-    done[i]=file.join(readables[i],...)
-   end
-  else
-   done=readables
+  local tags={... }
+  local hash=concat(tags,"/")
+  local done=r_cache[hash]
+  if not done then
+    local writable,readables=identify() 
+    if #tags>0 then
+      done={}
+      for i=1,#readables do
+        done[i]=file.join(readables[i],...)
+      end
+    else
+      done=readables
+    end
+    r_cache[hash]=done
   end
-  r_cache[hash]=done
- end
- return done
+  return done
 end
 local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
-  local writable,readables=identify() 
-  if #tags>0 then
-   done=mkdirs(writable,...)
-  else
-   done=writable
+  local tags={... }
+  local hash=concat(tags,"/")
+  local done=w_cache[hash]
+  if not done then
+    local writable,readables=identify() 
+    if #tags>0 then
+      done=mkdirs(writable,...)
+    else
+      done=writable
+    end
+    w_cache[hash]=done
   end
-  w_cache[hash]=done
- end
- return done
+  return done
 end
 caches.getreadablepaths=getreadablepaths
 caches.getwritablepath=getwritablepath
 function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
- if is_readable(fullname) then
-  return fullname,path 
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
-  local path=rd[i]
-  local fullname=file.join(path,filename)
+  local fullname,path=caches.setfirstwritablefile(filename,...)
   if is_readable(fullname) then
-   usedreadables[i]=true
-   return fullname,path 
+    return fullname,path 
   end
- end
- return fullname,path 
+  local rd=getreadablepaths(...)
+  for i=1,#rd do
+    local path=rd[i]
+    local fullname=file.join(path,filename)
+    if is_readable(fullname) then
+      usedreadables[i]=true
+      return fullname,path 
+    end
+  end
+  return fullname,path 
 end
 function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+  local wr=getwritablepath(...)
+  local fullname=file.join(wr,filename)
+  return fullname,wr
 end
 function caches.define(category,subcategory) 
- return function()
-  return getwritablepath(category,subcategory)
- end
+  return function()
+    return getwritablepath(category,subcategory)
+  end
 end
 function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+  return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
 end
 function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
-  readables={ readables }
- end
- for i=1,#readables do
-  local path=readables[i]
-  local loader=false
-  local tmaname,tmcname=caches.setluanames(path,name)
-  if isfile(tmcname) then
-   loader=loadfile(tmcname)
+  if type(readables)=="string" then
+    readables={ readables }
   end
-  if not loader and isfile(tmaname) then
-   local tmacrap,tmcname=caches.setluanames(writable,name)
-   if isfile(tmcname) then
-    loader=loadfile(tmcname)
-   end
-   utilities.lua.compile(tmaname,tmcname)
-   if isfile(tmcname) then
-    loader=loadfile(tmcname)
-   end
-   if not loader then
-    loader=loadfile(tmaname)
-   end
+  for i=1,#readables do
+    local path=readables[i]
+    local loader=false
+    local tmaname,tmcname=caches.setluanames(path,name)
+    if isfile(tmcname) then
+      loader=loadfile(tmcname)
+    end
+    if not loader and isfile(tmaname) then
+      local tmacrap,tmcname=caches.setluanames(writable,name)
+      if isfile(tmcname) then
+        loader=loadfile(tmcname)
+      end
+      utilities.lua.compile(tmaname,tmcname)
+      if isfile(tmcname) then
+        loader=loadfile(tmcname)
+      end
+      if not loader then
+        loader=loadfile(tmaname)
+      end
+    end
+    if loader then
+      loader=loader()
+      collectgarbage("step")
+      return loader
+    end
   end
-  if loader then
-   loader=loader()
-   collectgarbage("step")
-   return loader
-  end
- end
- return false
+  return false
 end
 function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+  local tmaname,tmcname=caches.setluanames(filepath,filename)
+  return is_writable(tmaname)
 end
 local saveoptions={ compact=true }
 function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
-  file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
-  table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+  local tmaname,tmcname=caches.setluanames(filepath,filename)
+  data.cache_uuid=os.uuid()
+  if caches.direct then
+    file.savedata(tmaname,table.serialize(data,true,saveoptions))
+  else
+    table.tofile(tmaname,data,true,saveoptions)
+  end
+  utilities.lua.compile(tmaname,tmcname)
 end
 local content_state={}
 function caches.contentstate()
- return content_state or {}
+  return content_state or {}
 end
 function caches.loadcontent(cachename,dataname,filename)
- if not filename then
-  local name=caches.hashed(cachename)
-  local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
-  filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
-  local data=blob()
-  if data and data.content then
-   if data.type==dataname then
-    if data.version==resolvers.cacheversion then
-     content_state[#content_state+1]=data.uuid
-     if trace_locating then
-      report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
-     end
-     return data.content
-    else
-     report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
+  if not filename then
+    local name=caches.hashed(cachename)
+    local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+    filename=file.join(path,name)
+  end
+  local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+  if blob then
+    local data=blob()
+    if data and data.content then
+      if data.type==dataname then
+        if data.version==resolvers.cacheversion then
+          content_state[#content_state+1]=data.uuid
+          if trace_locating then
+            report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+          end
+          return data.content
+        else
+          report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
+        end
+      else
+        report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+      end
+    elseif trace_locating then
+      report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
     end
-   else
-    report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
-   end
   elseif trace_locating then
-   report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+    report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
   end
- elseif trace_locating then
-  report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
- end
 end
 function caches.collapsecontent(content)
- for k,v in next,content do
-  if type(v)=="table" and #v==1 then
-   content[k]=v[1]
+  for k,v in next,content do
+    if type(v)=="table" and #v==1 then
+      content[k]=v[1]
+    end
   end
- end
 end
 function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
-  local name=caches.hashed(cachename)
-  local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
-  filename=file.join(path,name) 
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
- if trace_locating then
-  report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
-  type=dataname,
-  root=cachename,
-  version=resolvers.cacheversion,
-  date=os.date("%Y-%m-%d"),
-  time=os.date("%H:%M:%S"),
-  content=content,
-  uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
+  if not filename then
+    local name=caches.hashed(cachename)
+    local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+    filename=file.join(path,name) 
+  end
+  local luaname=addsuffix(filename,luasuffixes.lua)
+  local lucname=addsuffix(filename,luasuffixes.luc)
   if trace_locating then
-   report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
+    report_resolvers("preparing %a for %a",dataname,cachename)
   end
-  if utilities.lua.compile(luaname,lucname) then
-   if trace_locating then
-    report_resolvers("%a compiled to %a",dataname,lucname)
-   end
-   return true
-  else
-   if trace_locating then
-    report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
-   end
-   os.remove(lucname)
+  local data={
+    type=dataname,
+    root=cachename,
+    version=resolvers.cacheversion,
+    date=os.date("%Y-%m-%d"),
+    time=os.date("%H:%M:%S"),
+    content=content,
+    uuid=os.uuid(),
+  }
+  local ok=io.savedata(luaname,table.serialize(data,true))
+  if ok then
+    if trace_locating then
+      report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
+    end
+    if utilities.lua.compile(luaname,lucname) then
+      if trace_locating then
+        report_resolvers("%a compiled to %a",dataname,lucname)
+      end
+      return true
+    else
+      if trace_locating then
+        report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+      end
+      os.remove(lucname)
+    end
+  elseif trace_locating then
+    report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
   end
- elseif trace_locating then
-  report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
- end
 end
 
 
@@ -21151,14 +17577,14 @@
 
 package.loaded["data-met"] = package.loaded["data-met"] or true
 
--- original size: 5310, stripped down to: 3784
+-- original size: 5310, stripped down to: 3980
 
 if not modules then modules={} end modules ['data-met']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.100,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local find,format=string.find,string.format
 local sequenced=table.sequenced
@@ -21172,86 +17598,86 @@
 local resolvers=resolvers
 local registered={}
 local function splitmethod(filename) 
- if not filename then
-  return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
-  return filename 
- end
- filename=file.collapsepath(filename,".") 
- if not find(filename,"://",1,true) then
-  return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
-  return { scheme="file",path=filename,original=filename,filename=filename }
- else
-  return specification
- end
+  if not filename then
+    return { scheme="unknown",original=filename }
+  end
+  if type(filename)=="table" then
+    return filename 
+  end
+  filename=file.collapsepath(filename,".") 
+  if not find(filename,"://",1,true) then
+    return { scheme="file",path=filename,original=filename,filename=filename }
+  end
+  local specification=url.hashed(filename)
+  if not specification.scheme or specification.scheme=="" then
+    return { scheme="file",path=filename,original=filename,filename=filename }
+  else
+    return specification
+  end
 end
 resolvers.splitmethod=splitmethod
 local function methodhandler(what,first,...) 
- local method=registered[what]
- if method then
-  local how,namespace=method.how,method.namespace
-  if how=="uri" or how=="url" then
-   local specification=splitmethod(first)
-   local scheme=specification.scheme
-   local resolver=namespace and namespace[scheme]
-   if resolver then
-    if trace_methods then
-     report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+  local method=registered[what]
+  if method then
+    local how,namespace=method.how,method.namespace
+    if how=="uri" or how=="url" then
+      local specification=splitmethod(first)
+      local scheme=specification.scheme
+      local resolver=namespace and namespace[scheme]
+      if resolver then
+        if trace_methods then
+          report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+        end
+        return resolver(specification,...)
+      else
+        resolver=namespace.default or namespace.file
+        if resolver then
+          if trace_methods then
+            report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+          end
+          return resolver(specification,...)
+        elseif trace_methods then
+          report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
+        end
+      end
+    elseif how=="tag" then
+      local resolver=namespace and namespace[first]
+      if resolver then
+        if trace_methods then
+          report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+        end
+        return resolver(...)
+      else
+        resolver=namespace.default or namespace.file
+        if resolver then
+          if trace_methods then
+            report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+          end
+          return resolver(...)
+        elseif trace_methods then
+          report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+        end
+      end
     end
-    return resolver(specification,...)
-   else
-    resolver=namespace.default or namespace.file
-    if resolver then
-     if trace_methods then
-      report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
-     end
-     return resolver(specification,...)
-    elseif trace_methods then
-     report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
-    end
-   end
-  elseif how=="tag" then
-   local resolver=namespace and namespace[first]
-   if resolver then
-    if trace_methods then
-     report_methods("resolving, method %a, how %a, tag %a",what,how,first)
-    end
-    return resolver(...)
-   else
-    resolver=namespace.default or namespace.file
-    if resolver then
-     if trace_methods then
-      report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
-     end
-     return resolver(...)
-    elseif trace_methods then
-     report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
-    end
-   end
+  else
+    report_methods("resolving, invalid method %a")
   end
- else
-  report_methods("resolving, invalid method %a")
- end
 end
 resolvers.methodhandler=methodhandler
 function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
-  if scheme=="file" then
-   return methodhandler(name,filename,...)
-  else
-   return methodhandler(name,addurlscheme(filename,scheme),...)
+  registered[name]={ how=how or "tag",namespace=namespace }
+  namespace["byscheme"]=function(scheme,filename,...)
+    if scheme=="file" then
+      return methodhandler(name,filename,...)
+    else
+      return methodhandler(name,addurlscheme(filename,scheme),...)
+    end
   end
- end
 end
-local concatinators=allocate { notfound=file.join    }  
-local locators=allocate { notfound=function() end  }  
-local hashers=allocate { notfound=function() end  }  
-local generators=allocate { notfound=function() end  }  
+local concatinators=allocate { notfound=file.join    } 
+local locators=allocate { notfound=function() end } 
+local hashers=allocate { notfound=function() end } 
+local generators=allocate { notfound=function() end } 
 resolvers.concatinators=concatinators
 resolvers.locators=locators
 resolvers.hashers=hashers
@@ -21269,17 +17695,17 @@
 
 package.loaded["data-res"] = package.loaded["data-res"] or true
 
--- original size: 68195, stripped down to: 43680
+-- original size: 68263, stripped down to: 47789
 
 if not modules then modules={} end modules ['data-res']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files",
 }
 local gsub,find,lower,upper,match,gmatch=string.gsub,string.find,string.lower,string.upper,string.match,string.gmatch
-local concat,insert,remove=table.concat,table.insert,table.remove
+local concat,insert,remove,sortedkeys,sortedhash=table.concat,table.insert,table.remove,table.sortedkeys,table.sortedhash
 local next,type,rawget=next,type,rawget
 local os=os
 local P,S,R,C,Cc,Cs,Ct,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Carg
@@ -21301,11 +17727,11 @@
 local isdir=lfs.isdir
 local setmetatableindex=table.setmetatableindex
 local luasuffixes=utilities.lua.suffixes
-local trace_locating=false  trackers  .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false  trackers  .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false  trackers  .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false  trackers  .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true   directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true  directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
 local report_resolving=logs.reporter("resolvers","resolving")
 local resolvers=resolvers
 local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -21326,15 +17752,15 @@
 resolvers.luacnffallback="contextcnf.lua"
 resolvers.luacnfstate="unknown"
 if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf 
+  resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf 
 else
- resolvers.luacnfspec=concat ({
-  "home:texmf/web2c",
-  "selfautoparent:/texmf-local/web2c",
-  "selfautoparent:/texmf-context/web2c",
-  "selfautoparent:/texmf-dist/web2c",
-  "selfautoparent:/texmf/web2c",
- },";")
+  resolvers.luacnfspec=concat ({
+    "home:texmf/web2c",
+    "selfautoparent:/texmf-local/web2c",
+    "selfautoparent:/texmf-context/web2c",
+    "selfautoparent:/texmf-dist/web2c",
+    "selfautoparent:/texmf/web2c",
+  },";")
 end
 local unset_variable="unset"
 local formats=resolvers.formats
@@ -21345,24 +17771,24 @@
 resolvers.defaultsuffixes={ "tex" } 
 local instance=nil
 function resolvers.setenv(key,value,raw)
- if instance then
-  instance.environment[key]=value
-  ossetenv(key,raw and value or resolveprefix(value))
- end
+  if instance then
+    instance.environment[key]=value
+    ossetenv(key,raw and value or resolveprefix(value))
+  end
 end
 local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
-  return value
- else
-  local e=osgetenv(key)
-  return e~=nil and e~="" and checkedvariable(e) or ""
- end
+  local value=rawget(instance.environment,key)
+  if value and value~="" then
+    return value
+  else
+    local e=osgetenv(key)
+    return e~=nil and e~="" and checkedvariable(e) or ""
+  end
 end
 resolvers.getenv=getenv
 resolvers.env=getenv
 local function resolvevariable(k)
- return instance.expansions[k]
+  return instance.expansions[k]
 end
 local dollarstripper=lpeg.stripper("$")
 local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -21376,1506 +17802,1506 @@
 local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
 local variableresolver=Cs((variable+P(1))^0)
 local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+  return lpegmatch(variableexpander,var) or var
 end
 function resolvers.reset()
- if trace_locating then
-  report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
-  environment=environment,
-  variables=variables,
-  expansions=expansions,
-  order=order,
-  files={},
-  setups={},
-  found={},
-  foundintrees={},
-  hashes={},
-  hashed={},
-  pathlists=false,
-  specification={},
-  lists={},
-  data={},
-  fakepaths={},
-  remember=true,
-  diskcache=true,
-  renewcache=false,
-  renewtree=false,
-  loaderror=false,
-  savelists=true,
-  pattern=nil,
-  force_suffixes=true,
-  pathstack={},
- }
- setmetatableindex(variables,function(t,k)
-  local v
-  for i=1,#order do
-   v=order[i][k]
-   if v~=nil then
+  if trace_locating then
+    report_resolving("creating instance")
+  end
+  local environment={}
+  local variables={}
+  local expansions={}
+  local order={}
+  instance={
+    environment=environment,
+    variables=variables,
+    expansions=expansions,
+    order=order,
+    files={},
+    setups={},
+    found={},
+    foundintrees={},
+    hashes={},
+    hashed={},
+    pathlists=false,
+    specification={},
+    lists={},
+    data={},
+    fakepaths={},
+    remember=true,
+    diskcache=true,
+    renewcache=false,
+    renewtree=false,
+    loaderror=false,
+    savelists=true,
+    pattern=nil,
+    force_suffixes=true,
+    pathstack={},
+  }
+  setmetatableindex(variables,function(t,k)
+    local v
+    for i=1,#order do
+      v=order[i][k]
+      if v~=nil then
+        t[k]=v
+        return v
+      end
+    end
+    if v==nil then
+      v=""
+    end
     t[k]=v
     return v
-   end
-  end
-  if v==nil then
-   v=""
-  end
-  t[k]=v
-  return v
- end)
- setmetatableindex(environment,function(t,k)
-  local v=osgetenv(k)
-  if v==nil then
-   v=variables[k]
-  end
-  if v~=nil then
-   v=checkedvariable(v) or ""
-  end
-  v=resolvers.repath(v) 
-  t[k]=v
-  return v
- end)
- setmetatableindex(expansions,function(t,k)
-  local v=environment[k]
-  if type(v)=="string" then
-   v=lpegmatch(variableresolver,v)
-   v=lpegmatch(variablecleaner,v)
-  end
-  t[k]=v
-  return v
- end)
+  end)
+  setmetatableindex(environment,function(t,k)
+    local v=osgetenv(k)
+    if v==nil then
+      v=variables[k]
+    end
+    if v~=nil then
+      v=checkedvariable(v) or ""
+    end
+    v=resolvers.repath(v) 
+    t[k]=v
+    return v
+  end)
+  setmetatableindex(expansions,function(t,k)
+    local v=environment[k]
+    if type(v)=="string" then
+      v=lpegmatch(variableresolver,v)
+      v=lpegmatch(variablecleaner,v)
+    end
+    t[k]=v
+    return v
+  end)
 end
 function resolvers.initialized()
- return instance~=nil
+  return instance~=nil
 end
 local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+  instance.lists={}
+  instance.pathlists=false
+  instance.found={}
 end
 local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+  instance.lists={}
+  instance.pathlists=false
 end
 local slash=P("/")
 local pathexpressionpattern=Cs (
- Cc("^")*(
-  Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+  Cc("^")*(
+    Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
 +slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$") 
+  )^1*Cc("$") 
 )
 local cache={}
 local function makepathexpression(str)
- if str=="." then
-  return "^%./$"
- else
-  local c=cache[str]
-  if not c then
-   c=lpegmatch(pathexpressionpattern,str)
-   cache[str]=c
+  if str=="." then
+    return "^%./$"
+  else
+    local c=cache[str]
+    if not c then
+      c=lpegmatch(pathexpressionpattern,str)
+      cache[str]=c
+    end
+    return c
   end
-  return c
- end
 end
 local function reportcriticalvariables(cnfspec)
- if trace_locating then
-  for i=1,#resolvers.criticalvars do
-   local k=resolvers.criticalvars[i]
-   local v=resolvers.getenv(k) or "unknown" 
-   report_resolving("variable %a set to %a",k,v)
+  if trace_locating then
+    for i=1,#resolvers.criticalvars do
+      local k=resolvers.criticalvars[i]
+      local v=resolvers.getenv(k) or "unknown" 
+      report_resolving("variable %a set to %a",k,v)
+    end
+    report_resolving()
+    if cnfspec then
+      report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
+    end
+    report_resolving()
   end
-  report_resolving()
-  if cnfspec then
-   report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
-  end
-  report_resolving()
- end
- reportcriticalvariables=function() end
+  reportcriticalvariables=function() end
 end
 local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
-  local cnfspec=getenv("TEXMFCNF")
-  if cnfspec=="" then
-   cnfspec=resolvers.luacnfspec
-   resolvers.luacnfstate="default"
-  else
-   resolvers.luacnfstate="environment"
-  end
-  reportcriticalvariables(cnfspec)
-  local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
-  local function locatecnf(luacnfname,kind)
-   for i=1,#cnfpaths do
-    local filepath=cnfpaths[i]
-    local filename=collapsepath(filejoin(filepath,luacnfname))
-    local realname=resolveprefix(filename)
+  local specification=instance.specification
+  if #specification==0 then
+    local cnfspec=getenv("TEXMFCNF")
+    if cnfspec=="" then
+      cnfspec=resolvers.luacnfspec
+      resolvers.luacnfstate="default"
+    else
+      resolvers.luacnfstate="environment"
+    end
+    reportcriticalvariables(cnfspec)
+    local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+    local function locatecnf(luacnfname,kind)
+      for i=1,#cnfpaths do
+        local filepath=cnfpaths[i]
+        local filename=collapsepath(filejoin(filepath,luacnfname))
+        local realname=resolveprefix(filename)
+        if trace_locating then
+          local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+          local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+          report_resolving("looking for %s %a on %s path %a from specification %a",
+            kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+        end
+        if isfile(realname) then
+          specification[#specification+1]=filename 
+          if trace_locating then
+            report_resolving("found %s configuration file %a",kind,realname)
+          end
+        end
+      end
+    end
+    locatecnf(resolvers.luacnfname,"regular")
+    if #specification==0 then
+      locatecnf(resolvers.luacnffallback,"fallback")
+    end
     if trace_locating then
-     local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
-     local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
-     report_resolving("looking for %s %a on %s path %a from specification %a",
-      kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+      report_resolving()
     end
-    if isfile(realname) then
-     specification[#specification+1]=filename 
-     if trace_locating then
-      report_resolving("found %s configuration file %a",kind,realname)
-     end
-    end
-   end
+  elseif trace_locating then
+    report_resolving("configuration files already identified")
   end
-  locatecnf(resolvers.luacnfname,"regular")
-  if #specification==0 then
-   locatecnf(resolvers.luacnffallback,"fallback")
-  end
-  if trace_locating then
-   report_resolving()
-  end
- elseif trace_locating then
-  report_resolving("configuration files already identified")
- end
 end
 local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
-  local luacnfname=resolvers.luacnfname
-  for i=1,#specification do
-   local filename=specification[i]
-   local pathname=filedirname(filename)
-   local filename=filejoin(pathname,luacnfname)
-   local realname=resolveprefix(filename) 
-   local blob=loadfile(realname)
-   if blob then
-    local setups=instance.setups
-    local data=blob()
-    local parent=data and data.parent
-    if parent then
-     local filename=filejoin(pathname,parent)
-     local realname=resolveprefix(filename) 
-     local blob=loadfile(realname)
-     if blob then
-      local parentdata=blob()
-      if parentdata then
-       report_resolving("loading configuration file %a",filename)
-       data=table.merged(parentdata,data)
+  local specification=instance.specification
+  if #specification>0 then
+    local luacnfname=resolvers.luacnfname
+    for i=1,#specification do
+      local filename=specification[i]
+      local pathname=filedirname(filename)
+      local filename=filejoin(pathname,luacnfname)
+      local realname=resolveprefix(filename) 
+      local blob=loadfile(realname)
+      if blob then
+        local setups=instance.setups
+        local data=blob()
+        local parent=data and data.parent
+        if parent then
+          local filename=filejoin(pathname,parent)
+          local realname=resolveprefix(filename) 
+          local blob=loadfile(realname)
+          if blob then
+            local parentdata=blob()
+            if parentdata then
+              report_resolving("loading configuration file %a",filename)
+              data=table.merged(parentdata,data)
+            end
+          end
+        end
+        data=data and data.content
+        if data then
+          if trace_locating then
+            report_resolving("loading configuration file %a",filename)
+            report_resolving()
+          end
+          local variables=data.variables or {}
+          local warning=false
+          for k,v in next,data do
+            local variant=type(v)
+            if variant=="table" then
+              initializesetter(filename,k,v)
+            elseif variables[k]==nil then
+              if trace_locating and not warning then
+                report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+                  k,resolveprefix(filename))
+                warning=true
+              end
+              variables[k]=v
+            end
+          end
+          setups[pathname]=variables
+          if resolvers.luacnfstate=="default" then
+            local cnfspec=variables["TEXMFCNF"]
+            if cnfspec then
+              if trace_locating then
+                report_resolving("reloading configuration due to TEXMF redefinition")
+              end
+              resolvers.setenv("TEXMFCNF",cnfspec)
+              instance.specification={}
+              identify_configuration_files()
+              load_configuration_files()
+              resolvers.luacnfstate="configuration"
+              break
+            end
+          end
+        else
+          if trace_locating then
+            report_resolving("skipping configuration file %a (no content)",filename)
+          end
+          setups[pathname]={}
+          instance.loaderror=true
+        end
+      elseif trace_locating then
+        report_resolving("skipping configuration file %a (no valid format)",filename)
       end
-     end
-    end
-    data=data and data.content
-    if data then
-     if trace_locating then
-      report_resolving("loading configuration file %a",filename)
-      report_resolving()
-     end
-     local variables=data.variables or {}
-     local warning=false
-     for k,v in next,data do
-      local variant=type(v)
-      if variant=="table" then
-       initializesetter(filename,k,v)
-      elseif variables[k]==nil then
-       if trace_locating and not warning then
-        report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
-         k,resolveprefix(filename))
-        warning=true
-       end
-       variables[k]=v
+      instance.order[#instance.order+1]=instance.setups[pathname]
+      if instance.loaderror then
+        break
       end
-     end
-     setups[pathname]=variables
-     if resolvers.luacnfstate=="default" then
-      local cnfspec=variables["TEXMFCNF"]
-      if cnfspec then
-       if trace_locating then
-        report_resolving("reloading configuration due to TEXMF redefinition")
-       end
-       resolvers.setenv("TEXMFCNF",cnfspec)
-       instance.specification={}
-       identify_configuration_files()
-       load_configuration_files()
-       resolvers.luacnfstate="configuration"
-       break
-      end
-     end
-    else
-     if trace_locating then
-      report_resolving("skipping configuration file %a (no content)",filename)
-     end
-     setups[pathname]={}
-     instance.loaderror=true
     end
-   elseif trace_locating then
-    report_resolving("skipping configuration file %a (no valid format)",filename)
-   end
-   instance.order[#instance.order+1]=instance.setups[pathname]
-   if instance.loaderror then
-    break
-   end
+  elseif trace_locating then
+    report_resolving("warning: no lua configuration files found")
   end
- elseif trace_locating then
-  report_resolving("warning: no lua configuration files found")
- end
 end
 function resolvers.configurationfiles()
- return instance.specification or {}
+  return instance.specification or {}
 end
 local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
-  local hashes=instance.hashes
-  for k=1,#hashes do
-   local hash=hashes[k]
-   resolvers.hashers.byscheme(hash.type,hash.name)
-   if instance.loaderror then break end
+  instance.loaderror=false
+  instance.files={}
+  if not instance.renewcache then
+    local hashes=instance.hashes
+    for k=1,#hashes do
+      local hash=hashes[k]
+      resolvers.hashers.byscheme(hash.type,hash.name)
+      if instance.loaderror then break end
+    end
   end
- end
 end
 local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
-  for i=1,#texmfpaths do
-   local path=collapsepath(texmfpaths[i])
-   path=gsub(path,"/+$","") 
-   local stripped=lpegmatch(inhibitstripper,path) 
-   if stripped~="" then
-    local runtime=stripped==path
-    path=cleanpath(path)
-    local spec=resolvers.splitmethod(stripped)
-    if runtime and (spec.noscheme or spec.scheme=="file") then
-     stripped="tree:///"..stripped
-    elseif spec.scheme=="cache" or spec.scheme=="file" then
-     stripped=spec.path
+  local texmfpaths=resolvers.expandedpathlist("TEXMF")
+  if #texmfpaths>0 then
+    for i=1,#texmfpaths do
+      local path=collapsepath(texmfpaths[i])
+      path=gsub(path,"/+$","") 
+      local stripped=lpegmatch(inhibitstripper,path) 
+      if stripped~="" then
+        local runtime=stripped==path
+        path=cleanpath(path)
+        local spec=resolvers.splitmethod(stripped)
+        if runtime and (spec.noscheme or spec.scheme=="file") then
+          stripped="tree:///"..stripped
+        elseif spec.scheme=="cache" or spec.scheme=="file" then
+          stripped=spec.path
+        end
+        if trace_locating then
+          if runtime then
+            report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+          else
+            report_resolving("locating list of %a (cached)",path)
+          end
+        end
+        methodhandler('locators',stripped)
+      end
     end
     if trace_locating then
-     if runtime then
-      report_resolving("locating list of %a (runtime) (%s)",path,stripped)
-     else
-      report_resolving("locating list of %a (cached)",path)
-     end
+      report_resolving()
     end
-    methodhandler('locators',stripped)
-   end
+  elseif trace_locating then
+    report_resolving("no texmf paths are defined (using TEXMF)")
   end
+end
+local function generate_file_databases()
+  local hashes=instance.hashes
+  for k=1,#hashes do
+    local hash=hashes[k]
+    methodhandler('generators',hash.name)
+  end
   if trace_locating then
-   report_resolving()
+    report_resolving()
   end
- elseif trace_locating then
-  report_resolving("no texmf paths are defined (using TEXMF)")
- end
 end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
-  local hash=hashes[k]
-  methodhandler('generators',hash.name)
- end
- if trace_locating then
-  report_resolving()
- end
-end
 local function save_file_databases() 
- for i=1,#instance.hashes do
-  local hash=instance.hashes[i]
-  local cachename=hash.name
-  if hash.cache then
-   local content=instance.files[cachename]
-   caches.collapsecontent(content)
-   if trace_locating then
-    report_resolving("saving tree %a",cachename)
-   end
-   caches.savecontent(cachename,"files",content)
-  elseif trace_locating then
-   report_resolving("not saving runtime tree %a",cachename)
+  for i=1,#instance.hashes do
+    local hash=instance.hashes[i]
+    local cachename=hash.name
+    if hash.cache then
+      local content=instance.files[cachename]
+      caches.collapsecontent(content)
+      if trace_locating then
+        report_resolving("saving tree %a",cachename)
+      end
+      caches.savecontent(cachename,"files",content)
+    elseif trace_locating then
+      report_resolving("not saving runtime tree %a",cachename)
+    end
   end
- end
 end
 function resolvers.renew(hashname)
- if hashname and hashname~="" then
-  local expanded=resolvers.expansion(hashname) or ""
-  if expanded~="" then
-   if trace_locating then
-    report_resolving("identifying tree %a from %a",expanded,hashname)
-   end
-   hashname=expanded
-  else
-   if trace_locating then
-    report_resolving("identifying tree %a",hashname)
-   end
+  if hashname and hashname~="" then
+    local expanded=resolvers.expansion(hashname) or ""
+    if expanded~="" then
+      if trace_locating then
+        report_resolving("identifying tree %a from %a",expanded,hashname)
+      end
+      hashname=expanded
+    else
+      if trace_locating then
+        report_resolving("identifying tree %a",hashname)
+      end
+    end
+    local realpath=resolveprefix(hashname)
+    if isdir(realpath) then
+      if trace_locating then
+        report_resolving("using path %a",realpath)
+      end
+      methodhandler('generators',hashname)
+      local content=instance.files[hashname]
+      caches.collapsecontent(content)
+      if trace_locating then
+        report_resolving("saving tree %a",hashname)
+      end
+      caches.savecontent(hashname,"files",content)
+    else
+      report_resolving("invalid path %a",realpath)
+    end
   end
-  local realpath=resolveprefix(hashname)
-  if isdir(realpath) then
-   if trace_locating then
-    report_resolving("using path %a",realpath)
-   end
-   methodhandler('generators',hashname)
-   local content=instance.files[hashname]
-   caches.collapsecontent(content)
-   if trace_locating then
-    report_resolving("saving tree %a",hashname)
-   end
-   caches.savecontent(hashname,"files",content)
-  else
-   report_resolving("invalid path %a",realpath)
-  end
- end
 end
 local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
-  load_file_databases()
-  if instance.loaderror then
-   generate_file_databases()
-   save_file_databases()
+  locate_file_databases()
+  if instance.diskcache and not instance.renewcache then
+    load_file_databases()
+    if instance.loaderror then
+      generate_file_databases()
+      save_file_databases()
+    end
+  else
+    generate_file_databases()
+    if instance.renewcache then
+      save_file_databases()
+    end
   end
- else
-  generate_file_databases()
-  if instance.renewcache then
-   save_file_databases()
-  end
- end
 end
 function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
-  if trace_locating then
-   report_resolving("hash %a appended",name)
+  if not instance.hashed[name] then
+    if trace_locating then
+      report_resolving("hash %a appended",name)
+    end
+    insert(instance.hashes,{ type=type,name=name,cache=cache } )
+    instance.hashed[name]=cache
   end
-  insert(instance.hashes,{ type=type,name=name,cache=cache } )
-  instance.hashed[name]=cache
- end
 end
 function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
-  if trace_locating then
-   report_resolving("hash %a prepended",name)
+  if not instance.hashed[name] then
+    if trace_locating then
+      report_resolving("hash %a prepended",name)
+    end
+    insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+    instance.hashed[name]=cache
   end
-  insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
-  instance.hashed[name]=cache
- end
 end
 function resolvers.extendtexmfvariable(specification) 
- local t=resolvers.splitpath(getenv("TEXMF")) 
- insert(t,1,specification)
- local newspec=concat(t,",") 
- if instance.environment["TEXMF"] then
-  instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
-  instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+  local t=resolvers.splitpath(getenv("TEXMF")) 
+  insert(t,1,specification)
+  local newspec=concat(t,",") 
+  if instance.environment["TEXMF"] then
+    instance.environment["TEXMF"]=newspec
+  elseif instance.variables["TEXMF"] then
+    instance.variables["TEXMF"]=newspec
+  else
+  end
+  reset_hashes()
 end
 function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
-  local t,tn,h,p={},0,{},splitconfigurationpath(v)
-  for kk=1,#p do
-   local vv=p[kk]
-   if vv~="" and not h[vv] then
-    tn=tn+1
-    t[tn]=vv
-    h[vv]=true
-   end
+  local ie=instance.expansions
+  for k,v in next,ie do
+    local t,tn,h,p={},0,{},splitconfigurationpath(v)
+    for kk=1,#p do
+      local vv=p[kk]
+      if vv~="" and not h[vv] then
+        tn=tn+1
+        t[tn]=vv
+        h[vv]=true
+      end
+    end
+    if #t>1 then
+      ie[k]=t
+    else
+      ie[k]=t[1]
+    end
   end
-  if #t>1 then
-   ie[k]=t
-  else
-   ie[k]=t[1]
-  end
- end
 end
 function resolvers.datastate()
- return caches.contentstate()
+  return caches.contentstate()
 end
 function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+  local name=name and lpegmatch(dollarstripper,name)
+  local result=name and instance.variables[name]
+  return result~=nil and result or ""
 end
 function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+  local name=name and lpegmatch(dollarstripper,name)
+  local result=name and instance.expansions[name]
+  return result~=nil and result or ""
 end
 function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+  local pth=resolvers.variable(str)
+  local lst=resolvers.splitpath(pth)
+  return expandedpathfromlist(lst)
 end
 function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+  return joinpath(resolvers.unexpandedpathlist(str))
 end
 function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
-  lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
-  lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
-  report_resolving("pushing path %a",lastpath)
- end
+  local pathstack=instance.pathstack
+  local lastpath=pathstack[#pathstack]
+  local pluspath=filedirname(name)
+  if lastpath then
+    lastpath=collapsepath(filejoin(lastpath,pluspath))
+  else
+    lastpath=collapsepath(pluspath)
+  end
+  insert(pathstack,lastpath)
+  if trace_paths then
+    report_resolving("pushing path %a",lastpath)
+  end
 end
 function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
-  report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+  local pathstack=instance.pathstack
+  if trace_paths and #pathstack>0 then
+    report_resolving("popping path %a",pathstack[#pathstack])
+  end
+  remove(pathstack)
 end
 function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+  local pathstack=instance.pathstack
+  local currentpath=pathstack[#pathstack]
+  return currentpath~="" and currentpath or nil
 end
 local done={}
 function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
-  done={}
-  instance.extra_paths={}
- elseif #ep>0 then
-  done={}
-  reset_caches()
- end
+  local ep=instance.extra_paths
+  if not ep then
+    done={}
+    instance.extra_paths={}
+  elseif #ep>0 then
+    done={}
+    reset_caches()
+  end
 end
 function resolvers.getextrapaths()
- return instance.extra_paths or {}
+  return instance.extra_paths or {}
 end
 function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
-  if not paths or path=="" then
-   return 
-  elseif done[paths] then
-   return 
+  if not subpaths or subpaths=="" then
+    if not paths or path=="" then
+      return 
+    elseif done[paths] then
+      return 
+    end
   end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
-  if nofsubpaths>0 then
-   for i=1,nofpaths do
-    local p=paths[i]
-    for j=1,nofsubpaths do
-     local s=subpaths[j]
-     local ps=p.."/"..s
-     if not done[ps] then
-      newn=newn+1
-      ep[newn]=cleanpath(ps)
-      done[ps]=true
-     end
+  local paths=settings_to_array(paths)
+  local subpaths=settings_to_array(subpaths)
+  local ep=instance.extra_paths or {}
+  local oldn=#ep
+  local newn=oldn
+  local nofpaths=#paths
+  local nofsubpaths=#subpaths
+  if nofpaths>0 then
+    if nofsubpaths>0 then
+      for i=1,nofpaths do
+        local p=paths[i]
+        for j=1,nofsubpaths do
+          local s=subpaths[j]
+          local ps=p.."/"..s
+          if not done[ps] then
+            newn=newn+1
+            ep[newn]=cleanpath(ps)
+            done[ps]=true
+          end
+        end
+      end
+    else
+      for i=1,nofpaths do
+        local p=paths[i]
+        if not done[p] then
+          newn=newn+1
+          ep[newn]=cleanpath(p)
+          done[p]=true
+        end
+      end
     end
-   end
-  else
-   for i=1,nofpaths do
-    local p=paths[i]
-    if not done[p] then
-     newn=newn+1
-     ep[newn]=cleanpath(p)
-     done[p]=true
+  elseif nofsubpaths>0 then
+    for i=1,oldn do
+      for j=1,nofsubpaths do
+        local s=subpaths[j]
+        local ps=ep[i].."/"..s
+        if not done[ps] then
+          newn=newn+1
+          ep[newn]=cleanpath(ps)
+          done[ps]=true
+        end
+      end
     end
-   end
   end
- elseif nofsubpaths>0 then
-  for i=1,oldn do
-   for j=1,nofsubpaths do
-    local s=subpaths[j]
-    local ps=ep[i].."/"..s
-    if not done[ps] then
-     newn=newn+1
-     ep[newn]=cleanpath(ps)
-     done[ps]=true
-    end
-   end
+  if newn>0 then
+    instance.extra_paths=ep 
   end
- end
- if newn>0 then
-  instance.extra_paths=ep 
- end
- if newn~=oldn then
-  reset_caches()
- end
+  if newn~=oldn then
+    reset_caches()
+  end
 end
 function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
-  insert(instance.extra_stack,1,paths)
- else
-  instance.extra_stack={ paths }
- end
- reset_caches()
+  local paths=settings_to_array(path)
+  if instance.extra_stack then
+    insert(instance.extra_stack,1,paths)
+  else
+    instance.extra_stack={ paths }
+  end
+  reset_caches()
 end
 function resolvers.popextrapath()
- if instance.extra_stack then
-  reset_caches()
-  return remove(instance.extra_stack,1)
- end
+  if instance.extra_stack then
+    reset_caches()
+    return remove(instance.extra_stack,1)
+  end
 end
 local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
-  for k=1,#p do
-   local v=p[k]
-   if not done[v] then
-    done[v]=true
-    newn=newn+1
-    new[newn]=v
-   end
+  local done={}
+  local new={}
+  local newn=0
+  local function add(p)
+    for k=1,#p do
+      local v=p[k]
+      if not done[v] then
+        done[v]=true
+        newn=newn+1
+        new[newn]=v
+      end
+    end
   end
- end
- for k=1,#list do
-  local v=list[k]
-  if done[v] then
-  elseif find(v,"^[%.%/]$") then
-   done[v]=true
-   newn=newn+1
-   new[newn]=v
-  else
-   break
+  for k=1,#list do
+    local v=list[k]
+    if done[v] then
+    elseif find(v,"^[%.%/]$") then
+      done[v]=true
+      newn=newn+1
+      new[newn]=v
+    else
+      break
+    end
   end
- end
- if extra_too then
-  local es=instance.extra_stack
-  if es and #es>0 then
-   for k=1,#es do
-    add(es[k])
-   end
+  if extra_too then
+    local es=instance.extra_stack
+    if es and #es>0 then
+      for k=1,#es do
+        add(es[k])
+      end
+    end
+    local ep=instance.extra_paths
+    if ep and #ep>0 then
+      add(ep)
+    end
   end
-  local ep=instance.extra_paths
-  if ep and #ep>0 then
-   add(ep)
-  end
- end
- add(list)
- return new
+  add(list)
+  return new
 end
 function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
-  for i=1,#t do
-   t[i]=collapsepath(cleanpath(t[i]))
+  local t=resolvers.expandedpathlist(str)
+  if t then
+    for i=1,#t do
+      t[i]=collapsepath(cleanpath(t[i]))
+    end
   end
- end
- return t
+  return t
 end
 function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+  return joinpath(resolvers.expandedpathlist(str))
 end
 function resolvers.expandedpathlist(str,extra_too)
- if not str then
-  return {}
- elseif instance.savelists then 
-  str=lpegmatch(dollarstripper,str)
-  local lists=instance.lists
-  local lst=lists[str]
-  if not lst then
-   local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
-   lst=expandedpathfromlist(l)
-   lists[str]=lst
+  if not str then
+    return {}
+  elseif instance.savelists then 
+    str=lpegmatch(dollarstripper,str)
+    local lists=instance.lists
+    local lst=lists[str]
+    if not lst then
+      local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+      lst=expandedpathfromlist(l)
+      lists[str]=lst
+    end
+    return lst
+  else
+    local lst=resolvers.splitpath(resolvers.expansion(str))
+    return made_list(instance,expandedpathfromlist(lst),extra_too)
   end
-  return lst
- else
-  local lst=resolvers.splitpath(resolvers.expansion(str))
-  return made_list(instance,expandedpathfromlist(lst),extra_too)
- end
 end
 function resolvers.expandedpathlistfromvariable(str) 
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+  str=lpegmatch(dollarstripper,str)
+  local tmp=resolvers.variableofformatorsuffix(str)
+  return resolvers.expandedpathlist(tmp~="" and tmp or str)
 end
 function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+  return joinpath(resolvers.expandedpathlistfromvariable(str))
 end
 function resolvers.cleanedpathlist(v) 
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
-  t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+  local t=resolvers.expandedpathlist(v)
+  for i=1,#t do
+    t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+  end
+  return t
 end
 function resolvers.expandbraces(str) 
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+  local pth=expandedpathfromlist(resolvers.splitpath(str))
+  return joinpath(pth)
 end
 function resolvers.registerfilehash(name,content,someerror)
- if content then
-  instance.files[name]=content
- else
-  instance.files[name]={}
-  if somerror==true then 
-   instance.loaderror=someerror
+  if content then
+    instance.files[name]=content
+  else
+    instance.files[name]={}
+    if somerror==true then 
+      instance.loaderror=someerror
+    end
   end
- end
 end
 function resolvers.getfilehashes()
- return instance and instance.files or {}
+  return instance and instance.files or {}
 end
 function resolvers.gethashes()
- return instance and instance.hashes or {}
+  return instance and instance.hashes or {}
 end
 function resolvers.renewcache()
- if instance then
-  instance.renewcache=true
- end
+  if instance then
+    instance.renewcache=true
+  end
 end
 local function isreadable(name)
- local readable=isfile(name) 
- if trace_detail then
-  if readable then
-   report_resolving("file %a is readable",name)
-  else
-   report_resolving("file %a is not readable",name)
+  local readable=isfile(name) 
+  if trace_detail then
+    if readable then
+      report_resolving("file %a is readable",name)
+    else
+      report_resolving("file %a is not readable",name)
+    end
   end
- end
- return readable
+  return readable
 end
 local function collect_files(names) 
- local filelist={}   
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
-  if not pathname or find(path,pathname) then
-   local variant=hash.type
-   local search=filejoin(root,path,name) 
-   local result=methodhandler('concatinators',variant,root,path,name)
-   if trace_detail then
-    report_resolving("match: variant %a, search %a, result %a",variant,search,result)
-   end
-   noffiles=noffiles+1
-   filelist[noffiles]={ variant,search,result }
+  local filelist={}      
+  local noffiles=0
+  local function check(hash,root,pathname,path,basename,name)
+    if not pathname or find(path,pathname) then
+      local variant=hash.type
+      local search=filejoin(root,path,name) 
+      local result=methodhandler('concatinators',variant,root,path,name)
+      if trace_detail then
+        report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+      end
+      noffiles=noffiles+1
+      filelist[noffiles]={ variant,search,result }
+    end
   end
- end
- for k=1,#names do
-  local filename=names[k]
-  if trace_detail then
-   report_resolving("checking name %a",filename)
-  end
-  local basename=filebasename(filename)
-  local pathname=filedirname(filename)
-  if pathname=="" or find(pathname,"^%.") then
-   pathname=false
-  else
-   pathname=gsub(pathname,"%*",".*")
-   pathname="/"..pathname.."$"
-  end
-  local hashes=instance.hashes
-  for h=1,#hashes do
-   local hash=hashes[h]
-   local hashname=hash.name
-   local content=hashname and instance.files[hashname]
-   if content then
+  for k=1,#names do
+    local filename=names[k]
     if trace_detail then
-     report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
+      report_resolving("checking name %a",filename)
     end
-    local path,name=lookup(content,basename)
-    if path then
-     local metadata=content.metadata
-     local realroot=metadata and metadata.path or hashname
-     if type(path)=="string" then
-      check(hash,realroot,pathname,path,basename,name)
-     else
-      for i=1,#path do
-       check(hash,realroot,pathname,path[i],basename,name)
+    local basename=filebasename(filename)
+    local pathname=filedirname(filename)
+    if pathname=="" or find(pathname,"^%.") then
+      pathname=false
+    else
+      pathname=gsub(pathname,"%*",".*")
+      pathname="/"..pathname.."$"
+    end
+    local hashes=instance.hashes
+    for h=1,#hashes do
+      local hash=hashes[h]
+      local hashname=hash.name
+      local content=hashname and instance.files[hashname]
+      if content then
+        if trace_detail then
+          report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
+        end
+        local path,name=lookup(content,basename)
+        if path then
+          local metadata=content.metadata
+          local realroot=metadata and metadata.path or hashname
+          if type(path)=="string" then
+            check(hash,realroot,pathname,path,basename,name)
+          else
+            for i=1,#path do
+              check(hash,realroot,pathname,path[i],basename,name)
+            end
+          end
+        end
+      elseif trace_locating then
+        report_resolving("no match in %a (%s)",hashname,basename)
       end
-     end
     end
-   elseif trace_locating then
-    report_resolving("no match in %a (%s)",hashname,basename)
-   end
   end
- end
- return noffiles>0 and filelist or nil
+  return noffiles>0 and filelist or nil
 end
 local fit={}
 function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
-  local collapsed=collapsepath(foundname,true)
-  local t={
-   filename=filename,
-   format=format~="" and format   or nil,
-   filetype=filetype~="" and filetype or nil,
-   usedmethod=usedmethod,
-   foundname=foundname,
-   fullname=collapsed,
-  }
-  fit[foundname]=t
-  foundintrees[#foundintrees+1]=t
- end
+  local foundintrees=instance.foundintrees
+  if usedmethod=="direct" and filename==foundname and fit[foundname] then
+  else
+    local collapsed=collapsepath(foundname,true)
+    local t={
+      filename=filename,
+      format=format~="" and format  or nil,
+      filetype=filetype~="" and filetype or nil,
+      usedmethod=usedmethod,
+      foundname=foundname,
+      fullname=collapsed,
+    }
+    fit[foundname]=t
+    foundintrees[#foundintrees+1]=t
+  end
 end
 function resolvers.foundintrees()
- return instance.foundintrees or {}
+  return instance.foundintrees or {}
 end
 function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+  local f=fit[fullname]
+  return f and f.usedmethod=="database"
 end
 local function can_be_dir(name) 
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
-  if isdir(name) then
-   fakepaths[name]=1 
-  else
-   fakepaths[name]=2 
+  local fakepaths=instance.fakepaths
+  if not fakepaths[name] then
+    if isdir(name) then
+      fakepaths[name]=1 
+    else
+      fakepaths[name]=2 
+    end
   end
- end
- return fakepaths[name]==1
+  return fakepaths[name]==1
 end
 local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
 local collect_instance_files
 local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
-  if filesuffix=="" or not suffixmap[filesuffix] then
-   local defaultsuffixes=resolvers.defaultsuffixes
-   local formatofsuffix=resolvers.formatofsuffix
-   for i=1,#defaultsuffixes do
-    local forcedname=filename..'.'..defaultsuffixes[i]
-    wantedfiles[#wantedfiles+1]=forcedname
-    filetype=formatofsuffix(forcedname)
-    if trace_locating then
-     report_resolving("forcing filetype %a",filetype)
+  local filetype=''
+  local filesuffix=suffixonly(filename)
+  local wantedfiles={}
+  wantedfiles[#wantedfiles+1]=filename
+  if askedformat=="" then
+    if filesuffix=="" or not suffixmap[filesuffix] then
+      local defaultsuffixes=resolvers.defaultsuffixes
+      local formatofsuffix=resolvers.formatofsuffix
+      for i=1,#defaultsuffixes do
+        local forcedname=filename..'.'..defaultsuffixes[i]
+        wantedfiles[#wantedfiles+1]=forcedname
+        filetype=formatofsuffix(forcedname)
+        if trace_locating then
+          report_resolving("forcing filetype %a",filetype)
+        end
+      end
+    else
+      filetype=resolvers.formatofsuffix(filename)
+      if trace_locating then
+        report_resolving("using suffix based filetype %a",filetype)
+      end
     end
-   end
   else
-   filetype=resolvers.formatofsuffix(filename)
-   if trace_locating then
-    report_resolving("using suffix based filetype %a",filetype)
-   end
-  end
- else
-  if filesuffix=="" or not suffixmap[filesuffix] then
-   local format_suffixes=suffixes[askedformat]
-   if format_suffixes then
-    for i=1,#format_suffixes do
-     wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
+    if filesuffix=="" or not suffixmap[filesuffix] then
+      local format_suffixes=suffixes[askedformat]
+      if format_suffixes then
+        for i=1,#format_suffixes do
+          wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
+        end
+      end
     end
-   end
+    filetype=askedformat
+    if trace_locating then
+      report_resolving("using given filetype %a",filetype)
+    end
   end
-  filetype=askedformat
-  if trace_locating then
-   report_resolving("using given filetype %a",filetype)
-  end
- end
- return filetype,wantedfiles
+  return filetype,wantedfiles
 end
 local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
-  if trace_detail then
-   report_resolving("file %a found directly",filename)
+  if not dangerous[askedformat] and isreadable(filename) then
+    if trace_detail then
+      report_resolving("file %a found directly",filename)
+    end
+    return "direct",{ filename }
   end
-  return "direct",{ filename }
- end
 end
 local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
-  if trace_locating then
-   report_resolving("checking wildcard %a",filename)
+  if find(filename,'*',1,true) then
+    if trace_locating then
+      report_resolving("checking wildcard %a",filename)
+    end
+    local result=resolvers.findwildcardfiles(filename)
+    if result then
+      return "wildcard",result
+    end
   end
-  local result=resolvers.findwildcardfiles(filename)
-  if result then
-   return "wildcard",result
-  end
- end
 end
 local function find_qualified(filename,allresults,askedformat,alsostripped) 
- if not is_qualified_path(filename) then
-  return
- end
- if trace_locating then
-  report_resolving("checking qualified name %a",filename)
- end
- if isreadable(filename) then
-  if trace_detail then
-   report_resolving("qualified file %a found",filename)
+  if not is_qualified_path(filename) then
+    return
   end
-  return "qualified",{ filename }
- end
- if trace_detail then
-  report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then 
-  local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
-  if format_suffixes then
-   for i=1,#format_suffixes do
-    local s=format_suffixes[i]
-    forcedname=filename.."."..s
-    if isreadable(forcedname) then
-     if trace_locating then
-      report_resolving("no suffix, forcing format filetype %a",s)
-     end
-     return "qualified",{ forcedname }
+  if trace_locating then
+    report_resolving("checking qualified name %a",filename)
+  end
+  if isreadable(filename) then
+    if trace_detail then
+      report_resolving("qualified file %a found",filename)
     end
-   end
+    return "qualified",{ filename }
   end
- end
- if alsostripped and suffix and suffix~="" then
-  local basename=filebasename(filename)
-  local pattern=lpegmatch(preparetreepattern,filename)
-  local savedformat=askedformat
-  local format=savedformat or ""
-  if format=="" then
-   askedformat=resolvers.formatofsuffix(suffix)
+  if trace_detail then
+    report_resolving("locating qualified file %a",filename)
   end
-  if not format then
-   askedformat="othertextfiles" 
+  local forcedname,suffix="",suffixonly(filename)
+  if suffix=="" then 
+    local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+    if format_suffixes then
+      for i=1,#format_suffixes do
+        local s=format_suffixes[i]
+        forcedname=filename.."."..s
+        if isreadable(forcedname) then
+          if trace_locating then
+            report_resolving("no suffix, forcing format filetype %a",s)
+          end
+          return "qualified",{ forcedname }
+        end
+      end
+    end
   end
-  if basename~=filename then
-   local resolved=collect_instance_files(basename,askedformat,allresults)
-   if #resolved==0 then
-    local lowered=lower(basename)
-    if filename~=lowered then
-     resolved=collect_instance_files(lowered,askedformat,allresults)
+  if alsostripped and suffix and suffix~="" then
+    local basename=filebasename(filename)
+    local pattern=lpegmatch(preparetreepattern,filename)
+    local savedformat=askedformat
+    local format=savedformat or ""
+    if format=="" then
+      askedformat=resolvers.formatofsuffix(suffix)
     end
-   end
-   resolvers.format=savedformat
-   if #resolved>0 then
-    local result={}
-    for r=1,#resolved do
-     local rr=resolved[r]
-     if find(rr,pattern) then
-      result[#result+1]=rr
-     end
+    if not format then
+      askedformat="othertextfiles" 
     end
-    if #result>0 then
-     return "qualified",result
+    if basename~=filename then
+      local resolved=collect_instance_files(basename,askedformat,allresults)
+      if #resolved==0 then
+        local lowered=lower(basename)
+        if filename~=lowered then
+          resolved=collect_instance_files(lowered,askedformat,allresults)
+        end
+      end
+      resolvers.format=savedformat
+      if #resolved>0 then
+        local result={}
+        for r=1,#resolved do
+          local rr=resolved[r]
+          if find(rr,pattern) then
+            result[#result+1]=rr
+          end
+        end
+        if #result>0 then
+          return "qualified",result
+        end
+      end
     end
-   end
   end
- end
 end
 local function check_subpath(fname)
- if isreadable(fname) then
-  if trace_detail then
-   report_resolving("found %a by deep scanning",fname)
+  if isreadable(fname) then
+    if trace_detail then
+      report_resolving("found %a by deep scanning",fname)
+    end
+    return fname
   end
-  return fname
- end
 end
 local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype]) 
- local entry={}
- if pathlist and #pathlist>0 then
-  for k=1,#pathlist do
-   local path=pathlist[k]
-   local prescanned=find(path,'^!!')
-   local resursive=find(path,'//$')
-   local pathname=lpegmatch(inhibitstripper,path)
-   local expression=makepathexpression(pathname)
-   local barename=gsub(pathname,"/+$","")
-   barename=resolveprefix(barename)
-   local scheme=url.hasscheme(barename)
-   local schemename=gsub(barename,"%.%*$",'')
-   entry[k]={
-    path=path,
-    pathname=pathname,
-    prescanned=prescanned,
-    recursive=recursive,
-    expression=expression,
-    barename=barename,
-    scheme=scheme,
-    schemename=schemename,
-   }
+  local typespec=resolvers.variableofformat(filetype)
+  local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype]) 
+  local entry={}
+  if pathlist and #pathlist>0 then
+    for k=1,#pathlist do
+      local path=pathlist[k]
+      local prescanned=find(path,'^!!')
+      local resursive=find(path,'//$')
+      local pathname=lpegmatch(inhibitstripper,path)
+      local expression=makepathexpression(pathname)
+      local barename=gsub(pathname,"/+$","")
+      barename=resolveprefix(barename)
+      local scheme=url.hasscheme(barename)
+      local schemename=gsub(barename,"%.%*$",'')
+      entry[k]={
+        path=path,
+        pathname=pathname,
+        prescanned=prescanned,
+        recursive=recursive,
+        expression=expression,
+        barename=barename,
+        scheme=scheme,
+        schemename=schemename,
+      }
+    end
+    entry.typespec=typespec
+    list[filetype]=entry
+  else
+    list[filetype]=false
   end
-  entry.typespec=typespec
-  list[filetype]=entry
- else
-  list[filetype]=false
- end
- return entry
+  return entry
 end
 local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
-  pathlists=setmetatableindex({},makepathlist)
-  instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
-  local method="intree"
-  local filelist=collect_files(wantedfiles) 
-  local dirlist={}
-  local result={}
-  if filelist then
-   for i=1,#filelist do
-    dirlist[i]=filedirname(filelist[i][3]).."/" 
-   end
+  local pathlists=instance.pathlists
+  if not pathlists then
+    pathlists=setmetatableindex({},makepathlist)
+    instance.pathlists=pathlists
   end
-  if trace_detail then
-   report_resolving("checking filename %a in tree",filename)
-  end
-  for k=1,#pathlist do
-   local entry=pathlist[k]
-   local path=entry.path
-   local pathname=entry.pathname
-   local done=false
-   if filelist then
-    local expression=entry.expression
+  local pathlist=pathlists[filetype]
+  if pathlist then
+    local method="intree"
+    local filelist=collect_files(wantedfiles) 
+    local dirlist={}
+    local result={}
+    if filelist then
+      for i=1,#filelist do
+        dirlist[i]=filedirname(filelist[i][3]).."/" 
+      end
+    end
     if trace_detail then
-     report_resolving("using pattern %a for path %a",expression,pathname)
+      report_resolving("checking filename %a in tree",filename)
     end
-    for k=1,#filelist do
-     local fl=filelist[k]
-     local f=fl[2]
-     local d=dirlist[k]
-     if find(d,expression) or find(resolveprefix(d),expression) then
-      result[#result+1]=resolveprefix(fl[3]) 
-      done=true
-      if allresults then
-       if trace_detail then
-        report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
-       end
-      else
-       if trace_detail then
-        report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
-       end
-       break
-      end
-     elseif trace_detail then
-      report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
-     end
-    end
-   end
-   if done then
-    method="database"
-   else
-    method="filesystem" 
-    local scheme=entry.scheme
-    if not scheme or scheme=="file" then
-     local pname=entry.schemename
-     if not find(pname,"*",1,true) then
-      if can_be_dir(pname) then
-       if not done and not entry.prescanned then
+    for k=1,#pathlist do
+      local entry=pathlist[k]
+      local path=entry.path
+      local pathname=entry.pathname
+      local done=false
+      if filelist then
+        local expression=entry.expression
         if trace_detail then
-         report_resolving("quick root scan for %a",pname)
+          report_resolving("using pattern %a for path %a",expression,pathname)
         end
-        for k=1,#wantedfiles do
-         local w=wantedfiles[k]
-         local fname=check_subpath(filejoin(pname,w))
-         if fname then
-          result[#result+1]=fname
-          done=true
-          if not allresults then
-           break
+        for k=1,#filelist do
+          local fl=filelist[k]
+          local f=fl[2]
+          local d=dirlist[k]
+          if find(d,expression) or find(resolveprefix(d),expression) then
+            result[#result+1]=resolveprefix(fl[3]) 
+            done=true
+            if allresults then
+              if trace_detail then
+                report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+              end
+            else
+              if trace_detail then
+                report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+              end
+              break
+            end
+          elseif trace_detail then
+            report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
           end
-         end
         end
-        if not done and entry.recursive then
-         if trace_detail then
-          report_resolving("scanning filesystem for %a",pname)
-         end
-         local files=resolvers.simplescanfiles(pname,false,true)
-         for k=1,#wantedfiles do
-          local w=wantedfiles[k]
-          local subpath=files[w]
-          if not subpath or subpath=="" then
-          elseif type(subpath)=="string" then
-           local fname=check_subpath(filejoin(pname,subpath,w))
-           if fname then
-            result[#result+1]=fname
-            done=true
-            if not allresults then
-             break
+      end
+      if done then
+        method="database"
+      else
+        method="filesystem" 
+        local scheme=entry.scheme
+        if not scheme or scheme=="file" then
+          local pname=entry.schemename
+          if not find(pname,"*",1,true) then
+            if can_be_dir(pname) then
+              if not done and not entry.prescanned then
+                if trace_detail then
+                  report_resolving("quick root scan for %a",pname)
+                end
+                for k=1,#wantedfiles do
+                  local w=wantedfiles[k]
+                  local fname=check_subpath(filejoin(pname,w))
+                  if fname then
+                    result[#result+1]=fname
+                    done=true
+                    if not allresults then
+                      break
+                    end
+                  end
+                end
+                if not done and entry.recursive then
+                  if trace_detail then
+                    report_resolving("scanning filesystem for %a",pname)
+                  end
+                  local files=resolvers.simplescanfiles(pname,false,true)
+                  for k=1,#wantedfiles do
+                    local w=wantedfiles[k]
+                    local subpath=files[w]
+                    if not subpath or subpath=="" then
+                    elseif type(subpath)=="string" then
+                      local fname=check_subpath(filejoin(pname,subpath,w))
+                      if fname then
+                        result[#result+1]=fname
+                        done=true
+                        if not allresults then
+                          break
+                        end
+                      end
+                    else
+                      for i=1,#subpath do
+                        local sp=subpath[i]
+                        if sp=="" then
+                        else
+                          local fname=check_subpath(filejoin(pname,sp,w))
+                          if fname then
+                            result[#result+1]=fname
+                            done=true
+                            if not allresults then
+                              break
+                            end
+                          end
+                        end
+                      end
+                      if done and not allresults then
+                        break
+                      end
+                    end
+                  end
+                end
+              end
             end
-           end
           else
-           for i=1,#subpath do
-            local sp=subpath[i]
-            if sp=="" then
-            else
-             local fname=check_subpath(filejoin(pname,sp,w))
-             if fname then
+          end
+        else
+          for k=1,#wantedfiles do
+            local pname=entry.barename
+            local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+            if fname then
               result[#result+1]=fname
               done=true
               if not allresults then
-               break
+                break
               end
-             end
             end
-           end
-           if done and not allresults then
-            break
-           end
           end
-         end
         end
-       end
       end
-     else
-     end
-    else
-     for k=1,#wantedfiles do
-      local pname=entry.barename
-      local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
-      if fname then
-       result[#result+1]=fname
-       done=true
-       if not allresults then
+      if done and not allresults then
         break
-       end
       end
-     end
     end
-   end
-   if done and not allresults then
-    break
-   end
+    if #result>0 then
+      return method,result
+    end
   end
-  if #result>0 then
-   return method,result
-  end
- end
 end
 local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
-  report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
-  local fname=wantedfiles[k]
-  if fname and isreadable(fname) then
-   filename=fname
-   result[#result+1]=filejoin('.',fname)
-   if not allresults then
-    break
-   end
+  if trace_detail then
+    report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
   end
- end
- if #result>0 then
-  return "onpath",result
- end
+  local result={}
+  for k=1,#wantedfiles do
+    local fname=wantedfiles[k]
+    if fname and isreadable(fname) then
+      filename=fname
+      result[#result+1]=filejoin('.',fname)
+      if not allresults then
+        break
+      end
+    end
+  end
+  if #result>0 then
+    return "onpath",result
+  end
 end
 local function find_otherwise(filename,filetype,wantedfiles,allresults) 
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
-  return "otherwise",{ resolveprefix(fl[3]) } 
- end
+  local filelist=collect_files(wantedfiles)
+  local fl=filelist and filelist[1]
+  if fl then
+    return "otherwise",{ resolveprefix(fl[3]) } 
+  end
 end
 collect_instance_files=function(filename,askedformat,allresults) 
- if not filename or filename=="" then
-  return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/") 
- if allresults then
-  local filetype,wantedfiles=find_analyze(filename,askedformat)
-  local results={
-   { find_direct   (filename,true) },
-   { find_wildcard (filename,true) },
-   { find_qualified(filename,true,askedformat) },
-   { find_intree   (filename,filetype,wantedfiles,true) },
-   { find_onpath   (filename,filetype,wantedfiles,true) },
-   { find_otherwise(filename,filetype,wantedfiles,true) },
-  }
-  local result,status,done={},{},{}
-  for k,r in next,results do
-   local method,list=r[1],r[2]
-   if method and list then
-    for i=1,#list do
-     local c=collapsepath(list[i])
-     if not done[c] then
-      result[#result+1]=c
-      done[c]=true
-     end
-     status[#status+1]=formatters["%-10s: %s"](method,c)
-    end
-   end
+  if not filename or filename=="" then
+    return {}
   end
-  if trace_detail then
-   report_resolving("lookup status: %s",table.serialize(status,filename))
-  end
-  return result,status
- else
-  local method,result,stamp,filetype,wantedfiles
-  if instance.remember then
-   if askedformat=="" then
-    stamp=formatters["%s::%s"](suffixonly(filename),filename)
-   else
-    stamp=formatters["%s::%s"](askedformat,filename)
-   end
-   result=stamp and instance.found[stamp]
-   if result then
-    if trace_locating then
-     report_resolving("remembered file %a",filename)
+  askedformat=askedformat or ""
+  filename=collapsepath(filename,".")
+  filename=gsub(filename,"^%./",getcurrentdir().."/") 
+  if allresults then
+    local filetype,wantedfiles=find_analyze(filename,askedformat)
+    local results={
+      { find_direct  (filename,true) },
+      { find_wildcard (filename,true) },
+      { find_qualified(filename,true,askedformat) },
+      { find_intree  (filename,filetype,wantedfiles,true) },
+      { find_onpath  (filename,filetype,wantedfiles,true) },
+      { find_otherwise(filename,filetype,wantedfiles,true) },
+    }
+    local result,status,done={},{},{}
+    for k,r in next,results do
+      local method,list=r[1],r[2]
+      if method and list then
+        for i=1,#list do
+          local c=collapsepath(list[i])
+          if not done[c] then
+            result[#result+1]=c
+            done[c]=true
+          end
+          status[#status+1]=formatters["%-10s: %s"](method,c)
+        end
+      end
     end
-    return result
-   end
-  end
-  method,result=find_direct(filename)
-  if not result then
-   method,result=find_wildcard(filename)
-   if not result then
-    method,result=find_qualified(filename,false,askedformat)
+    if trace_detail then
+      report_resolving("lookup status: %s",table.serialize(status,filename))
+    end
+    return result,status
+  else
+    local method,result,stamp,filetype,wantedfiles
+    if instance.remember then
+      if askedformat=="" then
+        stamp=formatters["%s::%s"](suffixonly(filename),filename)
+      else
+        stamp=formatters["%s::%s"](askedformat,filename)
+      end
+      result=stamp and instance.found[stamp]
+      if result then
+        if trace_locating then
+          report_resolving("remembered file %a",filename)
+        end
+        return result
+      end
+    end
+    method,result=find_direct(filename)
     if not result then
-     filetype,wantedfiles=find_analyze(filename,askedformat)
-     method,result=find_intree(filename,filetype,wantedfiles)
-     if not result then
-      method,result=find_onpath(filename,filetype,wantedfiles)
-      if resolve_otherwise and not result then
-       method,result=find_otherwise(filename,filetype,wantedfiles)
+      method,result=find_wildcard(filename)
+      if not result then
+        method,result=find_qualified(filename,false,askedformat)
+        if not result then
+          filetype,wantedfiles=find_analyze(filename,askedformat)
+          method,result=find_intree(filename,filetype,wantedfiles)
+          if not result then
+            method,result=find_onpath(filename,filetype,wantedfiles)
+            if resolve_otherwise and not result then
+              method,result=find_otherwise(filename,filetype,wantedfiles)
+            end
+          end
+        end
       end
-     end
     end
-   end
+    if result and #result>0 then
+      local foundname=collapsepath(result[1])
+      resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+      result={ foundname }
+    else
+      result={} 
+    end
+    if stamp then
+      if trace_locating then
+        report_resolving("remembering file %a using hash %a",filename,stamp)
+      end
+      instance.found[stamp]=result
+    end
+    return result
   end
-  if result and #result>0 then
-   local foundname=collapsepath(result[1])
-   resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
-   result={ foundname }
-  else
-   result={} 
-  end
-  if stamp then
-   if trace_locating then
-    report_resolving("remembering file %a using hash %a",filename,stamp)
-   end
-   instance.found[stamp]=result
-  end
-  return result
- end
 end
 local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
-  return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
-  local lowered=lower(filename)
-  if filename~=lowered then
-   result,status=collect_instance_files(lowered,filetype or "",allresults)
+  if not filename or filename=="" then
+    return {}
   end
- end
- return result or {},status
+  local result,status=collect_instance_files(filename,filetype or "",allresults)
+  if not result or #result==0 then
+    local lowered=lower(filename)
+    if filename~=lowered then
+      result,status=collect_instance_files(lowered,filetype or "",allresults)
+    end
+  end
+  return result or {},status
 end
 function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
-  return ""
- else
-  return findfiles(filename,filetype,true)
- end
+  if not filename or filename=="" then
+    return ""
+  else
+    return findfiles(filename,filetype,true)
+  end
 end
 function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
-  return ""
- else
-  return findfiles(filename,filetype,false)[1] or ""
- end
+  if not filename or filename=="" then
+    return ""
+  else
+    return findfiles(filename,filetype,false)[1] or ""
+  end
 end
 function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+  return filedirname(findfiles(filename,filetype,false)[1] or "")
 end
 local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
-  local found=methodhandler('concatinators',hash.type,hash.name,path,name)
-  if found and found~="" then
-   result[#result+1]=resolveprefix(found)
-   return not allresults
+  local base=filebasename(filename)
+  local result={}
+  local hashes=instance.hashes
+  local function okay(hash,path,name)
+    local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+    if found and found~="" then
+      result[#result+1]=resolveprefix(found)
+      return not allresults
+    end
   end
- end
- for k=1,#hashes do
-  local hash=hashes[k]
-  local content=instance.files[hash.name]
-  if content then
-   local path,name=lookup(content,base)
-   if not path then
-   elseif type(path)=="string" then
-    if okay(hash,path,name) then
-     return result
+  for k=1,#hashes do
+    local hash=hashes[k]
+    local content=instance.files[hash.name]
+    if content then
+      local path,name=lookup(content,base)
+      if not path then
+      elseif type(path)=="string" then
+        if okay(hash,path,name) then
+          return result
+        end
+      else
+        for i=1,#path do
+          if okay(hash,path[i],name) then
+            return result
+          end
+        end
+      end
     end
-   else
-    for i=1,#path do
-     if okay(hash,path[i],name) then
-      return result
-     end
-    end
-   end
   end
- end
- return result
+  return result
 end
 function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+  return findgivenfiles(filename,true)
 end
 function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+  return findgivenfiles(filename,false)[1] or ""
 end
 local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+  (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
 )
 function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+  return lpegmatch(makewildcard,pattern) or pattern
 end
 local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
-  local hashes=instance.hashes
-  local function okay(found,path,base,hashname,hashtype)
-   if find(found,path) then
-    local full=methodhandler('concatinators',hashtype,hashname,found,base)
-    if full and full~="" then
-     result[#result+1]=resolveprefix(full)
-     return not allresults
+  local result=result or {}
+  local base=filebasename(filename)
+  local dirn=filedirname(filename)
+  local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+  local name=lower(lpegmatch(makewildcard,base) or base)
+  local files=instance.files
+  if find(name,"*",1,true) then
+    local hashes=instance.hashes
+    local function okay(found,path,base,hashname,hashtype)
+      if find(found,path) then
+        local full=methodhandler('concatinators',hashtype,hashname,found,base)
+        if full and full~="" then
+          result[#result+1]=resolveprefix(full)
+          return not allresults
+        end
+      end
     end
-   end
-  end
-  for k=1,#hashes do
-   local hash=hashes[k]
-   local hashname=hash.name
-   local hashtype=hash.type
-   if hashname and hashtype then
-    for found,base in filtered(files[hashname],name) do
-     if type(found)=='string' then
-      if okay(found,path,base,hashname,hashtype) then
-       break
+    for k=1,#hashes do
+      local hash=hashes[k]
+      local hashname=hash.name
+      local hashtype=hash.type
+      if hashname and hashtype then
+        for found,base in filtered(files[hashname],name) do
+          if type(found)=='string' then
+            if okay(found,path,base,hashname,hashtype) then
+              break
+            end
+          else
+            for i=1,#found do
+              if okay(found[i],path,base,hashname,hashtype) then
+                break
+              end
+            end
+          end
+        end
       end
-     else
-      for i=1,#found do
-       if okay(found[i],path,base,hashname,hashtype) then
-        break
-       end
+    end
+  else
+    local function okayokay(found,path,base,hashname,hashtype)
+      if find(found,path) then
+        local full=methodhandler('concatinators',hashtype,hashname,found,base)
+        if full and full~="" then
+          result[#result+1]=resolveprefix(full)
+          return not allresults
+        end
       end
-     end
     end
-   end
-  end
- else
-  local function okayokay(found,path,base,hashname,hashtype)
-   if find(found,path) then
-    local full=methodhandler('concatinators',hashtype,hashname,found,base)
-    if full and full~="" then
-     result[#result+1]=resolveprefix(full)
-     return not allresults
-    end
-   end
-  end
-  local hashes=instance.hashes
-  for k=1,#hashes do
-   local hash=hashes[k]
-   local hashname=hash.name
-   local hashtype=hash.type
-   if hashname and hashtype then
-    local found,base=lookup(content,base)
-    if not found then
-    elseif type(found)=='string' then
-     if okay(found,path,base,hashname,hashtype) then
-      break
-     end
-    else
-     for i=1,#found do
-      if okay(found[i],path,base,hashname,hashtype) then
-       break
+    local hashes=instance.hashes
+    for k=1,#hashes do
+      local hash=hashes[k]
+      local hashname=hash.name
+      local hashtype=hash.type
+      if hashname and hashtype then
+        local found,base=lookup(content,base)
+        if not found then
+        elseif type(found)=='string' then
+          if okay(found,path,base,hashname,hashtype) then
+            break
+          end
+        else
+          for i=1,#found do
+            if okay(found[i],path,base,hashname,hashtype) then
+              break
+            end
+          end
+        end
       end
-     end
     end
-   end
   end
- end
- return result
+  return result
 end
 function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+  return findwildcardfiles(filename,true,result)
 end
 function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+  return findwildcardfiles(filename,false)[1] or ""
 end
 function resolvers.automount()
 end
 function resolvers.starttiming()
- statistics.starttiming(instance)
+  statistics.starttiming(instance)
 end
 function resolvers.stoptiming()
- statistics.stoptiming(instance)
+  statistics.stoptiming(instance)
 end
 function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
-  load_databases()
-  resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+  resolvers.starttiming()
+  identify_configuration_files()
+  load_configuration_files()
+  if option~="nofiles" then
+    load_databases()
+    resolvers.automount()
+  end
+  resolvers.stoptiming()
+  local files=instance.files
+  return files and next(files) and true
 end
 function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+  return statistics.elapsedtime(instance)
 end
 local function report(str)
- if trace_locating then
-  report_resolving(str) 
- else
-  print(str)
- end
+  if trace_locating then
+    report_resolving(str) 
+  else
+    print(str)
+  end
 end
 function resolvers.dowithfilesandreport(command,files,...) 
- if files and #files>0 then
-  if trace_locating then
-   report('') 
-  end
-  if type(files)=="string" then
-   files={ files }
-  end
-  for f=1,#files do
-   local file=files[f]
-   local result=command(file,...)
-   if type(result)=='string' then
-    report(result)
-   else
-    for i=1,#result do
-     report(result[i]) 
+  if files and #files>0 then
+    if trace_locating then
+      report('') 
     end
-   end
+    if type(files)=="string" then
+      files={ files }
+    end
+    for f=1,#files do
+      local file=files[f]
+      local result=command(file,...)
+      if type(result)=='string' then
+        report(result)
+      else
+        for i=1,#result do
+          report(result[i]) 
+        end
+      end
+    end
   end
- end
 end
-function resolvers.showpath(str)  
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)   
+  return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
 end
 function resolvers.registerfile(files,name,path)
- if files[name] then
-  if type(files[name])=='string' then
-   files[name]={ files[name],path }
+  if files[name] then
+    if type(files[name])=='string' then
+      files[name]={ files[name],path }
+    else
+      files[name]=path
+    end
   else
-   files[name]=path
+    files[name]=path
   end
- else
-  files[name]=path
- end
 end
 function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
-  func("^"..cleanpath(pathlist[i]))
- end
+  local pathlist=resolvers.expandedpathlist(name)
+  for i=1,#pathlist do
+    func("^"..cleanpath(pathlist[i]))
+  end
 end
 function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+  func(expandedvariable(name))
 end
 function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
-  fmtname=resolvers.findfile(fullname)
-  fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
-  local barename=removesuffix(fmtname)
-  local luaname=addsuffix(barename,luasuffixes.lua)
-  local lucname=addsuffix(barename,luasuffixes.luc)
-  local luiname=addsuffix(barename,luasuffixes.lui)
-  if isfile(luiname) then
-   return barename,luiname
-  elseif isfile(lucname) then
-   return barename,lucname
-  elseif isfile(luaname) then
-   return barename,luaname
+  local engine=environment.ownmain or "luatex"
+  local barename=removesuffix(name)
+  local fullname=addsuffix(barename,"fmt")
+  local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+  if fmtname=="" then
+    fmtname=resolvers.findfile(fullname)
+    fmtname=cleanpath(fmtname)
   end
- end
- return nil,nil
+  if fmtname~="" then
+    local barename=removesuffix(fmtname)
+    local luaname=addsuffix(barename,luasuffixes.lua)
+    local lucname=addsuffix(barename,luasuffixes.luc)
+    local luiname=addsuffix(barename,luasuffixes.lui)
+    if isfile(luiname) then
+      return barename,luiname
+    elseif isfile(lucname) then
+      return barename,lucname
+    elseif isfile(luaname) then
+      return barename,luaname
+    end
+  end
+  return nil,nil
 end
 function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
-  return default
- else
-  b=toboolean(b)
-  return (b==nil and default) or b
- end
+  local b=resolvers.expansion(str)
+  if b=="" then
+    return default
+  else
+    b=toboolean(b)
+    return (b==nil and default) or b
+  end
 end
 function resolvers.dowithfilesintree(pattern,handle,before,after) 
- local hashes=instance.hashes
- for i=1,#hashes do
-  local hash=hashes[i]
-  local blobtype=hash.type
-  local blobpath=hash.name
-  if blobtype and blobpath then
-   local total=0
-   local checked=0
-   local done=0
-   if before then
-    before(blobtype,blobpath,pattern)
-   end
-   for path,name in filtered(instance.files[blobpath],pattern) do
-    if type(path)=="string" then
-     checked=checked+1
-     if handle(blobtype,blobpath,path,name) then
-      done=done+1
-     end
-    else
-     checked=checked+#path
-     for i=1,#path do
-      if handle(blobtype,blobpath,path[i],name) then
-       done=done+1
+  local hashes=instance.hashes
+  for i=1,#hashes do
+    local hash=hashes[i]
+    local blobtype=hash.type
+    local blobpath=hash.name
+    if blobtype and blobpath then
+      local total=0
+      local checked=0
+      local done=0
+      if before then
+        before(blobtype,blobpath,pattern)
       end
-     end
+      for path,name in filtered(instance.files[blobpath],pattern) do
+        if type(path)=="string" then
+          checked=checked+1
+          if handle(blobtype,blobpath,path,name) then
+            done=done+1
+          end
+        else
+          checked=checked+#path
+          for i=1,#path do
+            if handle(blobtype,blobpath,path[i],name) then
+              done=done+1
+            end
+          end
+        end
+      end
+      if after then
+        after(blobtype,blobpath,pattern,total,checked,done)
+      end
     end
-   end
-   if after then
-    after(blobtype,blobpath,pattern,checked,done)
-   end
   end
- end
 end
 local obsolete=resolvers.obsolete or {}
 resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles   obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile  obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles  obsolete.find_files=resolvers.findfiles
 function resolvers.knownvariables(pattern)
- if instance then
-  local environment=instance.environment
-  local variables=instance.variables
-  local expansions=instance.expansions
-  local order=instance.order
-  local pattern=upper(pattern or "")
-  local result={}
-  for i=1,#order do
-   for key in next,order[i] do
-    if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
-     result[key]={
-      environment=rawget(environment,key),
-      variable=key,
-      expansion=expansions[key],
-      resolved=resolveprefix(expansions[key]),
-     }
+  if instance then
+    local environment=instance.environment
+    local variables=instance.variables
+    local expansions=instance.expansions
+    local order=instance.order
+    local pattern=upper(pattern or "")
+    local result={}
+    for i=1,#order do
+      for key in next,order[i] do
+        if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+          result[key]={
+            environment=rawget(environment,key),
+            variable=key,
+            expansion=expansions[key],
+            resolved=resolveprefix(expansions[key]),
+          }
+        end
+      end
     end
-   end
+    return result
+  else
+    return {}
   end
-  return result
- else
-  return {}
- end
 end
 
 
@@ -22885,14 +19311,14 @@
 
 package.loaded["data-pre"] = package.loaded["data-pre"] or true
 
--- original size: 4854, stripped down to: 2889
+-- original size: 4090, stripped down to: 3059
 
 if not modules then modules={} end modules ['data-pre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local resolvers=resolvers
 local prefixes=resolvers.prefixes
@@ -22905,64 +19331,64 @@
 local joinpath=file.join
 local isfile=lfs.isfile
 prefixes.environment=function(str)
- return cleanpath(expansion(str))
+  return cleanpath(expansion(str))
 end
 local function relative(str,n)
- if not isfile(str) then
-  local pstr="./"..str
-  if isfile(pstr) then
-   str=pstr
-  else
-   local p="../"
-   for i=1,n or 2 do
-    local pstr=p..str
+  if not isfile(str) then
+    local pstr="./"..str
     if isfile(pstr) then
-     str=pstr
-     break
+      str=pstr
     else
-     p=p.."../"
+      local p="../"
+      for i=1,n or 2 do
+        local pstr=p..str
+        if isfile(pstr) then
+          str=pstr
+          break
+        else
+          p=p.."../"
+        end
+      end
     end
-   end
   end
- end
- return cleanpath(str)
+  return cleanpath(str)
 end
 local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+  local fullname=findgivenfile(str) or ""
+  return cleanpath(fullname~="" and fullname or str)
 end
 prefixes.relative=relative
 prefixes.locate=locate
 prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
-  fullname=locate(str)
- end
- return fullname
+  local fullname=relative(str)
+  if not isfile(fullname) then
+    fullname=locate(str)
+  end
+  return fullname
 end
 prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str)) 
+  local fullname=findgivenfile(str) or ""
+  return cleanpath(basename((fullname~="" and fullname) or str)) 
 end
 prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+  local fullname=findgivenfile(str) or ""
+  return cleanpath(dirname((fullname~="" and fullname) or str))
 end
 prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+  local pth=getenv('SELFAUTOLOC')
+  return cleanpath(str and joinpath(pth,str) or pth)
 end
 prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+  local pth=getenv('SELFAUTOPARENT')
+  return cleanpath(str and joinpath(pth,str) or pth)
 end
 prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+  local pth=getenv('SELFAUTODIR')
+  return cleanpath(str and joinpath(pth,str) or pth)
 end
 prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+  local pth=getenv('HOME')
+  return cleanpath(str and joinpath(pth,str) or pth)
 end
 prefixes.env=prefixes.environment
 prefixes.rel=prefixes.relative
@@ -22972,24 +19398,24 @@
 prefixes.file=prefixes.filename
 prefixes.path=prefixes.pathname
 local function toppath()
- local inputstack=resolvers.inputstack 
- if not inputstack then      
-  return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
-  return "."
- else
-  return pathname
- end
+  local inputstack=resolvers.inputstack 
+  if not inputstack then         
+    return "."
+  end
+  local pathname=dirname(inputstack[#inputstack] or "")
+  if pathname=="" then
+    return "."
+  else
+    return pathname
+  end
 end
 local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
-  return "."
- else
-  return path
- end
+  local path=resolvers.stackpath()
+  if not path or path=="" then
+    return "."
+  else
+    return path
+  end
 end
 resolvers.toppath=toppath
 resolvers.jobpath=jobpath
@@ -22997,6 +19423,8 @@
 prefixes.jobpath=function(str) return cleanpath(joinpath(jobpath(),str)) end 
 resolvers.setdynamic("toppath")
 resolvers.setdynamic("jobpath")
+prefixes.jobfile=prefixes.jobpath
+resolvers.setdynamic("jobfile")
 
 
 end -- of closure
@@ -23005,14 +19433,14 @@
 
 package.loaded["data-inp"] = package.loaded["data-inp"] or true
 
--- original size: 910, stripped down to: 818
+-- original size: 910, stripped down to: 823
 
 if not modules then modules={} end modules ['data-inp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local allocate=utilities.storage.allocate
 local resolvers=resolvers
@@ -23035,14 +19463,14 @@
 
 package.loaded["data-out"] = package.loaded["data-out"] or true
 
--- original size: 530, stripped down to: 470
+-- original size: 530, stripped down to: 475
 
 if not modules then modules={} end modules ['data-out']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local allocate=utilities.storage.allocate
 local resolvers=resolvers
@@ -23058,16 +19486,16 @@
 
 package.loaded["data-fil"] = package.loaded["data-fil"] or true
 
--- original size: 3863, stripped down to: 3170
+-- original size: 3863, stripped down to: 3310
 
 if not modules then modules={} end modules ['data-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
 local report_files=logs.reporter("resolvers","files")
 local resolvers=resolvers
 local resolveprefix=resolvers.resolve
@@ -23075,88 +19503,88 @@
 local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
 local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
 function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename) 
- if realname and realname~='' and lfs.isdir(realname) then
-  if trace_locating then
-   report_files("file locator %a found as %a",filename,realname)
+  local filename=specification.filename
+  local realname=resolveprefix(filename) 
+  if realname and realname~='' and lfs.isdir(realname) then
+    if trace_locating then
+      report_files("file locator %a found as %a",filename,realname)
+    end
+    resolvers.appendhash('file',filename,true) 
+  elseif trace_locating then
+    report_files("file locator %a not found",filename)
   end
-  resolvers.appendhash('file',filename,true) 
- elseif trace_locating then
-  report_files("file locator %a not found",filename)
- end
 end
 function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+  local pathname=specification.filename
+  local content=caches.loadcontent(pathname,'files')
+  resolvers.registerfilehash(pathname,content,content==nil)
 end
 function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true) 
- resolvers.registerfilehash(pathname,content,true)
+  local pathname=specification.filename
+  local content=resolvers.scanfiles(pathname,false,true) 
+  resolvers.registerfilehash(pathname,content,true)
 end
 concatinators.file=file.join
 function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
-  if trace_locating then
-   report_files("file finder: %a found",filename)
+  local filename=specification.filename
+  local foundname=resolvers.findfile(filename,filetype)
+  if foundname and foundname~="" then
+    if trace_locating then
+      report_files("file finder: %a found",filename)
+    end
+    return foundname
+  else
+    if trace_locating then
+      report_files("file finder: %a not found",filename)
+    end
+    return finders.notfound()
   end
-  return foundname
- else
-  if trace_locating then
-   report_files("file finder: %a not found",filename)
-  end
-  return finders.notfound()
- end
 end
 function openers.helpers.textopener(tag,filename,f)
- return {
-  reader=function()         return f:read () end,
-  close=function() logs.show_close(filename) return f:close() end,
- }
+  return {
+    reader=function()              return f:read () end,
+    close=function() logs.show_close(filename) return f:close() end,
+  }
 end
 function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
-  local f=io.open(filename,"r")
-  if f then
-   if trace_locating then
-    report_files("file opener: %a opened",filename)
-   end
-   return openers.helpers.textopener("file",filename,f)
+  local filename=specification.filename
+  if filename and filename~="" then
+    local f=io.open(filename,"r")
+    if f then
+      if trace_locating then
+        report_files("file opener: %a opened",filename)
+      end
+      return openers.helpers.textopener("file",filename,f)
+    end
   end
- end
- if trace_locating then
-  report_files("file opener: %a not found",filename)
- end
- return openers.notfound()
+  if trace_locating then
+    report_files("file opener: %a not found",filename)
+  end
+  return openers.notfound()
 end
 function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
-  local f=io.open(filename,"rb")
-  if f then
-   logs.show_load(filename)
-   if trace_locating then
-    report_files("file loader: %a loaded",filename)
-   end
-   local s=f:read("*a") 
-   if checkgarbage then
-    checkgarbage(#s)
-   end
-   f:close()
-   if s then
-    return true,s,#s
-   end
+  local filename=specification.filename
+  if filename and filename~="" then
+    local f=io.open(filename,"rb")
+    if f then
+      logs.show_load(filename)
+      if trace_locating then
+        report_files("file loader: %a loaded",filename)
+      end
+      local s=f:read("*a") 
+      if checkgarbage then
+        checkgarbage(#s)
+      end
+      f:close()
+      if s then
+        return true,s,#s
+      end
+    end
   end
- end
- if trace_locating then
-  report_files("file loader: %a not found",filename)
- end
- return loaders.notfound()
+  if trace_locating then
+    report_files("file loader: %a not found",filename)
+  end
+  return loaders.notfound()
 end
 
 
@@ -23166,19 +19594,19 @@
 
 package.loaded["data-con"] = package.loaded["data-con"] or true
 
--- original size: 5029, stripped down to: 3432
+-- original size: 5029, stripped down to: 3607
 
 if not modules then modules={} end modules ['data-con']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.100,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false  trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false  trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false  trackers.register("resolvers.storage",function(v) trace_storage=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
 containers=containers or {}
 local containers=containers
 containers.usecache=true
@@ -23185,97 +19613,97 @@
 local report_containers=logs.reporter("resolvers","containers")
 local allocated={}
 local mt={
- __index=function(t,k)
-  if k=="writable" then
-   local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
-   t.writable=writable
-   return writable
-  elseif k=="readables" then
-   local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
-   t.readables=readables
-   return readables
-  end
- end,
- __storage__=true
+  __index=function(t,k)
+    if k=="writable" then
+      local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+      t.writable=writable
+      return writable
+    elseif k=="readables" then
+      local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+      t.readables=readables
+      return readables
+    end
+  end,
+  __storage__=true
 }
 function containers.define(category,subcategory,version,enabled)
- if category and subcategory then
-  local c=allocated[category]
-  if not c then
-   c={}
-   allocated[category]=c
+  if category and subcategory then
+    local c=allocated[category]
+    if not c then
+      c={}
+      allocated[category]=c
+    end
+    local s=c[subcategory]
+    if not s then
+      s={
+        category=category,
+        subcategory=subcategory,
+        storage={},
+        enabled=enabled,
+        version=version or math.pi,
+        trace=false,
+      }
+      setmetatable(s,mt)
+      c[subcategory]=s
+    end
+    return s
   end
-  local s=c[subcategory]
-  if not s then
-   s={
-    category=category,
-    subcategory=subcategory,
-    storage={},
-    enabled=enabled,
-    version=version or math.pi,
-    trace=false,
-   }
-   setmetatable(s,mt)
-   c[subcategory]=s
-  end
-  return s
- end
 end
 function containers.is_usable(container,name)
- return container.enabled and caches and caches.is_writable(container.writable,name)
+  return container.enabled and caches and caches.is_writable(container.writable,name)
 end
 function containers.is_valid(container,name)
- if name and name~="" then
-  local storage=container.storage[name]
-  return storage and storage.cache_version==container.version
- else
-  return false
- end
+  if name and name~="" then
+    local storage=container.storage[name]
+    return storage and storage.cache_version==container.version
+  else
+    return false
+  end
 end
 function containers.read(container,name)
- local storage=container.storage
- local stored=storage[name]
- if not stored and container.enabled and caches and containers.usecache then
-  stored=caches.loaddata(container.readables,name,container.writable)
-  if stored and stored.cache_version==container.version then
-   if trace_cache or trace_containers then
-    report_containers("action %a, category %a, name %a","load",container.subcategory,name)
-   end
-  else
-   stored=nil
+  local storage=container.storage
+  local stored=storage[name]
+  if not stored and container.enabled and caches and containers.usecache then
+    stored=caches.loaddata(container.readables,name,container.writable)
+    if stored and stored.cache_version==container.version then
+      if trace_cache or trace_containers then
+        report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+      end
+    else
+      stored=nil
+    end
+    storage[name]=stored
+  elseif stored then
+    if trace_cache or trace_containers then
+      report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+    end
   end
-  storage[name]=stored
- elseif stored then
-  if trace_cache or trace_containers then
-   report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
-  end
- end
- return stored
+  return stored
 end
 function containers.write(container,name,data)
- if data then
-  data.cache_version=container.version
-  if container.enabled and caches then
-   local unique,shared=data.unique,data.shared
-   data.unique,data.shared=nil,nil
-   caches.savedata(container.writable,name,data)
-   if trace_cache or trace_containers then
-    report_containers("action %a, category %a, name %a","save",container.subcategory,name)
-   end
-   data.unique,data.shared=unique,shared
+  if data then
+    data.cache_version=container.version
+    if container.enabled and caches then
+      local unique,shared=data.unique,data.shared
+      data.unique,data.shared=nil,nil
+      caches.savedata(container.writable,name,data)
+      if trace_cache or trace_containers then
+        report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+      end
+      data.unique,data.shared=unique,shared
+    end
+    if trace_cache or trace_containers then
+      report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+    end
+    container.storage[name]=data
   end
-  if trace_cache or trace_containers then
-   report_containers("action %a, category %a, name %a","store",container.subcategory,name)
-  end
-  container.storage[name]=data
- end
- return data
+  return data
 end
 function containers.content(container,name)
- return container.storage[name]
+  return container.storage[name]
 end
 function containers.cleanname(name)
- return (gsub(lower(name),"[^%w\128-\255]+","-")) 
+  return (gsub(lower(name),"[^%w\128-\255]+","-")) 
 end
 
 
@@ -23285,101 +19713,97 @@
 
 package.loaded["data-use"] = package.loaded["data-use"] or true
 
--- original size: 4434, stripped down to: 3180
+-- original size: 4272, stripped down to: 3289
 
 if not modules then modules={} end modules ['data-use']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
 local report_mounts=logs.reporter("resolvers","mounts")
 local resolvers=resolvers
 resolvers.automounted=resolvers.automounted or {}
 function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
-  mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
-  resolvers.starttiming()
-  for k=1,#mountpaths do
-   local root=mountpaths[k]
-   local f=io.open(root.."/url.tmi")
-   if f then
-    for line in f:lines() do
-     if line then
-      if find(line,"^[%%#%-]") then
-      elseif find(line,"^zip://") then
-       if trace_locating then
-        report_mounts("mounting %a",line)
-       end
-       table.insert(resolvers.automounted,line)
-       resolvers.usezipfile(line)
+  local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+  if (not mountpaths or #mountpaths==0) and usecache then
+    mountpaths=caches.getreadablepaths("mount")
+  end
+  if mountpaths and #mountpaths>0 then
+    resolvers.starttiming()
+    for k=1,#mountpaths do
+      local root=mountpaths[k]
+      local f=io.open(root.."/url.tmi")
+      if f then
+        for line in f:lines() do
+          if line then
+            if find(line,"^[%%#%-]") then
+            elseif find(line,"^zip://") then
+              if trace_locating then
+                report_mounts("mounting %a",line)
+              end
+              table.insert(resolvers.automounted,line)
+              resolvers.usezipfile(line)
+            end
+          end
+        end
+        f:close()
       end
-     end
     end
-    f:close()
-   end
+    resolvers.stoptiming()
   end
-  resolvers.stoptiming()
- end
 end
 statistics.register("used config file",function() return caches.configfiles() end)
 statistics.register("used cache path",function() return caches.usedpaths() end)
 function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner) 
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
-  local luvname=file.replacesuffix(texname,"luv") 
-  local luvdata={
-   enginebanner=enginebanner,
-   formatbanner=formatbanner,
-   sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
-   sourcefile=sourcefile,
-   luaversion=LUAVERSION,
-  }
-  io.savedata(luvname,table.serialize(luvdata,true))
-  lua.registerfinalizer(function()
-   if jit then
-    logs.report("format banner","%s  lua: %s jit",banner,LUAVERSION)
-   else
-    logs.report("format banner","%s  lua: %s",banner,LUAVERSION)
-   end
-   logs.newline()
-  end)
- end
+  local enginebanner=status.banner
+  if formatbanner and enginebanner and sourcefile then
+    local luvname=file.replacesuffix(texname,"luv") 
+    local luvdata={
+      enginebanner=enginebanner,
+      formatbanner=formatbanner,
+      sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+      sourcefile=sourcefile,
+      luaversion=LUAVERSION,
+    }
+    io.savedata(luvname,table.serialize(luvdata,true))
+    lua.registerfinalizer(function()
+      logs.report("format banner","%s",banner)
+      logs.newline()
+    end)
+  end
 end
 function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
-  local luvname=file.replacesuffix(texname,"luv") 
-  if lfs.isfile(luvname) then
-   local luv=dofile(luvname)
-   if luv and luv.sourcefile then
-    local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
-    local luvbanner=luv.enginebanner or "?"
-    if luvbanner~=enginebanner then
-     return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+  local enginebanner=status.banner
+  if enginebanner and texname then
+    local luvname=file.replacesuffix(texname,"luv") 
+    if lfs.isfile(luvname) then
+      local luv=dofile(luvname)
+      if luv and luv.sourcefile then
+        local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+        local luvbanner=luv.enginebanner or "?"
+        if luvbanner~=enginebanner then
+          return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+        end
+        local luvhash=luv.sourcehash or "?"
+        if luvhash~=sourcehash then
+          return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+        end
+        local luvluaversion=luv.luaversion or 0
+        if luvluaversion~=LUAVERSION then
+          return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+        end
+      else
+        return "invalid status file"
+      end
+    else
+      return "missing status file"
     end
-    local luvhash=luv.sourcehash or "?"
-    if luvhash~=sourcehash then
-     return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
-    end
-    local luvluaversion=luv.luaversion or 0
-    if luvluaversion~=LUAVERSION then
-     return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
-    end
-   else
-    return "invalid status file"
-   end
-  else
-   return "missing status file"
   end
- end
- return true
+  return true
 end
 
 
@@ -23389,233 +19813,233 @@
 
 package.loaded["data-zip"] = package.loaded["data-zip"] or true
 
--- original size: 8700, stripped down to: 6313
+-- original size: 8716, stripped down to: 6795
 
 if not modules then modules={} end modules ['data-zip']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local format,find,match=string.format,string.find,string.match
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
 local report_zip=logs.reporter("resolvers","zip")
 local resolvers=resolvers
 zip=zip or {}
 local zip=zip
-local archives=zip.archives or {}
-zip.archives=archives
-local registeredfiles=zip.registeredfiles or {}
-zip.registeredfiles=registeredfiles
+zip.archives=zip.archives or {}
+local archives=zip.archives
+zip.registeredfiles=zip.registeredfiles or {}
+local registeredfiles=zip.registeredfiles
 local function validzip(str) 
- if not find(str,"^zip://") then
-  return "zip:///"..str
- else
-  return str
- end
+  if not find(str,"^zip://") then
+    return "zip:///"..str
+  else
+    return str
+  end
 end
 function zip.openarchive(name)
- if not name or name=="" then
-  return nil
- else
-  local arch=archives[name]
-  if not arch then
-     local full=resolvers.findfile(name) or ""
-     arch=full~="" and zip.open(full) or false
-     archives[name]=arch
+  if not name or name=="" then
+    return nil
+  else
+    local arch=archives[name]
+    if not arch then
+      local full=resolvers.findfile(name) or ""
+      arch=full~="" and zip.open(full) or false
+      archives[name]=arch
+    end
+    return arch
   end
-    return arch
- end
 end
 function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
-  zip.close(archives[name])
-  archives[name]=nil
- end
+  if not name or (name=="" and archives[name]) then
+    zip.close(archives[name])
+    archives[name]=nil
+  end
 end
 function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive) 
- if trace_locating then
-  if zipfile then
-   report_zip("locator: archive %a found",archive)
-  else
-   report_zip("locator: archive %a not found",archive)
+  local archive=specification.filename
+  local zipfile=archive and archive~="" and zip.openarchive(archive) 
+  if trace_locating then
+    if zipfile then
+      report_zip("locator: archive %a found",archive)
+    else
+      report_zip("locator: archive %a not found",archive)
+    end
   end
- end
 end
 function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
-  report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+  local archive=specification.filename
+  if trace_locating then
+    report_zip("loading file %a",archive)
+  end
+  resolvers.usezipfile(specification.original)
 end
 function resolvers.concatinators.zip(zipfile,path,name) 
- if not path or path=="" then
-  return format('%s?name=%s',zipfile,name)
- else
-  return format('%s?name=%s/%s',zipfile,path,name)
- end
+  if not path or path=="" then
+    return format('%s?name=%s',zipfile,name)
+  else
+    return format('%s?name=%s/%s',zipfile,path,name)
+  end
 end
 function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
-  local query=url.query(specification.query)
-  local queryname=query.name
-  if queryname then
-   local zfile=zip.openarchive(archive)
-   if zfile then
-    if trace_locating then
-     report_zip("finder: archive %a found",archive)
+  local original=specification.original
+  local archive=specification.filename
+  if archive then
+    local query=url.query(specification.query)
+    local queryname=query.name
+    if queryname then
+      local zfile=zip.openarchive(archive)
+      if zfile then
+        if trace_locating then
+          report_zip("finder: archive %a found",archive)
+        end
+        local dfile=zfile:open(queryname)
+        if dfile then
+          dfile=zfile:close()
+          if trace_locating then
+            report_zip("finder: file %a found",queryname)
+          end
+          return specification.original
+        elseif trace_locating then
+          report_zip("finder: file %a not found",queryname)
+        end
+      elseif trace_locating then
+        report_zip("finder: unknown archive %a",archive)
+      end
     end
-    local dfile=zfile:open(queryname)
-    if dfile then
-     dfile:close()
-     if trace_locating then
-      report_zip("finder: file %a found",queryname)
-     end
-     return specification.original
-    elseif trace_locating then
-     report_zip("finder: file %a not found",queryname)
-    end
-   elseif trace_locating then
-    report_zip("finder: unknown archive %a",archive)
-   end
   end
- end
- if trace_locating then
-  report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+  if trace_locating then
+    report_zip("finder: %a not found",original)
+  end
+  return resolvers.finders.notfound()
 end
 function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
-  local query=url.query(specification.query)
-  local queryname=query.name
-  if queryname then
-   local zfile=zip.openarchive(archive)
-   if zfile then
-    if trace_locating then
-     report_zip("opener; archive %a opened",archive)
+  local original=specification.original
+  local archive=specification.filename
+  if archive then
+    local query=url.query(specification.query)
+    local queryname=query.name
+    if queryname then
+      local zfile=zip.openarchive(archive)
+      if zfile then
+        if trace_locating then
+          report_zip("opener; archive %a opened",archive)
+        end
+        local dfile=zfile:open(queryname)
+        if dfile then
+          if trace_locating then
+            report_zip("opener: file %a found",queryname)
+          end
+          return resolvers.openers.helpers.textopener('zip',original,dfile)
+        elseif trace_locating then
+          report_zip("opener: file %a not found",queryname)
+        end
+      elseif trace_locating then
+        report_zip("opener: unknown archive %a",archive)
+      end
     end
-    local dfile=zfile:open(queryname)
-    if dfile then
-     if trace_locating then
-      report_zip("opener: file %a found",queryname)
-     end
-     return resolvers.openers.helpers.textopener('zip',original,dfile)
-    elseif trace_locating then
-     report_zip("opener: file %a not found",queryname)
-    end
-   elseif trace_locating then
-    report_zip("opener: unknown archive %a",archive)
-   end
   end
- end
- if trace_locating then
-  report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+  if trace_locating then
+    report_zip("opener: %a not found",original)
+  end
+  return resolvers.openers.notfound()
 end
 function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
-  local query=url.query(specification.query)
-  local queryname=query.name
-  if queryname then
-   local zfile=zip.openarchive(archive)
-   if zfile then
-    if trace_locating then
-     report_zip("loader: archive %a opened",archive)
+  local original=specification.original
+  local archive=specification.filename
+  if archive then
+    local query=url.query(specification.query)
+    local queryname=query.name
+    if queryname then
+      local zfile=zip.openarchive(archive)
+      if zfile then
+        if trace_locating then
+          report_zip("loader: archive %a opened",archive)
+        end
+        local dfile=zfile:open(queryname)
+        if dfile then
+          logs.show_load(original)
+          if trace_locating then
+            report_zip("loader; file %a loaded",original)
+          end
+          local s=dfile:read("*all")
+          dfile:close()
+          return true,s,#s
+        elseif trace_locating then
+          report_zip("loader: file %a not found",queryname)
+        end
+      elseif trace_locating then
+        report_zip("loader; unknown archive %a",archive)
+      end
     end
-    local dfile=zfile:open(queryname)
-    if dfile then
-     logs.show_load(original)
-     if trace_locating then
-      report_zip("loader; file %a loaded",original)
-     end
-     local s=dfile:read("*all")
-     dfile:close()
-     return true,s,#s
-    elseif trace_locating then
-     report_zip("loader: file %a not found",queryname)
-    end
-   elseif trace_locating then
-    report_zip("loader; unknown archive %a",archive)
-   end
   end
- end
- if trace_locating then
-  report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+  if trace_locating then
+    report_zip("loader: %a not found",original)
+  end
+  return resolvers.openers.notfound()
 end
 function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive) 
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
-  local z=zip.openarchive(archive)
-  if z then
-   local tree=url.query(specification.query).tree or ""
-   if trace_locating then
-    report_zip("registering: archive %a",archive)
-   end
-   resolvers.starttiming()
-   resolvers.prependhash('zip',archive)
-   resolvers.extendtexmfvariable(archive) 
-   registeredfiles[archive]=z
-   resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
-   resolvers.stoptiming()
+  local specification=resolvers.splitmethod(archive) 
+  local archive=specification.filename
+  if archive and not registeredfiles[archive] then
+    local z=zip.openarchive(archive)
+    if z then
+      local tree=url.query(specification.query).tree or ""
+      if trace_locating then
+        report_zip("registering: archive %a",archive)
+      end
+      resolvers.starttiming()
+      resolvers.prependhash('zip',archive)
+      resolvers.extendtexmfvariable(archive) 
+      registeredfiles[archive]=z
+      resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+      resolvers.stoptiming()
+    elseif trace_locating then
+      report_zip("registering: unknown archive %a",archive)
+    end
   elseif trace_locating then
-   report_zip("registering: unknown archive %a",archive)
+    report_zip("registering: archive %a not found",archive)
   end
- elseif trace_locating then
-  report_zip("registering: archive %a not found",archive)
- end
 end
 function resolvers.registerzipfile(z,tree)
- local names={}
- local files={} 
- local remap={} 
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
-  report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
-  local filename=i.filename
-  local path,name=match(filename,filter)
-  if not path then
-   n=n+1
-   register(names,filename,"")
-   local usedname=lower(filename)
-   files[usedname]=""
-   if usedname~=filename then
-    remap[usedname]=filename
-   end
-  elseif name and name~="" then
-   n=n+1
-   register(names,name,path)
-   local usedname=lower(name)
-   files[usedname]=path
-   if usedname~=name then
-    remap[usedname]=name
-   end
-  else
+  local names={}
+  local files={} 
+  local remap={} 
+  local n=0
+  local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+  local register=resolvers.registerfile
+  if trace_locating then
+    report_zip("registering: using filter %a",filter)
   end
- end
- report_zip("registering: %s files registered",n)
- return {
-  files=files,
-  remap=remap,
- }
+  for i in z:files() do
+    local filename=i.filename
+    local path,name=match(filename,filter)
+    if not path then
+      n=n+1
+      register(names,filename,"")
+      local usedname=lower(filename)
+      files[usedname]=""
+      if usedname~=filename then
+        remap[usedname]=filename
+      end
+    elseif name and name~="" then
+      n=n+1
+      register(names,name,path)
+      local usedname=lower(name)
+      files[usedname]=path
+      if usedname~=name then
+        remap[usedname]=name
+      end
+    else
+    end
+  end
+  report_zip("registering: %s files registered",n)
+  return {
+    files=files,
+    remap=remap,
+  }
 end
 
 
@@ -23625,20 +20049,20 @@
 
 package.loaded["data-tre"] = package.loaded["data-tre"] or true
 
--- original size: 8478, stripped down to: 5223
+-- original size: 8479, stripped down to: 5580
 
 if not modules then modules={} end modules ['data-tre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file   .join
+local basename,dirname,joinname=file.basename,file.dirname,file  .join
 local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
 local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
 local report_trees=logs.reporter("resolvers","trees")
 local resolvers=resolvers
 local resolveprefix=resolvers.resolve
@@ -23647,167 +20071,165 @@
 local collectors={}
 local found={}
 function resolvers.finders.tree(specification) 
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
-  if spec~="" then
-   local path=dirname(spec)
-   local name=basename(spec)
-   if path=="" then
-    path="."
-   end
-   local names=collectors[path]
-   if not names then
-    local pattern=find(path,"/%*+$") and path or (path.."/*")
-    names=globdir(pattern)
-    collectors[path]=names
-   end
-   local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
-   for i=1,#names do
-    local fullname=names[i]
-    if find(fullname,pattern) then
-     found[spec]=fullname
-     return fullname
+  local spec=specification.filename
+  local okay=found[spec]
+  if okay==nil then
+    if spec~="" then
+      local path=dirname(spec)
+      local name=basename(spec)
+      if path=="" then
+        path="."
+      end
+      local names=collectors[path]
+      if not names then
+        local pattern=find(path,"/%*+$") and path or (path.."/*")
+        names=globdir(pattern)
+        collectors[path]=names
+      end
+      local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+      for i=1,#names do
+        local fullname=names[i]
+        if find(fullname,pattern) then
+          found[spec]=fullname
+          return fullname
+        end
+      end
+      local pattern=lower(pattern)
+      for i=1,#names do
+        local fullname=lower(names[i])
+        if find(fullname,pattern) then
+          if isfile(fullname) then
+            found[spec]=fullname
+            return fullname
+          else
+            break
+          end
+        end
+      end
     end
-   end
-   local pattern=lower(pattern)
-   for i=1,#names do
-    local fullname=lower(names[i])
-    if find(fullname,pattern) then
-     if isfile(fullname) then
-      found[spec]=fullname
-      return fullname
-     else
-      break
-     end
-    end
-   end
+    okay=notfound() 
+    found[spec]=okay
   end
-  okay=notfound() 
-  found[spec]=okay
- end
- return okay
+  return okay
 end
 function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name) 
- if realname and realname~='' and isdir(realname) then
-  if trace_locating then
-   report_trees("locator %a found",realname)
+  local name=specification.filename
+  local realname=resolveprefix(name) 
+  if realname and realname~='' and isdir(realname) then
+    if trace_locating then
+      report_trees("locator %a found",realname)
+    end
+    resolvers.appendhash('tree',name,false) 
+  elseif trace_locating then
+    report_trees("locator %a not found",name)
   end
-  resolvers.appendhash('tree',name,false) 
- elseif trace_locating then
-  report_trees("locator %a not found",name)
- end
 end
 function resolvers.hashers.tree(specification)
- local name=specification.filename
- if trace_locating then
-  report_trees("analyzing %a",name)
- end
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+  local name=specification.filename
+    report_trees("analyzing %a",name)
+  resolvers.methodhandler("hashers",name)
+  resolvers.generators.file(specification)
 end
 local collectors={}
 local splitter=lpeg.splitat("/**/")
 local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
 table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
-  content=resolvers.scanfiles(rootname,nil,nil,false,true) 
-  caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+  local rootname=lpegmatch(stripper,k)
+  local dataname=joinname(rootname,"dirlist")
+  local content=caches.loadcontent(dataname,"files",dataname)
+  if not content then
+    content=resolvers.scanfiles(rootname,nil,nil,false,true) 
+    caches.savecontent(dataname,"files",content,dataname)
+  end
+  t[k]=content
+  return content
 end)
 local function checked(root,p,n)
- if p then
-  if type(p)=="table" then
-   for i=1,#p do
-    local fullname=joinname(root,p[i],n)
-    if isfile(fullname) then 
-     return fullname
+  if p then
+    if type(p)=="table" then
+      for i=1,#p do
+        local fullname=joinname(root,p[i],n)
+        if isfile(fullname) then 
+          return fullname
+        end
+      end
+    else
+      local fullname=joinname(root,p,n)
+      if isfile(fullname) then 
+        return fullname
+      end
     end
-   end
-  else
-   local fullname=joinname(root,p,n)
-   if isfile(fullname) then 
-    return fullname
-   end
   end
- end
- return notfound()
+  return notfound()
 end
 local function resolve(specification) 
- local filename=specification.filename
- if filename~="" then
-  local root,rest=lpegmatch(splitter,filename)
-  if root and rest then
-   local path,name=dirname(rest),basename(rest)
-   if name~=rest then
-    local content=collectors[root]
-    local p,n=lookup(content,name)
-    if not p then
-     return notfound()
-    end
-    local pattern=".*/"..path.."$"
-    local istable=type(p)=="table"
-    if istable then
-     for i=1,#p do
-      local pi=p[i]
-      if pi==path or find(pi,pattern) then
-       local fullname=joinname(root,pi,n)
-       if isfile(fullname) then 
-        return fullname
-       end
+  local filename=specification.filename
+  if filename~="" then
+    local root,rest=lpegmatch(splitter,filename)
+    if root and rest then
+      local path,name=dirname(rest),basename(rest)
+      if name~=rest then
+        local content=collectors[root]
+        local p,n=lookup(content,name)
+        if not p then
+          return notfound()
+        end
+        local pattern=".*/"..path.."$"
+        local istable=type(p)=="table"
+        if istable then
+          for i=1,#p do
+            local pi=p[i]
+            if pi==path or find(pi,pattern) then
+              local fullname=joinname(root,pi,n)
+              if isfile(fullname) then 
+                return fullname
+              end
+            end
+          end
+        elseif p==path or find(p,pattern) then
+          local fullname=joinname(root,p,n)
+          if isfile(fullname) then 
+            return fullname
+          end
+        end
+        local queries=specification.queries
+        if queries and queries.option=="fileonly" then
+          return checked(root,p,n)
+        else
+          return notfound()
+        end
       end
-     end
-    elseif p==path or find(p,pattern) then
-     local fullname=joinname(root,p,n)
-     if isfile(fullname) then 
-      return fullname
-     end
     end
-    local queries=specification.queries
-    if queries and queries.option=="fileonly" then
-     return checked(root,p,n)
-    else
-     return notfound()
+    local path,name=dirname(filename),basename(filename)
+    local root=lpegmatch(stripper,path)
+    local content=collectors[path]
+    local p,n=lookup(content,name)
+    if p then
+      return checked(root,p,n)
     end
-   end
   end
-  local path,name=dirname(filename),basename(filename)
-  local root=lpegmatch(stripper,path)
-  local content=collectors[path]
-  local p,n=lookup(content,name)
-  if p then
-   return checked(root,p,n)
-  end
- end
- return notfound()
+  return notfound()
 end
-resolvers.finders   .dirlist=resolve
-resolvers.locators  .dirlist=resolvers.locators  .tree
-resolvers.hashers   .dirlist=resolvers.hashers   .tree
+resolvers.finders  .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers  .dirlist=resolvers.hashers  .tree
 resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers   .dirlist=resolvers.openers   .file
-resolvers.loaders   .dirlist=resolvers.loaders   .file
+resolvers.openers  .dirlist=resolvers.openers  .file
+resolvers.loaders  .dirlist=resolvers.loaders  .file
 function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
-  queries.option="fileonly"
- else
-  specification.queries={ option="fileonly" }
- end
- return resolve(specification)
+  local queries=specification.queries
+  if queries then
+    queries.option="fileonly"
+  else
+    specification.queries={ option="fileonly" }
+  end
+  return resolve(specification)
 end
-resolvers.locators  .dirfile=resolvers.locators  .dirlist
-resolvers.hashers   .dirfile=resolvers.hashers   .dirlist
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers  .dirfile=resolvers.hashers  .dirlist
 resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers   .dirfile=resolvers.openers   .dirlist
-resolvers.loaders   .dirfile=resolvers.loaders   .dirlist
+resolvers.openers  .dirfile=resolvers.openers  .dirlist
+resolvers.loaders  .dirfile=resolvers.loaders  .dirlist
 
 
 end -- of closure
@@ -23816,19 +20238,19 @@
 
 package.loaded["data-sch"] = package.loaded["data-sch"] or true
 
--- original size: 6753, stripped down to: 5268
+-- original size: 6753, stripped down to: 5511
 
 if not modules then modules={} end modules ['data-sch']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local load,tonumber=load,tonumber
 local gsub,concat,format=string.gsub,table.concat,string.format
 local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false  trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
 local report_schemes=logs.reporter("resolvers","schemes")
 local http=require("socket.http")
 local ltn12=require("ltn12")
@@ -23841,27 +20263,27 @@
 local threshold=24*60*60
 directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
 function cleaners.none(specification)
- return specification.original
+  return specification.original
 end
 function cleaners.strip(specification) 
- local path,name=file.splitbase(specification.original)
- if path=="" then
-  return (gsub(name,"[^%a%d%.]+","-"))
- else
-  return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+  local path,name=file.splitbase(specification.original)
+  if path=="" then
+    return (gsub(name,"[^%a%d%.]+","-"))
+  else
+    return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+  end
 end
 function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+  return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
 end
 local cleaner=cleaners.strip
 directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
 function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
-  report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+  local hash=cleaner(specification)
+  if trace_schemes then
+    report_schemes("hashing %a to %a",specification.original,hash)
+  end
+  return hash
 end
 local cached={}
 local loaded={}
@@ -23869,139 +20291,139 @@
 local thresholds={}
 local handlers={}
 local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
-  cachename="cache",
-  original="url",
- }
+  name="curl resolver",
+  method="execute",
+  program="curl",
+  template="--silent --insecure --create-dirs --output %cachename% %original%",
+  checkers={
+    cachename="cache",
+    original="url",
+  }
 }
 local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
-  statistics.starttiming(schemes)
-  if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
-   cached[original]=cachename
-   local handler=handlers[scheme]
-   if handler then
-    if trace_schemes then
-     report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
+  local original=specification.original
+  local scheme=specification.scheme
+  local cleanname=schemes.cleanname(specification)
+  local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+  if not cached[original] then
+    statistics.starttiming(schemes)
+    if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+      cached[original]=cachename
+      local handler=handlers[scheme]
+      if handler then
+        if trace_schemes then
+          report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
+        end
+        logs.flush()
+        handler(specification,cachename)
+      else
+        if trace_schemes then
+          report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
+        end
+        logs.flush()
+        runner {
+          original=original,
+          cachename=cachename,
+        }
+      end
     end
-    logs.flush()
-    handler(specification,cachename)
-   else
+    if io.exists(cachename) then
+      cached[original]=cachename
+      if trace_schemes then
+        report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+      end
+    else
+      cached[original]=""
+      if trace_schemes then
+        report_schemes("using missing %a, protocol %a",original,scheme)
+      end
+    end
+    loaded[scheme]=loaded[scheme]+1
+    statistics.stoptiming(schemes)
+  else
     if trace_schemes then
-     report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
+      report_schemes("reusing %a, protocol %a",original,scheme)
     end
-    logs.flush()
-    runner {
-     original=original,
-     cachename=cachename,
-    }
-   end
+    reused[scheme]=reused[scheme]+1
   end
-  if io.exists(cachename) then
-   cached[original]=cachename
-   if trace_schemes then
-    report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
-   end
-  else
-   cached[original]=""
-   if trace_schemes then
-    report_schemes("using missing %a, protocol %a",original,scheme)
-   end
-  end
-  loaded[scheme]=loaded[scheme]+1
-  statistics.stoptiming(schemes)
- else
-  if trace_schemes then
-   report_schemes("reusing %a, protocol %a",original,scheme)
-  end
-  reused[scheme]=reused[scheme]+1
- end
- return cached[original]
+  return cached[original]
 end
 local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+  return resolvers.methodhandler("finders",fetch(specification),filetype)
 end
 local opener=openers.file
 local loader=loaders.file
 local function install(scheme,handler,newthreshold)
- handlers  [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders   [scheme]=finder
- openers   [scheme]=opener
- loaders   [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+  handlers [scheme]=handler
+  loaded  [scheme]=0
+  reused  [scheme]=0
+  finders  [scheme]=finder
+  openers  [scheme]=opener
+  loaders  [scheme]=loader
+  thresholds[scheme]=newthreshold or threshold
 end
 schemes.install=install
 local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
-  url=specification.original,
-  sink=ltn12.sink.file(f)
- }
- if not status then
-  os.remove(tempname)
- else
-  os.remove(cachename)
-  os.rename(tempname,cachename)
- end
- return cachename
+  local tempname=cachename..".tmp"
+  local f=io.open(tempname,"wb")
+  local status,message=http.request {
+    url=specification.original,
+    sink=ltn12.sink.file(f)
+  }
+  if not status then
+    os.remove(tempname)
+  else
+    os.remove(cachename)
+    os.rename(tempname,cachename)
+  end
+  return cachename
 end
 install('http',http_handler)
 install('https') 
 install('ftp')
 statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
-  if v>0 then
-   nl=nl+1
-   l[nl]=k..":"..v
+  local l,r,nl,nr={},{},0,0
+  for k,v in table.sortedhash(loaded) do
+    if v>0 then
+      nl=nl+1
+      l[nl]=k..":"..v
+    end
   end
- end
- for k,v in table.sortedhash(reused) do
-  if v>0 then
-   nr=nr+1
-   r[nr]=k..":"..v
+  for k,v in table.sortedhash(reused) do
+    if v>0 then
+      nr=nr+1
+      r[nr]=k..":"..v
+    end
   end
- end
- local n=nl+nr
- if n>0 then
-  l=nl>0 and concat(l) or "none"
-  r=nr>0 and concat(r) or "none"
-  return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
-   statistics.elapsedtime(schemes),n,threshold,l,r)
- else
-  return nil
- end
+  local n=nl+nr
+  if n>0 then
+    l=nl>0 and concat(l) or "none"
+    r=nr>0 and concat(r) or "none"
+    return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+      statistics.elapsedtime(schemes),n,threshold,l,r)
+  else
+    return nil
+  end
 end)
 local httprequest=http.request
 local toquery=url.toquery
 local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
-  url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply 
+  local q=data and toquery(data)
+  if q then
+    url=url.."?"..q
+  end
+  local reply=httprequest(url)
+  return reply 
 end
 schemes.fetchstring=fetchstring
 function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
-  local s=load("return "..reply)
-  if s then
-   return s()
+  local reply=fetchstring(url,data)
+  if reply then
+    local s=load("return "..reply)
+    if s then
+      return s()
+    end
   end
- end
 end
 
 
@@ -24011,14 +20433,14 @@
 
 package.loaded["data-lua"] = package.loaded["data-lua"] or true
 
--- original size: 4207, stripped down to: 3041
+-- original size: 4207, stripped down to: 3137
 
 if not modules then modules={} end modules ['data-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local package,lpeg=package,lpeg
 local gsub=string.gsub
@@ -24037,20 +20459,20 @@
 trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
 trackers.register("resolvers.locating",function(v) helpers.trace=v end)
 helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+  "already loaded",
+  "preload table",
+  "lua variable format",
+  "lib variable format",
+  "lua extra list",
+  "lib extra list",
+  "path specification",
+  "cpath specification",
+  "all in one fallback",
+  "not loaded",
 }
 local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
 function helpers.cleanpath(path) 
- return resolveprefix(lpegmatch(pattern,path))
+  return resolveprefix(lpegmatch(pattern,path))
 end
 local loadedaslib=helpers.loadedaslib
 local registerpath=helpers.registerpath
@@ -24058,56 +20480,56 @@
 local luaformatpaths
 local libformatpaths
 local function getluaformatpaths()
- if not luaformatpaths then
-  luaformatpaths={}
-  for i=1,#luaformats do
-   registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
+  if not luaformatpaths then
+    luaformatpaths={}
+    for i=1,#luaformats do
+      registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
+    end
   end
- end
- return luaformatpaths
+  return luaformatpaths
 end
 local function getlibformatpaths()
- if not libformatpaths then
-  libformatpaths={}
-  for i=1,#libformats do
-   registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
+  if not libformatpaths then
+    libformatpaths={}
+    for i=1,#libformats do
+      registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
+    end
   end
- end
- return libformatpaths
+  return libformatpaths
 end
 local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do 
-  local format=suffixes[i]
-  local resolved=resolvers.findfile(name,format) or ""
-  if trace then
-   report("%s format, identifying %a using format %a",what,name,format)
+  local trace=helpers.trace
+  local report=helpers.report
+  for i=1,#suffixes do 
+    local format=suffixes[i]
+    local resolved=resolvers.findfile(name,format) or ""
+    if trace then
+      report("%s format, identifying %a using format %a",what,name,format)
+    end
+    if resolved~="" then
+      if trace then
+        report("%s format, %a found on %a",what,name,resolved)
+      end
+      if islib then
+        return loadedaslib(resolved,rawname)
+      else
+        return loadfile(resolved)
+      end
+    end
   end
-  if resolved~="" then
-   if trace then
-    report("%s format, %a found on %a",what,name,resolved)
-   end
-   if islib then
-    return loadedaslib(resolved,rawname)
-   else
-    return loadfile(resolved)
-   end
-  end
- end
 end
 helpers.loadedbyformat=loadedbyformat
 methods["lua variable format"]=function(name)
- if helpers.trace then
-  helpers.report("%s format, checking %s paths","lua",#getluaformatpaths()) 
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+  if helpers.trace then
+    helpers.report("%s format, checking %s paths","lua",#getluaformatpaths()) 
+  end
+  return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
 end
 methods["lib variable format"]=function(name)
- if helpers.trace then
-  helpers.report("%s format, checking %s paths","lib",#getlibformatpaths()) 
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+  if helpers.trace then
+    helpers.report("%s format, checking %s paths","lib",#getlibformatpaths()) 
+  end
+  return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
 end
 resolvers.loadlualib=require 
 
@@ -24118,64 +20540,64 @@
 
 package.loaded["data-aux"] = package.loaded["data-aux"] or true
 
--- original size: 2452, stripped down to: 1877
+-- original size: 2438, stripped down to: 2003
 
 if not modules then modules={} end modules ['data-aux']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local find=string.find
 local type,next=type,next
-local trace_locating=false  trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
 local resolvers=resolvers
 local report_scripts=logs.reporter("resolvers","scripts")
 function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
- if trace_locating then
-  report_scripts("to be replaced old script %a",oldscript)
- end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+  local scriptpath="context/lua"
+  newname=file.addsuffix(newname,"lua")
+  local oldscript=resolvers.cleanpath(oldname)
   if trace_locating then
-   report_scripts("unable to locate new script")
+    report_scripts("to be replaced old script %a",oldscript)
   end
- else
-  for i=1,#newscripts do
-   local newscript=resolvers.cleanpath(newscripts[i])
-   if trace_locating then
-    report_scripts("checking new script %a",newscript)
-   end
-   if oldscript==newscript then
+  local newscripts=resolvers.findfiles(newname) or {}
+  if #newscripts==0 then
     if trace_locating then
-     report_scripts("old and new script are the same")
+      report_scripts("unable to locate new script")
     end
-   elseif not find(newscript,scriptpath,1,true) then
-    if trace_locating then
-     report_scripts("new script should come from %a",scriptpath)
+  else
+    for i=1,#newscripts do
+      local newscript=resolvers.cleanpath(newscripts[i])
+      if trace_locating then
+        report_scripts("checking new script %a",newscript)
+      end
+      if oldscript==newscript then
+        if trace_locating then
+          report_scripts("old and new script are the same")
+        end
+      elseif not find(newscript,scriptpath,1,true) then
+        if trace_locating then
+          report_scripts("new script should come from %a",scriptpath)
+        end
+      elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+        if trace_locating then
+          report_scripts("invalid new script name")
+        end
+      else
+        local newdata=io.loaddata(newscript)
+        if newdata then
+          if trace_locating then
+            report_scripts("old script content replaced by new content")
+          end
+          io.savedata(oldscript,newdata)
+          break
+        elseif trace_locating then
+          report_scripts("unable to load new script")
+        end
+      end
     end
-   elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
-    if trace_locating then
-     report_scripts("invalid new script name")
-    end
-   else
-    local newdata=io.loaddata(newscript)
-    if newdata then
-     if trace_locating then
-      report_scripts("old script content replaced by new content: %s",oldscript)
-     end
-     io.savedata(oldscript,newdata)
-     break
-    elseif trace_locating then
-     report_scripts("unable to load new script")
-    end
-   end
   end
- end
 end
 
 
@@ -24185,53 +20607,53 @@
 
 package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
 
--- original size: 2601, stripped down to: 1549
+-- original size: 2601, stripped down to: 1627
 
 if not modules then modules={} end modules ['data-tmf']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local resolvers=resolvers
 local report_tds=logs.reporter("resolvers","tds")
 function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
-  local getenv,setenv=resolvers.getenv,resolvers.setenv
-  local texos="texmf-"..os.platform
-  local oldroot=environment.texroot
-  local newroot=file.collapsepath(tree)
-  local newtree=file.join(newroot,texos)
-  local newpath=file.join(newtree,"bin")
-  if not lfs.isdir(newtree) then
-   report_tds("no %a under tree %a",texos,tree)
-   os.exit()
+  if type(tree)=="string" and tree~="" then
+    local getenv,setenv=resolvers.getenv,resolvers.setenv
+    local texos="texmf-"..os.platform
+    local oldroot=environment.texroot
+    local newroot=file.collapsepath(tree)
+    local newtree=file.join(newroot,texos)
+    local newpath=file.join(newtree,"bin")
+    if not lfs.isdir(newtree) then
+      report_tds("no %a under tree %a",texos,tree)
+      os.exit()
+    end
+    if not lfs.isdir(newpath) then
+      report_tds("no '%s/bin' under tree %a",texos,tree)
+      os.exit()
+    end
+    local texmfos=newtree
+    environment.texroot=newroot
+    environment.texos=texos
+    environment.texmfos=texmfos
+    if resolve then
+      resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+    end
+    setenv('SELFAUTOPARENT',newroot)
+    setenv('SELFAUTODIR',newtree)
+    setenv('SELFAUTOLOC',newpath)
+    setenv('TEXROOT',newroot)
+    setenv('TEXOS',texos)
+    setenv('TEXMFOS',texmfos)
+    setenv('TEXMFCNF',resolvers.luacnfspec,true) 
+    setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+    report_tds("changing from root %a to %a",oldroot,newroot)
+    report_tds("prepending %a to PATH",newpath)
+    report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+    report_tds()
   end
-  if not lfs.isdir(newpath) then
-   report_tds("no '%s/bin' under tree %a",texos,tree)
-   os.exit()
-  end
-  local texmfos=newtree
-  environment.texroot=newroot
-  environment.texos=texos
-  environment.texmfos=texmfos
-  if resolve then
-   resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
-  end
-  setenv('SELFAUTOPARENT',newroot)
-  setenv('SELFAUTODIR',newtree)
-  setenv('SELFAUTOLOC',newpath)
-  setenv('TEXROOT',newroot)
-  setenv('TEXOS',texos)
-  setenv('TEXMFOS',texmfos)
-  setenv('TEXMFCNF',resolvers.luacnfspec,true) 
-  setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
-  report_tds("changing from root %a to %a",oldroot,newroot)
-  report_tds("prepending %a to PATH",newpath)
-  report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
-  report_tds()
- end
 end
 
 
@@ -24241,14 +20663,14 @@
 
 package.loaded["data-lst"] = package.loaded["data-lst"] or true
 
--- original size: 1823, stripped down to: 1542
+-- original size: 1823, stripped down to: 1591
 
 if not modules then modules={} end modules ['data-lst']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local type=type
 local concat,sortedhash=table.concat,table.sortedhash
@@ -24259,37 +20681,37 @@
 local report_lists=logs.reporter("resolvers","lists")
 local report_resolved=logs.reporter("system","resolved")
 local function tabstr(str)
- if type(str)=='table' then
-  return concat(str," | ")
- else
-  return str
- end
+  if type(str)=='table' then
+    return concat(str," | ")
+  else
+    return str
+  end
 end
 function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
-  report_lists(key)
-  report_lists("  env: %s",tabstr(value.environment or "unset"))
-  report_lists("  var: %s",tabstr(value.variable or "unset"))
-  report_lists("  exp: %s",tabstr(value.expansion   or "unset"))
-  report_lists("  res: %s",tabstr(value.resolved or "unset"))
- end
+  local result=resolvers.knownvariables(pattern)
+  for key,value in sortedhash(result) do
+    report_lists(key)
+    report_lists("  env: %s",tabstr(value.environment or "unset"))
+    report_lists("  var: %s",tabstr(value.variable  or "unset"))
+    report_lists("  exp: %s",tabstr(value.expansion  or "unset"))
+    report_lists("  res: %s",tabstr(value.resolved  or "unset"))
+  end
 end
 function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
-  report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
-  local li=resolveprefix(list[i])
-  if lfs.isdir(li) then
-   report_resolved("path - %s",li)
-  else
-   report_resolved("path + %s",li)
+  local configurations=resolvers.configurationfiles()
+  for i=1,#configurations do
+    report_resolved("file : %s",resolveprefix(configurations[i]))
   end
- end
+  report_resolved("")
+  local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+  for i=1,#list do
+    local li=resolveprefix(list[i])
+    if lfs.isdir(li) then
+      report_resolved("path - %s",li)
+    else
+      report_resolved("path + %s",li)
+    end
+  end
 end
 
 
@@ -24299,14 +20721,14 @@
 
 package.loaded["util-lib"] = package.loaded["util-lib"] or true
 
--- original size: 16094, stripped down to: 8443
+-- original size: 14943, stripped down to: 8305
 
 if not modules then modules={} end modules ['util-lib']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+  version=1.001,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files",
 }
 local type=type
 local next=next
@@ -24326,291 +20748,256 @@
 local isfile=lfs.isfile
 local done=false
 local function locate(required,version,trace,report,action)
- if type(required)~="string" then
-  report("provide a proper library name")
-  return
- end
- if trace then
-  report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/") 
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
-  if isfile(addsuffix(required,os.libsuffix)) then
-   if trace then
-    report("qualified name %a found",required)
-   end
-   found_library=required
-  else
-   if trace then
-    report("qualified name %a not found",required)
-   end
+  if type(required)~="string" then
+    report("provide a proper library name")
+    return
   end
- else
-  local required_name=required_base.."."..os.libsuffix
-  local version=type(version)=="string" and version~="" and version or false
-  local engine="luatex"
-  if trace and not done then
-   local list=expandpaths("lib") 
-   for i=1,#list do
-      report("tds path %i: %s",i,list[i])
-   end
+  if trace then
+    report("requiring library %a with version %a",required,version or "any")
   end
-  local function found(locate,asked_library,how,...)
-   if trace then
-    report("checking %s: %a",how,asked_library)
-   end
-   return locate(asked_library,...)
-  end
-  local function check(locate,...)
-   local found=nil
-   if version then
-    local asked_library=joinfile(required_path,version,required_name)
-    if trace then
-     report("checking %s: %a","with version",asked_library)
+  local found_library=nil
+  local required_full=gsub(required,"%.","/") 
+  local required_path=pathpart(required_full)
+  local required_base=nameonly(required_full)
+  if qualifiedpath(required) then
+    if isfile(addsuffix(required,os.libsuffix)) then
+      if trace then
+        report("qualified name %a found",required)
+      end
+      found_library=required
+    else
+      if trace then
+        report("qualified name %a not found",required)
+      end
     end
-    found=locate(asked_library,...)
-   end
-   if not found or found=="" then
-    local asked_library=joinfile(required_path,required_name)
-    if trace then
-     report("checking %s: %a","with version",asked_library)
+  else
+    local required_name=required_base.."."..os.libsuffix
+    local version=type(version)=="string" and version~="" and version or false
+    local engine="luatex"
+    if trace and not done then
+      local list=expandpaths("lib") 
+      for i=1,#list do
+        report("tds path %i: %s",i,list[i])
+      end
     end
-    found=locate(asked_library,...)
-   end
-   return found and found~="" and found or false
-  end
-  local function attempt(checkpattern)
-   if trace then
-    report("checking tds lib paths strictly")
-   end
-   local found=findfile and check(findfile,"lib")
-   if found and (not checkpattern or find(found,checkpattern)) then
-    return found
-   end
-   if trace then
-    report("checking tds lib paths with wildcard")
-   end
-   local asked_library=joinfile(required_path,".*",required_name)
-   if trace then
-    report("checking %s: %a","latest version",asked_library)
-   end
-   local list=findfiles(asked_library,"lib",true)
-   if list and #list>0 then
-    sort(list)
-    local found=list[#list]
-    if found and (not checkpattern or find(found,checkpattern)) then
-     return found
+    local function found(locate,asked_library,how,...)
+      if trace then
+        report("checking %s: %a",how,asked_library)
+      end
+      return locate(asked_library,...)
     end
-   end
-   if trace then
-    report("checking lib paths")
-   end
-   package.extralibpath(environment.ownpath)
-   local paths=package.libpaths()
-   local pattern="/[^/]+%."..os.libsuffix.."$"
-   for i=1,#paths do
-    required_path=gsub(paths[i],pattern,"")
-    local found=check(lfs.isfound)
-    if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
-     return found
+    local function check(locate,...)
+      local found=nil
+      if version then
+        local asked_library=joinfile(required_path,version,required_name)
+        if trace then
+          report("checking %s: %a","with version",asked_library)
+        end
+        found=locate(asked_library,...)
+      end
+      if not found or found=="" then
+        local asked_library=joinfile(required_path,required_name)
+        if trace then
+          report("checking %s: %a","with version",asked_library)
+        end
+        found=locate(asked_library,...)
+      end
+      return found and found~="" and found or false
     end
-   end
-   return false
+    local function attempt(checkpattern)
+      if trace then
+        report("checking tds lib paths strictly")
+      end
+      local found=findfile and check(findfile,"lib")
+      if found and (not checkpattern or find(found,checkpattern)) then
+        return found
+      end
+      if trace then
+        report("checking tds lib paths with wildcard")
+      end
+      local asked_library=joinfile(required_path,".*",required_name)
+      if trace then
+        report("checking %s: %a","latest version",asked_library)
+      end
+      local list=findfiles(asked_library,"lib",true)
+      if list and #list>0 then
+        sort(list)
+        local found=list[#list]
+        if found and (not checkpattern or find(found,checkpattern)) then
+          return found
+        end
+      end
+      if trace then
+        report("checking lib paths")
+      end
+      package.extralibpath(environment.ownpath)
+      local paths=package.libpaths()
+      local pattern="/[^/]+%."..os.libsuffix.."$"
+      for i=1,#paths do
+        required_path=gsub(paths[i],pattern,"")
+        local found=check(lfs.isfound)
+        if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+          return found
+        end
+      end
+      return false
+    end
+    if engine then
+      if trace then
+        report("attemp 1, engine %a",engine)
+      end
+      found_library=attempt("/"..engine.."/")
+      if not found_library then
+        if trace then
+          report("attemp 2, no engine",asked_library)
+        end
+        found_library=attempt()
+      end
+    else
+      found_library=attempt()
+    end
   end
-  if engine then
-   if trace then
-    report("attemp 1, engine %a",engine)
-   end
-   found_library=attempt("/"..engine.."/")
-   if not found_library then
+  if not found_library then
     if trace then
-     report("attemp 2, no engine",asked_library)
+      report("not found: %a",required)
     end
-    found_library=attempt()
-   end
+    library=false
   else
-   found_library=attempt()
+    if trace then
+      report("found: %a",found_library)
+    end
+    local result,message=action(found_library,required_base)
+    if result then
+      library=result
+    else
+      library=false
+      report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+    end
   end
- end
- if not found_library then
   if trace then
-   report("not found: %a",required)
+    if not library then
+      report("unknown library: %a",required)
+    else
+      report("stored library: %a",required)
+    end
   end
-  library=false
- else
-  if trace then
-   report("found: %a",found_library)
-  end
-  local result,message=action(found_library,required_base)
-  if result then
-   library=result
-  else
-   library=false
-   report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
-  end
- end
- if trace then
-  if not library then
-   report("unknown library: %a",required)
-  else
-   report("stored library: %a",required)
-  end
- end
- return library or nil
+  return library
 end
 do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
-  local library=loadedlibs[library]
-  if library==nil then
-   local trace_swiglib=trace_swiglib or package.helpers.trace
-   library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
-    pushdir(pathpart(name))
-    local opener="luaopen_"..base
-    if trace_swiglib then
-     report_swiglib("opening: %a with %a",name,opener)
+  local report_swiglib=logs.reporter("swiglib")
+  local trace_swiglib=false
+  local savedrequire=require
+  local loadedlibs={}
+  local loadlib=package.loadlib
+  local pushdir=dir.push
+  local popdir=dir.pop
+  trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+  function requireswiglib(required,version)
+    local library=loadedlibs[library]
+    if library==nil then
+      local trace_swiglib=trace_swiglib or package.helpers.trace
+      library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+        pushdir(pathpart(name))
+        local opener="luaopen_"..base
+        if trace_swiglib then
+          report_swiglib("opening: %a with %a",name,opener)
+        end
+        local library,message=loadlib(name,opener)
+        local libtype=type(library)
+        if libtype=="function" then
+          library=library()
+        else
+          report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+          library=false
+        end
+        popdir()
+        return library
+      end)
+      loadedlibs[required]=library or false
     end
-    local library,message=loadlib(name,opener)
-    local libtype=type(library)
-    if libtype=="function" then
-     library=library()
+    return library
+  end
+  function require(name,version)
+    if find(name,"^swiglib%.") then
+      return requireswiglib(name,version)
     else
-     report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
-     library=false
+      return savedrequire(name)
     end
-    popdir()
+  end
+  local swiglibs={}
+  local initializer="core"
+  function swiglib(name,version)
+    local library=swiglibs[name]
+    if not library then
+      statistics.starttiming(swiglibs)
+      if trace_swiglib then
+        report_swiglib("loading %a",name)
+      end
+      if not find(name,"%."..initializer.."$") then
+        fullname="swiglib."..name.."."..initializer
+      else
+        fullname="swiglib."..name
+      end
+      library=requireswiglib(fullname,version)
+      swiglibs[name]=library
+      statistics.stoptiming(swiglibs)
+    end
     return library
-   end)
-   loadedlibs[required]=library or false
   end
-  return library
- end
- function require(name,version)
-  if find(name,"^swiglib%.") then
-   return requireswiglib(name,version)
-  else
-   return savedrequire(name)
-  end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
-  local library=swiglibs[name]
-  if not library then
-   statistics.starttiming(swiglibs)
-   if trace_swiglib then
-    report_swiglib("loading %a",name)
-   end
-   if not find(name,"%."..initializer.."$") then
-    fullname="swiglib."..name.."."..initializer
-   else
-    fullname="swiglib."..name
-   end
-   library=requireswiglib(fullname,version)
-   swiglibs[name]=library
-   statistics.stoptiming(swiglibs)
-  end
-  return library
- end
- statistics.register("used swiglibs",function()
-  if next(swiglibs) then
-   return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
-  end
- end)
+  statistics.register("used swiglibs",function()
+    if next(swiglibs) then
+      return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+    end
+  end)
 end
 if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
-  name=removesuffix(name)
-  local l=loaded[name]
-  if l==nil then
-   local state,library=pcall(savedffiload,name)
-   if type(library)=="userdata" then
-    l=library
-   elseif type(state)=="userdata" then
-    l=state
-   else
-    l=false
-   end
-   loaded[name]=l
-  elseif trace_ffilib then
-   report_ffilib("reusing already loaded %a",name)
+  local report_ffilib=logs.reporter("ffilib")
+  local trace_ffilib=false
+  local savedffiload=ffi.load
+  trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+  local loaded={}
+  local function locateindeed(name)
+    name=removesuffix(name)
+    local l=loaded[name]
+    if l==nil then
+      local message,library=pcall(savedffiload,name)
+      if type(message)=="userdata" then
+        l=message
+      elseif type(library)=="userdata" then
+        l=library
+      else
+        l=false
+      end
+      loaded[name]=l
+    elseif trace_ffilib then
+      report_ffilib("reusing already loaded %a",name)
+    end
+    return l
   end
-  return l
- end
- local function getlist(required)
-  local list=directives.value("system.librarynames" )
-  if type(list)=="table" then
-   list=list[required]
-   if type(list)=="table" then
-    if trace then
-     report("using lookup list for library %a: % | t",required,list)
+  function ffilib(name,version)
+    name=removesuffix(name)
+    local l=loaded[name]
+    if l~=nil then
+      if trace_ffilib then
+        report_ffilib("reusing already loaded %a",name)
+      end
+      return l
+    elseif version=="system" then
+      return locateindeed(name)
+    else
+      return locate(name,version,trace_ffilib,report_ffilib,locateindeed)
     end
-    return list
-   end
   end
-  return { required }
- end
- function ffilib(name,version)
-  name=removesuffix(name)
-  local l=loaded[name]
-  if l~=nil then
-   if trace_ffilib then
-    report_ffilib("reusing already loaded %a",name)
-   end
-   return l
-  end
-  local list=getlist(name)
-  if version=="system" then
-   for i=1,#list do
-    local library=locateindeed(list[i])
+  function ffi.load(name)
+    local library=ffilib(name)
     if type(library)=="userdata" then
-     return library
+      return library
     end
-   end
-  else
-   for i=1,#list do
-    local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
-    if type(library)=="userdata" then
-     return library
+    if trace_ffilib then
+      report_ffilib("trying to load %a using normal loader",name)
     end
-   end
+    return savedffiload(name)
   end
- end
- function ffi.load(name)
-  local list=getlist(name)
-  for i=1,#list do
-   local library=ffilib(list[i])
-   if type(library)=="userdata" then
-    return library
-   end
-  end
-  if trace_ffilib then
-   report_ffilib("trying to load %a using normal loader",name)
-  end
-  for i=1,#list do
-   local state,library=pcall(savedffiload,list[i])
-   if type(library)=="userdata" then
-    return library
-   elseif type(state)=="userdata" then
-    return library
-   end
-  end
- end
 end
 
 
@@ -24620,13 +21007,13 @@
 
 package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
 
--- original size: 5703, stripped down to: 2321
+-- original size: 5703, stripped down to: 2507
 
 if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local gmatch,match=string.gmatch,string.match
 local type=type
@@ -24639,81 +21026,81 @@
 states.tag=states.tag   or ""
 states.filename=states.filename or ""
 function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
-  "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+  tag=tag or states.tag
+  filename=file.addsuffix(filename or states.filename,'lus')
+  io.savedata(filename,
+    "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+  )
 end
 function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+  states.filename=filename
+  states.tag=tag or "whatever"
+  states.filename=file.addsuffix(states.filename,'lus')
+  data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
 end
 local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
-  if type(d)=="table" then
-   local dkey,hkey=key,key
-   local pre,post=match(key,"(.+)%.([^%.]+)$")
-   if pre and post then
-    for k in gmatch(pre,"[^%.]+") do
-     local dk=d[k]
-     if not dk then
-      dk={}
-      d[k]=dk
-     elseif type(dk)=="string" then
-      break
-     end
-     d=dk
+  local d,h=data[tag],hash[tag]
+  if d then
+    if type(d)=="table" then
+      local dkey,hkey=key,key
+      local pre,post=match(key,"(.+)%.([^%.]+)$")
+      if pre and post then
+        for k in gmatch(pre,"[^%.]+") do
+          local dk=d[k]
+          if not dk then
+            dk={}
+            d[k]=dk
+          elseif type(dk)=="string" then
+            break
+          end
+          d=dk
+        end
+        dkey,hkey=post,key
+      end
+      if value==nil then
+        value=default
+      elseif value==false then
+      elseif persistent then
+        value=value or d[dkey] or default
+      else
+        value=value or default
+      end
+      d[dkey],h[hkey]=value,value
+    elseif type(d)=="string" then
+      data[tag],hash[tag]=value,value
     end
-    dkey,hkey=post,key
-   end
-   if value==nil then
-    value=default
-   elseif value==false then
-   elseif persistent then
-    value=value or d[dkey] or default
-   else
-    value=value or default
-   end
-   d[dkey],h[hkey]=value,value
-  elseif type(d)=="string" then
-   data[tag],hash[tag]=value,value
   end
- end
 end
 local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
-  return h[key]
- else
-  local d=data[tag]
-  if d then
-   for k in gmatch(key,"[^%.]+") do
-    local dk=d[k]
-    if dk~=nil then
-     d=dk
-    else
-     return default
+  local h=hash[tag]
+  if h and h[key] then
+    return h[key]
+  else
+    local d=data[tag]
+    if d then
+      for k in gmatch(key,"[^%.]+") do
+        local dk=d[k]
+        if dk~=nil then
+          d=dk
+        else
+          return default
+        end
+      end
+      if d==false then
+        return false
+      else
+        return d or default
+      end
     end
-   end
-   if d==false then
-    return false
-   else
-    return d or default
-   end
   end
- end
 end
 states.set_by_tag=set_by_tag
 states.get_by_tag=get_by_tag
 function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+  set_by_tag(states.tag,key,value,default,persistent)
 end
 function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+  return get_by_tag(states.tag,key,default)
 end
 
 
@@ -24723,14 +21110,14 @@
 
 package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
 
--- original size: 9418, stripped down to: 7087
+-- original size: 9268, stripped down to: 7401
 
 if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+  version=1.001,
+  comment="companion to mtxrun",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
 }
 local format=string.format
 local concat=table.concat
@@ -24738,232 +21125,229 @@
 local luasuffixes=utilities.lua.suffixes
 local report_format=logs.reporter("resolvers","formats")
 local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
-  flags[#flags+1]="--interaction=batchmode"
- end
- return concat(flags," ")
+  local arguments=environment.arguments
+  local flags={}
+  if arguments.silent then
+    flags[#flags+1]="--interaction=batchmode"
+  end
+  if arguments.jit then
+    flags[#flags+1]="--jiton"
+  end
+  return concat(flags," ")
 end
 local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
-  flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
-  flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
-  flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
-  flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
-  flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
-  flags[#flags+1]="--c:ansi"
- end
- if arguments.strip then
-  flags[#flags+1]="--c:strip"
- end
- if arguments.lmtx then
-  flags[#flags+1]="--c:lmtx"
- end
- return concat(flags," ")
+  local arguments=environment.arguments
+  local trackers=arguments.trackers
+  local directives=arguments.directives
+  local flags={}
+  if trackers and trackers~="" then
+    flags[#flags+1]="--c:trackers="..quoted(trackers)
+  end
+  if directives and directives~="" then
+    flags[#flags+1]="--c:directives="..quoted(directives)
+  end
+  if arguments.silent then
+    flags[#flags+1]="--c:silent"
+  end
+  if arguments.errors then
+    flags[#flags+1]="--c:errors"
+  end
+  if arguments.jit then
+    flags[#flags+1]="--c:jiton"
+  end
+  if arguments.ansi then
+    flags[#flags+1]="--c:ansi"
+  end
+  return concat(flags," ")
 end
 local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
 local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+  primaryflags="string",
+  secondaryflags="string",
+  luafile="readable",
+  texfile="readable",
+  redirect="string",
+  dump="string",
 }
 local runners={
- luatex=sandbox.registerrunner {
-  name="make luatex format",
-  program="luatex",
-  template=template,
-  checkers=checkers,
-  reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
-  name="make luajittex format",
-  program="luajittex",
-  template=template,
-  checkers=checkers,
-  reporter=report_format,
- },
+  luatex=sandbox.registerrunner {
+    name="make luatex format",
+    program="luatex",
+    template=template,
+    checkers=checkers,
+    reporter=report_format,
+  },
+  luajittex=sandbox.registerrunner {
+    name="make luajittex format",
+    program="luajittex",
+    template=template,
+    checkers=checkers,
+    reporter=report_format,
+  },
 }
 function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or "" 
- if path~="" then
-  lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
-  texsourcename=file.addsuffix(name,"tex")
-  fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
-  report_format("no tex source file with name %a (mkiv or tex)",name)
-  lfs.chdir(olddir)
-  return
- else
-  report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
-  specificationname=file.join(texsourcepath,"context.lus")
-  fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
-  report_format("unknown stub specification %a",specificationname)
-  lfs.chdir(olddir)
-  return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
-  usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
-  report_format("using stub specification %a",fullspecificationname)
-  local texbasename=file.basename(name)
-  local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
-  local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
-  report_format("creating initialization file %a",luastubname)
-  utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
-  if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
-   report_format("using compiled initialization file %a",lucstubname)
-   usedluastub=lucstubname
+  local engine=environment.ownmain or "luatex"
+  local silent=environment.arguments.silent
+  local errors=environment.arguments.errors
+  local olddir=dir.current()
+  local path=caches.getwritablepath("formats",engine) or "" 
+  if path~="" then
+    lfs.chdir(path)
+  end
+  report_format("using format path %a",dir.current())
+  local texsourcename=file.addsuffix(name,"mkiv")
+  local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+  if fulltexsourcename=="" then
+    texsourcename=file.addsuffix(name,"tex")
+    fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+  end
+  if fulltexsourcename=="" then
+    report_format("no tex source file with name %a (mkiv or tex)",name)
+    lfs.chdir(olddir)
+    return
   else
-   report_format("using uncompiled initialization file %a",luastubname)
-   usedluastub=luastubname
+    report_format("using tex source file %a",fulltexsourcename)
   end
- else
-  report_format("invalid stub specification %a",fullspecificationname)
-  lfs.chdir(olddir)
-  return
- end
- local specification={
-  primaryflags=primaryflags(),
-  secondaryflags=secondaryflags(),
-  luafile=quoted(usedluastub),
-  texfile=quoted(fulltexsourcename),
-  dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
-  report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
-  statistics.starttiming()
-  specification.redirect="> temp.log"
-  local result=runner(specification)
-  local runtime=statistics.stoptiming()
-  if result~=0 then
-   print(format("%s silent make > fatal error when making format %q",engine,name)) 
+  local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+  local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+  local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+  if fullspecificationname=="" then
+    specificationname=file.join(texsourcepath,"context.lus")
+    fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+  end
+  if fullspecificationname=="" then
+    report_format("unknown stub specification %a",specificationname)
+    lfs.chdir(olddir)
+    return
+  end
+  local specificationpath=file.dirname(fullspecificationname)
+  local usedluastub=nil
+  local usedlualibs=dofile(fullspecificationname)
+  if type(usedlualibs)=="string" then
+    usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+  elseif type(usedlualibs)=="table" then
+    report_format("using stub specification %a",fullspecificationname)
+    local texbasename=file.basename(name)
+    local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+    local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+    report_format("creating initialization file %a",luastubname)
+    utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+    if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+      report_format("using compiled initialization file %a",lucstubname)
+      usedluastub=lucstubname
+    else
+      report_format("using uncompiled initialization file %a",luastubname)
+      usedluastub=luastubname
+    end
   else
-   print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime)) 
+    report_format("invalid stub specification %a",fullspecificationname)
+    lfs.chdir(olddir)
+    return
   end
-  os.remove("temp.log")
- else
-  runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
-  for i=1,#mp do
-   local name=mp[i]
-   report_format("removing related mplib format %a",file.basename(name))
-   os.remove(name)
+  local specification={
+    primaryflags=primaryflags(),
+    secondaryflags=secondaryflags(),
+    luafile=quoted(usedluastub),
+    texfile=quoted(fulltexsourcename),
+    dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+  }
+  local runner=runners[engine]
+  if not runner then
+    report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+  elseif silent then
+    statistics.starttiming()
+    specification.redirect="> temp.log"
+    local result=runner(specification)
+    local runtime=statistics.stoptiming()
+    if result~=0 then
+      print(format("%s silent make > fatal error when making format %q",engine,name)) 
+    else
+      print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime)) 
+    end
+    os.remove("temp.log")
+  else
+    runner(specification)
   end
- end
- lfs.chdir(olddir)
+  local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+  local mp=dir.glob(pattern)
+  if mp then
+    for i=1,#mp do
+      local name=mp[i]
+      report_format("removing related mplib format %a",file.basename(name))
+      os.remove(name)
+    end
+  end
+  lfs.chdir(olddir)
 end
 local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
 local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+  flags="string",
+  more="string",
+  fmtfile="readable",
+  luafile="readable",
+  texfile="readable",
 }
 local runners={
- luatex=sandbox.registerrunner {
-  name="run luatex format",
-  program="luatex",
-  template=template,
-  checkers=checkers,
-  reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
-  name="run luajittex format",
-  program="luajittex",
-  template=template,
-  checkers=checkers,
-  reporter=report_format,
- },
+  luatex=sandbox.registerrunner {
+    name="run luatex format",
+    program="luatex",
+    template=template,
+    checkers=checkers,
+    reporter=report_format,
+  },
+  luajittex=sandbox.registerrunner {
+    name="run luajittex format",
+    program="luajittex",
+    template=template,
+    checkers=checkers,
+    reporter=report_format,
+  },
 }
 function environment.run_format(name,data,more)
- if name and name~="" then
-  local engine=environment.ownmain or "luatex"
-  local barename=file.removesuffix(name)
-  local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
-  if fmtname=="" then
-   fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
-  end
-  fmtname=resolvers.cleanpath(fmtname)
-  if fmtname=="" then
-   report_format("no format with name %a",name)
-  else
-   local barename=file.removesuffix(name) 
-   local luaname=file.addsuffix(barename,"luc")
-   if not lfs.isfile(luaname) then
-    luaname=file.addsuffix(barename,"lua")
-   end
-   if not lfs.isfile(luaname) then
-    report_format("using format name %a",fmtname)
-    report_format("no luc/lua file with name %a",barename)
-   else
-    local runner=runners[engine]
-    if not runner then
-     report_format("format %a cannot be run, no runner available for engine %a",name,engine)
+  if name and name~="" then
+    local engine=environment.ownmain or "luatex"
+    local barename=file.removesuffix(name)
+    local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+    if fmtname=="" then
+      fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+    end
+    fmtname=resolvers.cleanpath(fmtname)
+    if fmtname=="" then
+      report_format("no format with name %a",name)
     else
-     runner {
-      flags=primaryflags(),
-      fmtfile=quoted(barename),
-      luafile=quoted(luaname),
-      texfile=quoted(data),
-      more=more,
-     }
+      local barename=file.removesuffix(name) 
+      local luaname=file.addsuffix(barename,"luc")
+      if not lfs.isfile(luaname) then
+        luaname=file.addsuffix(barename,"lua")
+      end
+      if not lfs.isfile(luaname) then
+        report_format("using format name %a",fmtname)
+        report_format("no luc/lua file with name %a",barename)
+      else
+        local runner=runners[engine]
+        if not runner then
+          report_format("format %a cannot be run, no runner available for engine %a",name,engine)
+        else
+          runner {
+            flags=primaryflags(),
+            fmtfile=quoted(barename),
+            luafile=quoted(luaname),
+            texfile=quoted(data),
+            more=more,
+          }
+        end
+      end
     end
-   end
   end
- end
 end
 
 
 end -- of closure
 
--- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
+-- used libraries    : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
 -- skipped libraries : -
--- original bytes    : 994864
--- stripped bytes    : 395007
+-- original bytes    : 877962
+-- stripped bytes    : 317771
 
 -- end library merge
 
@@ -24986,7 +21370,6 @@
 
 local ownlibs = { -- order can be made better
 
-    'l-bit32.lua',
     'l-lua.lua',
     'l-macro.lua',
     'l-sandbox.lua',
@@ -25002,7 +21385,6 @@
     'l-file.lua',
     'l-gzip.lua',
     'l-md5.lua',
-    'l-sha.lua',
     'l-url.lua',
     'l-dir.lua',
     'l-boolean.lua',
@@ -25017,19 +21399,6 @@
     'util-prs.lua',
     'util-fmt.lua',
 
-    'util-soc-imp-reset.lua',
-    'util-soc-imp-socket.lua',
-    'util-soc-imp-copas.lua',
-    'util-soc-imp-ltn12.lua',
- -- 'util-soc-imp-mbox.lua',
-    'util-soc-imp-mime.lua',
-    'util-soc-imp-url.lua',
-    'util-soc-imp-headers.lua',
-    'util-soc-imp-tp.lua',
-    'util-soc-imp-http.lua',
-    'util-soc-imp-ftp.lua',
-    'util-soc-imp-smtp.lua',
-
     'trac-set.lua',
     'trac-log.lua',
     'trac-inf.lua', -- was before trac-set
@@ -25232,7 +21601,9 @@
     <flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
    </subcategory>
    <subcategory>
+    <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
     <flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
+    <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
     <flag name="path" value="runpath"><short>go to given path before execution</short></flag>
     <flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
     <flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -25252,7 +21623,7 @@
    </subcategory>
    <subcategory>
     <flag name="edit"><short>launch editor with found file</short></flag>
-    <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
+    <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
    </subcategory>
    <subcategory>
     <flag name="timedrun"><short>run a script and time its run</short></flag>
@@ -25651,9 +22022,9 @@
 end
 
 function runners.launch_file(filename)
+    trackers.enable("resolvers.locating")
     local allresults = environment.arguments["all"]
-    local pattern    = environment.arguments["pattern"]
-    local listonly   = environment.arguments["list"]
+    local pattern = environment.arguments["pattern"]
     if not pattern or pattern == "" then
         pattern = filename
     end
@@ -25668,33 +22039,15 @@
             t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults)
         end
         if t and #t > 0 then
-            for i=1,#t do
-                local name = t[i]
-                if listonly then
-                    report("% 3i:  %-30s %s",i,file.basename(name),file.dirname(name))
-                else
-                    report("launching: %s",name)
-                    resolvers.launch(name)
-                    if not allresults then
-                        break
-                    end
+            if allresults then
+                for _, v in pairs(t) do
+                    report("launching %s", v)
+                    resolvers.launch(v)
                 end
+            else
+                report("launching %s", t[1])
+                resolvers.launch(t[1])
             end
-            if listonly then
-                io.write("\n")
-                io.write("\n[select number]\n\n>> ")
-                local answer = tonumber(io.read())
-                if answer then
-                    io.write("\n")
-                    local name = t[answer]
-                    if name then
-                        report("launching: %s",name)
-                        resolvers.launch(name)
-                    else
-                        report("invalid number")
-                    end
-                end
-            end
         else
             report("no match for %s", pattern)
         end
@@ -25813,9 +22166,12 @@
             dofile(fullname)
             local savename = environment.arguments['save']
             if savename then
-                if type(savename) ~= "string" then savename = file.basename(fullname) end
-                savename = file.replacesuffix(savename,"cfg")
-                runners.save_script_session(savename,save_list)
+                local save_list = runners.save_list
+                if save_list and next(save_list) then
+                    if type(savename) ~= "string" then savename = file.basename(fullname) end
+                    savename = file.replacesuffix(savename,"cfg")
+                    runners.save_script_session(savename,save_list)
+                end
             end
             return true
         end
@@ -25832,22 +22188,22 @@
                     local scriptbase = match(scriptname,".*mtx%-([^%-]-)%.lua")
                     if scriptbase then
                         local data = io.loaddata(scriptname)
-                        local application = match(data,"local application.-=.-(%{.-%})")
-                        if application then
-                            application = loadstring("return " .. application)
-                            if application then
-                                application = application()
-                                local banner = application.banner
-                                if banner then
-                                    local description, version = match(banner,"^(.-) ([%d.]+)$")
-                                    if description then
-                                        valid[#valid+1] = { scriptbase, version, description }
-                                    else
-                                        valid[#valid+1] = { scriptbase, "", banner }
-                                    end
-                                end
-                            end
-                        end
+local application = match(data,"local application.-=.-(%{.-%})")
+if application then
+    application = loadstring("return " .. application)
+    if application then
+        application = application()
+        local banner = application.banner
+        if banner then
+            local description, version = match(banner,"^(.-) ([%d.]+)$")
+            if description then
+                valid[#valid+1] = { scriptbase, version, description }
+            else
+                valid[#valid+1] = { scriptbase, "", banner }
+            end
+        end
+    end
+end
                     end
                 end
                 if #valid > 0 then
@@ -25887,7 +22243,7 @@
 end
 
 function runners.timed(action)
-    statistics.timed(action,true)
+    statistics.timed(action)
 end
 
 function runners.associate(filename)

Modified: trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua	2019-02-25 22:22:50 UTC (rev 50131)
@@ -9,8 +9,8 @@
 
 local ProvidesLuaModule = { 
     name          = "luaotfload-tool",
-    version       = "2.95",       --TAGVERSION
-    date          = "2019-01-28", --TAGDATE
+    version       = "2.96",       --TAGVERSION
+    date          = "2019-02-14", --TAGDATE
     description   = "luaotfload-tool / database functionality",
     license       = "GPL v2.0"
 }

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS	2019-02-25 22:22:50 UTC (rev 50131)
@@ -1,5 +1,11 @@
 Change History
 --------------
+2019-01-28 luaotfload v2.96
+    * repaired broken letterspace (issue #38)
+    * changed handling of spaces in letterspacing
+    * changed handling of ligatures in letterspacing
+    * corrected detection of bold fonts (issue #41)
+
 2019-01-28 luaotfload v2.95
     * imported context files of 2019-01-28
     * changed bold indification (for lucida demi bold) (issue #33)

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md	2019-02-25 22:22:50 UTC (rev 50131)
@@ -1,8 +1,8 @@
 # The Luaotfload Package
 
-VERSION: 2.95
+VERSION: 2.96
 
-DATE: 2019-01-28
+DATE: 2019-02-14
 
 
 ## Description

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf
===================================================================
(Binary files differ)

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

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex	2019-02-25 22:22:50 UTC (rev 50131)
@@ -65,7 +65,7 @@
 ]{Linux Libertine O}
 \setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN-Regular.otf}
 %setsansfont[Ligatures=TeX]{Linux Biolinum O}
-\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
+\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{IwonaMedium-Regular.otf}
 %setmathfont{XITS Math}
 
 \usepackage{hologo}

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex	2019-02-25 22:22:50 UTC (rev 50131)
@@ -32,7 +32,7 @@
 \beginfrontmatter
 
   \setdocumenttitle  {The \identifier{luaotfload} package}
-  \setdocumentdate   {2019-01-28 v2.95}
+  \setdocumentdate   {2019-02-14 v2.96}
   \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer\\
                       Home:    \hyperlink {https://github.com/lualatex/luaotfload}\\
                       New Home: \hyperlink {https://github.com/u-fischer/luaotfload}\\
@@ -56,6 +56,18 @@
 \pdfbookmark[1]{\contentsname}{table}
 \typesetcontent
 
+\beginsection {New in version 2.96 (by Ulrike Fischer)}
+\begin{itemize}
+\item In\marginpar{\mbox{}\hfill \textbf{Incompatible change!}}
+version 2.95 letterspacing was broken due to a change in the fontloader (issue 38). This has been repaired. At the same time a number of oddities and bugs in the letterspacing has been corrected. This can change existing documents. See page~\pageref{p:letterspace} for more information.
+
+\item A problem with the detection of bold fonts has been corrected (issue 41, pull request 42).
+
+\end{itemize}
+\endsection
+
+
+
 \beginsection {New in version 2.95 (by Ulrike Fischer)}
 \begin{itemize}
 \item
@@ -748,7 +760,7 @@
          \endlisting
   \endaltitem
 
-  \beginaltitem {kernfactor \& letterspace}
+  \beginaltitem {kernfactor \& letterspace}\label{p:letterspace}
          Define a font with letterspacing (tracking) enabled.
          %
          In \identifier{luaotfload}, letterspacing is implemented by
@@ -771,9 +783,42 @@
          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).
 
+         Spaces\marginpar{\mbox{}\hfill NEW in v2.96!} between words are now stretched too. This is consistent with the \XETEX behaviour (and the amount of stretching should be similar). This
+         naturally changes the output of a document.  In case you want the old behaviour back use
+         \beginlisting
+           \directlua{luaotfload.letterspace.keepwordspacing = true}
+         \endlisting
+
+         The difference between both options is obvious:
+
+         \begingroup
+         \fontspec{IwonaMedium-Regular.otf}[LetterSpace=60]
+          New: hello world
+
+          \directlua{luaotfload.letterspace.keepwordspacing = true}
+
+          Old: hello world
+
+          \directlua{luaotfload.letterspace.keepwordspacing = false}
+          \endgroup
+
+
+         Ligatures\marginpar{\mbox{}\hfill NEW in v2.96!}  are no longer split into their component glyphs.
+         This change too make the \identifier{luaotfload} more compatible with \XETEX. It also makes it much easier to activate or deactivate ligature sets in letterspaced fonts.
+         If you want to split ligatures, you should deactivate as you would do it with a not-letterspaced font, e.g. with the fontspec \identifier{Ligatures} option, or the low-level \identifier{-liga} and similar.
+
+
+         {\font \test = "file:Iwona-Regular.otf:mode=base;+liga;+tlig;letterspace=12.5"
+          \test With standard ligatures: fi -- ff\par
+
+          \font \test = "file:Iwona-Regular.otf:mode=base;-liga;+tlig;letterspace=12.5"
+          \test Only with tlig: fi -- ff \par
+
+          \font \test = "file:Iwona-Regular.otf:mode=base;-liga;letterspace=12.5"
+          \test No ligatures: fi -- ff \par
+         }
+
          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
@@ -787,7 +832,10 @@
     \font \iwonakernedB = "file:Iwona-Regular.otf:letterspace=12.5"
          \endlisting
 
-         Specific pairs of letters and ligatures may be exempt from
+         The \identifier{microtype} package uses a special implementation of letterspacing, and the commands \inlinecode{\lsstyle} and \inlinecode{\textls} are  not affected by these changes.
+
+         Setting the ligatures with the font options is the recommended way, to activate or deactivate them. In case of special requirements
+         specific pairs of letters and ligatures may be exempt from
          letterspacing by defining the \LUA functions
          \luaident{keeptogether} and \luaident{keepligature},
          respectively, inside the namespace \inlinecode {luaotfload.letterspace}.

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst	2019-02-25 22:22:50 UTC (rev 50131)
@@ -6,9 +6,9 @@
          generate and query the Luaotfload font names database
 -----------------------------------------------------------------------
 
-:Date:                  2019-01-28
+:Date:                  2019-02-14
 :Copyright:             GPL v2.0
-:Version:               2.95
+:Version:               2.96
 :Manual section:        1
 :Manual group:          text processing
 

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst	2019-02-25 22:22:50 UTC (rev 50131)
@@ -6,9 +6,9 @@
                      Luaotfload configuration file
 -----------------------------------------------------------------------
 
-:Date:                  2019-01-28
+:Date:                  2019-02-14
 :Copyright:             GPL v2.0
-:Version:               2.95
+:Version:               2.96
 :Manual section:        5
 :Manual group:          text processing
 

Modified: trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1	2019-02-25 22:22:50 UTC (rev 50131)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH LUAOTFLOAD-TOOL 1 "2019-01-28" "2.95" "text processing"
+.TH LUAOTFLOAD-TOOL 1 "2019-02-14" "2.96" "text processing"
 .SH NAME
 luaotfload-tool \- generate and query the Luaotfload font names database
 .

Modified: trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5
===================================================================
--- trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5	2019-02-25 22:22:50 UTC (rev 50131)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH LUAOTFLOAD.CONF 5 "2019-01-28" "2.95" "text processing"
+.TH LUAOTFLOAD.CONF 5 "2019-02-14" "2.96" "text processing"
 .SH NAME
 luaotfload.conf \- Luaotfload configuration file
 .

Modified: trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua	2019-02-25 22:22:50 UTC (rev 50131)
@@ -9,8 +9,8 @@
 
 local ProvidesLuaModule = { 
     name          = "luaotfload-tool",
-    version       = "2.95",       --TAGVERSION
-    date          = "2019-01-28", --TAGDATE
+    version       = "2.96",       --TAGVERSION
+    date          = "2019-02-14", --TAGDATE
     description   = "luaotfload-tool / database functionality",
     license       = "GPL v2.0"
 }

Deleted: trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-01-28.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-01-28.lua	2019-02-25 22:22:22 UTC (rev 50130)
+++ trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-01-28.lua	2019-02-25 22:22:50 UTC (rev 50131)
@@ -1,33234 +0,0 @@
---[[info-----------------------------------------------------------------------
-  Luaotfload fontloader package
-  build 2019-01-30 23:31:07
--------------------------------------------------------------------------------
-
-  © 2019 PRAGMA ADE / ConTeXt Development Team
-
-  The code in this file is provided under the GPL v2.0 license. See the
-  file COPYING in the Luaotfload repository for details.
-
-  Report bugs to github.com/u-fischer/luaotfload
-
-  This file has been assembled from components taken from Context. See
-  the Luaotfload documentation for details:
-
-      $ texdoc luaotfload
-      $ man 1 luaotfload-tool
-      $ man 5 luaotfload.conf
-
-  Included files:
-
-    · fontloader-data-con.lua
-    · fontloader-basics-nod.lua
-    · fontloader-basics-chr.lua
-    · fontloader-font-ini.lua
-    · fontloader-fonts-mis.lua
-    · fontloader-font-con.lua
-    · fontloader-fonts-enc.lua
-    · fontloader-font-cid.lua
-    · fontloader-font-map.lua
-    · fontloader-font-vfc.lua
-    · fontloader-font-otr.lua
-    · fontloader-font-oti.lua
-    · fontloader-font-ott.lua
-    · fontloader-font-cff.lua
-    · fontloader-font-ttf.lua
-    · fontloader-font-dsp.lua
-    · fontloader-font-oup.lua
-    · fontloader-font-otl.lua
-    · fontloader-font-oto.lua
-    · fontloader-font-otj.lua
-    · fontloader-font-ota.lua
-    · fontloader-font-ots.lua
-    · fontloader-font-osd.lua
-    · fontloader-font-ocl.lua
-    · fontloader-font-otc.lua
-    · fontloader-font-onr.lua
-    · fontloader-font-one.lua
-    · fontloader-font-afk.lua
-    · fontloader-font-tfm.lua
-    · fontloader-font-lua.lua
-    · fontloader-font-def.lua
-    · fontloader-fonts-def.lua
-    · fontloader-fonts-ext.lua
-    · fontloader-font-imp-tex.lua
-    · fontloader-font-imp-ligatures.lua
-    · fontloader-font-imp-italics.lua
-    · fontloader-font-imp-effects.lua
-    · fontloader-fonts-lig.lua
-    · fontloader-fonts-gbn.lua
-
---info]]-----------------------------------------------------------------------
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “data-con” 7ce546725b1550f655c78ac9d69419ca] ---
-
-if not modules then modules={} end modules ['data-con']={
-  version=1.100,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
-containers=containers or {}
-local containers=containers
-containers.usecache=true
-local report_containers=logs.reporter("resolvers","containers")
-local allocated={}
-local mt={
-  __index=function(t,k)
-    if k=="writable" then
-      local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
-      t.writable=writable
-      return writable
-    elseif k=="readables" then
-      local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
-      t.readables=readables
-      return readables
-    end
-  end,
-  __storage__=true
-}
-function containers.define(category,subcategory,version,enabled)
-  if category and subcategory then
-    local c=allocated[category]
-    if not c then
-      c={}
-      allocated[category]=c
-    end
-    local s=c[subcategory]
-    if not s then
-      s={
-        category=category,
-        subcategory=subcategory,
-        storage={},
-        enabled=enabled,
-        version=version or math.pi,
-        trace=false,
-      }
-      setmetatable(s,mt)
-      c[subcategory]=s
-    end
-    return s
-  end
-end
-function containers.is_usable(container,name)
-  return container.enabled and caches and caches.is_writable(container.writable,name)
-end
-function containers.is_valid(container,name)
-  if name and name~="" then
-    local storage=container.storage[name]
-    return storage and storage.cache_version==container.version
-  else
-    return false
-  end
-end
-function containers.read(container,name)
-  local storage=container.storage
-  local stored=storage[name]
-  if not stored and container.enabled and caches and containers.usecache then
-    stored=caches.loaddata(container.readables,name,container.writable)
-    if stored and stored.cache_version==container.version then
-      if trace_cache or trace_containers then
-        report_containers("action %a, category %a, name %a","load",container.subcategory,name)
-      end
-    else
-      stored=nil
-    end
-    storage[name]=stored
-  elseif stored then
-    if trace_cache or trace_containers then
-      report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
-    end
-  end
-  return stored
-end
-function containers.write(container,name,data)
-  if data then
-    data.cache_version=container.version
-    if container.enabled and caches then
-      local unique,shared=data.unique,data.shared
-      data.unique,data.shared=nil,nil
-      caches.savedata(container.writable,name,data)
-      if trace_cache or trace_containers then
-        report_containers("action %a, category %a, name %a","save",container.subcategory,name)
-      end
-      data.unique,data.shared=unique,shared
-    end
-    if trace_cache or trace_containers then
-      report_containers("action %a, category %a, name %a","store",container.subcategory,name)
-    end
-    container.storage[name]=data
-  end
-  return data
-end
-function containers.content(container,name)
-  return container.storage[name]
-end
-function containers.cleanname(name)
-  return (gsub(lower(name),"[^%w\128-\255]+","-")) 
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “data-con”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “basics-nod” 31e53bc2d299eda36a0f6592a0d0693f] ---
-
-if not modules then modules={} end modules ['luatex-fonts-nod']={
-  version=1.001,
-  comment="companion to luatex-fonts.lua",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  os.exit()
-end
-if tex.attribute[0]~=0 then
-  texio.write_nl("log","!")
-  texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
-  texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
-  texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
-  texio.write_nl("log","!")
-  tex.attribute[0]=0 
-end
-attributes=attributes or {}
-attributes.unsetvalue=-0x7FFFFFFF
-local numbers,last={},127
-attributes.private=attributes.private or function(name)
-  local number=numbers[name]
-  if not number then
-    if last<255 then
-      last=last+1
-    end
-    number=last
-    numbers[name]=number
-  end
-  return number
-end
-nodes={}
-nodes.handlers={}
-local nodecodes={}
-local glyphcodes=node.subtypes("glyph")
-local disccodes=node.subtypes("disc")
-for k,v in next,node.types() do
-  v=string.gsub(v,"_","")
-  nodecodes[k]=v
-  nodecodes[v]=k
-end
-for k,v in next,glyphcodes do
-  glyphcodes[v]=k
-end
-for k,v in next,disccodes do
-  disccodes[v]=k
-end
-nodes.nodecodes=nodecodes
-nodes.glyphcodes=glyphcodes
-nodes.disccodes=disccodes
-local flush_node=node.flush_node
-local remove_node=node.remove
-local traverse_id=node.traverse_id
-nodes.handlers.protectglyphs=node.protect_glyphs  
-nodes.handlers.unprotectglyphs=node.unprotect_glyphs 
-function nodes.remove(head,current,free_too)
-  local t=current
-  head,current=remove_node(head,current)
-  if t then
-    if free_too then
-      flush_node(t)
-      t=nil
-    else
-      t.next,t.prev=nil,nil
-    end
-  end
-  return head,current,t
-end
-function nodes.delete(head,current)
-  return nodes.remove(head,current,true)
-end
-local getfield=node.getfield
-local setfield=node.setfield
-nodes.getfield=getfield
-nodes.setfield=setfield
-nodes.getattr=getfield
-nodes.setattr=setfield
-nodes.tostring=node.tostring or tostring
-nodes.copy=node.copy
-nodes.copy_node=node.copy
-nodes.copy_list=node.copy_list
-nodes.delete=node.delete
-nodes.dimensions=node.dimensions
-nodes.end_of_math=node.end_of_math
-nodes.flush_list=node.flush_list
-nodes.flush_node=node.flush_node
-nodes.flush=node.flush_node
-nodes.free=node.free
-nodes.insert_after=node.insert_after
-nodes.insert_before=node.insert_before
-nodes.hpack=node.hpack
-nodes.new=node.new
-nodes.tail=node.tail
-nodes.traverse=node.traverse
-nodes.traverse_id=node.traverse_id
-nodes.slide=node.slide
-nodes.vpack=node.vpack
-nodes.first_glyph=node.first_glyph
-nodes.has_glyph=node.has_glyph or node.first_glyph
-nodes.current_attr=node.current_attr
-nodes.has_field=node.has_field
-nodes.last_node=node.last_node
-nodes.usedlist=node.usedlist
-nodes.protrusion_skippable=node.protrusion_skippable
-nodes.write=node.write
-nodes.has_attribute=node.has_attribute
-nodes.set_attribute=node.set_attribute
-nodes.unset_attribute=node.unset_attribute
-nodes.protect_glyphs=node.protect_glyphs
-nodes.unprotect_glyphs=node.unprotect_glyphs
-nodes.mlist_to_hlist=node.mlist_to_hlist
-local direct=node.direct
-local nuts={}
-nodes.nuts=nuts
-local tonode=direct.tonode
-local tonut=direct.todirect
-nodes.tonode=tonode
-nodes.tonut=tonut
-nuts.tonode=tonode
-nuts.tonut=tonut
-nuts.getattr=direct.get_attribute
-nuts.getboth=direct.getboth
-nuts.getchar=direct.getchar
-nuts.getcomponents=direct.getcomponents
-nuts.getdirection=direct.getdirection
-nuts.getdisc=direct.getdisc
-nuts.getfield=direct.getfield
-nuts.getfont=direct.getfont
-nuts.getid=direct.getid
-nuts.getkern=direct.getkern
-nuts.getlist=direct.getlist
-nuts.getnext=direct.getnext
-nuts.getoffsets=direct.getoffsets
-nuts.getprev=direct.getprev
-nuts.getsubtype=direct.getsubtype
-nuts.getwidth=direct.getwidth
-nuts.setattr=direct.setfield
-nuts.setboth=direct.setboth
-nuts.setchar=direct.setchar
-nuts.setcomponents=direct.setcomponents
-nuts.setdir=direct.setdir
-nuts.setdirection=direct.setdirection
-nuts.setdisc=direct.setdisc
-nuts.setfield=setfield
-nuts.setkern=direct.setkern
-nuts.setlink=direct.setlink
-nuts.setlist=direct.setlist
-nuts.setnext=direct.setnext
-nuts.setoffsets=direct.setoffsets
-nuts.setprev=direct.setprev
-nuts.setsplit=direct.setsplit
-nuts.setsubtype=direct.setsubtype
-nuts.setwidth=direct.setwidth
-nuts.is_char=direct.is_char
-nuts.is_glyph=direct.is_glyph
-nuts.ischar=direct.is_char
-nuts.isglyph=direct.is_glyph
-nuts.copy=direct.copy
-nuts.copy_list=direct.copy_list
-nuts.copy_node=direct.copy
-nuts.delete=direct.delete
-nuts.end_of_math=direct.end_of_math
-nuts.flush=direct.flush
-nuts.flush_list=direct.flush_list
-nuts.flush_node=direct.flush_node
-nuts.free=direct.free
-nuts.insert_after=direct.insert_after
-nuts.insert_before=direct.insert_before
-nuts.is_node=direct.is_node
-nuts.kerning=direct.kerning
-nuts.ligaturing=direct.ligaturing
-nuts.new=direct.new
-nuts.remove=direct.remove
-nuts.tail=direct.tail
-nuts.traverse=direct.traverse
-nuts.traverse_char=direct.traverse_char
-nuts.traverse_glyph=direct.traverse_glyph
-nuts.traverse_id=direct.traverse_id
-if not nuts.getdirection then
-  local getdir=direct.getdir
-  function nuts.getdirection(n)
-    local d=getdir(n)
-    if   d=="TLT" then return 0
-    elseif d=="TRT" then return 1
-    elseif d=="+TLT" then return 0,false
-    elseif d=="+TRT" then return 1,false
-    elseif d=="-TLT" then return 0,true
-    elseif d=="-TRT" then return 1,true
-    else          return 0
-    end
-  end
-end
-local propertydata=direct.get_properties_table()
-nodes.properties={ data=propertydata }
-direct.set_properties_mode(true,true)   
-function direct.set_properties_mode() end 
-nuts.getprop=function(n,k)
-  local p=propertydata[n]
-  if p then
-    return p[k]
-  end
-end
-nuts.setprop=function(n,k,v)
-  if v then
-    local p=propertydata[n]
-    if p then
-      p[k]=v
-    else
-      propertydata[n]={ [k]=v }
-    end
-  end
-end
-nodes.setprop=nodes.setproperty
-nodes.getprop=nodes.getproperty
-local setprev=nuts.setprev
-local setnext=nuts.setnext
-local getnext=nuts.getnext
-local setlink=nuts.setlink
-local getfield=nuts.getfield
-local setfield=nuts.setfield
-local getcomponents=nuts.getcomponents
-local setcomponents=nuts.setcomponents
-local find_tail=nuts.tail
-local flush_list=nuts.flush_list
-local flush_node=nuts.flush_node
-local traverse_id=nuts.traverse_id
-local copy_node=nuts.copy_node
-local glyph_code=nodes.nodecodes.glyph
-function nuts.copy_no_components(g,copyinjection)
-  local components=getcomponents(g)
-  if components then
-    setcomponents(g)
-    local n=copy_node(g)
-    if copyinjection then
-      copyinjection(n,g)
-    end
-    setcomponents(g,components)
-    return n
-  else
-    local n=copy_node(g)
-    if copyinjection then
-      copyinjection(n,g)
-    end
-    return n
-  end
-end
-function nuts.copy_only_glyphs(current)
-  local head=nil
-  local previous=nil
-  for n in traverse_id(glyph_code,current) do
-    n=copy_node(n)
-    if head then
-      setlink(previous,n)
-    else
-      head=n
-    end
-    previous=n
-  end
-  return head
-end
-nuts.uses_font=direct.uses_font
-do
-  local dummy=tonut(node.new("glyph"))
-  nuts.traversers={
-    glyph=nuts.traverse_id(nodecodes.glyph,dummy),
-    glue=nuts.traverse_id(nodecodes.glue,dummy),
-    disc=nuts.traverse_id(nodecodes.disc,dummy),
-    boundary=nuts.traverse_id(nodecodes.boundary,dummy),
-    char=nuts.traverse_char(dummy),
-    node=nuts.traverse(dummy),
-  }
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “basics-nod”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “basics-chr” a8b8316248b40cc9bc1be19050f7074f] ---
-
-
-characters=characters or {}
-characters.blockrange={}
-characters.classifiers={
- [768]=5,
- [769]=5,
- [770]=5,
- [771]=5,
- [772]=5,
- [773]=5,
- [774]=5,
- [775]=5,
- [776]=5,
- [777]=5,
- [778]=5,
- [779]=5,
- [780]=5,
- [781]=5,
- [782]=5,
- [783]=5,
- [784]=5,
- [785]=5,
- [786]=5,
- [787]=5,
- [788]=5,
- [789]=5,
- [790]=5,
- [791]=5,
- [792]=5,
- [793]=5,
- [794]=5,
- [795]=5,
- [796]=5,
- [797]=5,
- [798]=5,
- [799]=5,
- [800]=5,
- [801]=5,
- [802]=5,
- [803]=5,
- [804]=5,
- [805]=5,
- [806]=5,
- [807]=5,
- [808]=5,
- [809]=5,
- [810]=5,
- [811]=5,
- [812]=5,
- [813]=5,
- [814]=5,
- [815]=5,
- [816]=5,
- [817]=5,
- [818]=5,
- [819]=5,
- [820]=5,
- [821]=5,
- [822]=5,
- [823]=5,
- [824]=5,
- [825]=5,
- [826]=5,
- [827]=5,
- [828]=5,
- [829]=5,
- [830]=5,
- [831]=5,
- [832]=5,
- [833]=5,
- [834]=5,
- [835]=5,
- [836]=5,
- [837]=5,
- [838]=5,
- [839]=5,
- [840]=5,
- [841]=5,
- [842]=5,
- [843]=5,
- [844]=5,
- [845]=5,
- [846]=5,
- [847]=5,
- [848]=5,
- [849]=5,
- [850]=5,
- [851]=5,
- [852]=5,
- [853]=5,
- [854]=5,
- [855]=5,
- [856]=5,
- [857]=5,
- [858]=5,
- [859]=5,
- [860]=5,
- [861]=5,
- [862]=5,
- [863]=5,
- [864]=5,
- [865]=5,
- [866]=5,
- [867]=5,
- [868]=5,
- [869]=5,
- [870]=5,
- [871]=5,
- [872]=5,
- [873]=5,
- [874]=5,
- [875]=5,
- [876]=5,
- [877]=5,
- [878]=5,
- [879]=5,
- [1155]=5,
- [1156]=5,
- [1157]=5,
- [1158]=5,
- [1159]=5,
- [1425]=5,
- [1426]=5,
- [1427]=5,
- [1428]=5,
- [1429]=5,
- [1430]=5,
- [1431]=5,
- [1432]=5,
- [1433]=5,
- [1434]=5,
- [1435]=5,
- [1436]=5,
- [1437]=5,
- [1438]=5,
- [1439]=5,
- [1440]=5,
- [1441]=5,
- [1442]=5,
- [1443]=5,
- [1444]=5,
- [1445]=5,
- [1446]=5,
- [1447]=5,
- [1448]=5,
- [1449]=5,
- [1450]=5,
- [1451]=5,
- [1452]=5,
- [1453]=5,
- [1454]=5,
- [1455]=5,
- [1456]=5,
- [1457]=5,
- [1458]=5,
- [1459]=5,
- [1460]=5,
- [1461]=5,
- [1462]=5,
- [1463]=5,
- [1464]=5,
- [1465]=5,
- [1466]=5,
- [1467]=5,
- [1468]=5,
- [1469]=5,
- [1471]=5,
- [1473]=5,
- [1474]=5,
- [1476]=5,
- [1477]=5,
- [1479]=5,
- [1536]=4,
- [1537]=4,
- [1538]=4,
- [1539]=4,
- [1540]=4,
- [1541]=4,
- [1542]=6,
- [1543]=6,
- [1544]=4,
- [1545]=6,
- [1546]=6,
- [1547]=4,
- [1548]=6,
- [1549]=6,
- [1550]=6,
- [1551]=6,
- [1552]=5,
- [1553]=5,
- [1554]=5,
- [1555]=5,
- [1556]=5,
- [1557]=5,
- [1558]=5,
- [1559]=5,
- [1560]=5,
- [1561]=5,
- [1562]=5,
- [1563]=6,
- [1564]=6,
- [1566]=6,
- [1567]=6,
- [1568]=2,
- [1569]=4,
- [1570]=3,
- [1571]=3,
- [1572]=3,
- [1573]=3,
- [1574]=2,
- [1575]=3,
- [1576]=2,
- [1577]=3,
- [1578]=2,
- [1579]=2,
- [1580]=2,
- [1581]=2,
- [1582]=2,
- [1583]=3,
- [1584]=3,
- [1585]=3,
- [1586]=3,
- [1587]=2,
- [1588]=2,
- [1589]=2,
- [1590]=2,
- [1591]=2,
- [1592]=2,
- [1593]=2,
- [1594]=2,
- [1595]=2,
- [1596]=2,
- [1597]=2,
- [1598]=2,
- [1599]=2,
- [1600]=2,
- [1601]=2,
- [1602]=2,
- [1603]=2,
- [1604]=2,
- [1605]=2,
- [1606]=2,
- [1607]=2,
- [1608]=3,
- [1609]=2,
- [1610]=2,
- [1611]=5,
- [1612]=5,
- [1613]=5,
- [1614]=5,
- [1615]=5,
- [1616]=5,
- [1617]=5,
- [1618]=5,
- [1619]=5,
- [1620]=5,
- [1621]=5,
- [1622]=5,
- [1623]=5,
- [1624]=5,
- [1625]=5,
- [1626]=5,
- [1627]=5,
- [1628]=5,
- [1629]=5,
- [1630]=5,
- [1631]=5,
- [1632]=6,
- [1633]=6,
- [1634]=6,
- [1635]=6,
- [1636]=6,
- [1637]=6,
- [1638]=6,
- [1639]=6,
- [1640]=6,
- [1641]=6,
- [1642]=6,
- [1643]=6,
- [1644]=6,
- [1645]=6,
- [1646]=2,
- [1647]=2,
- [1648]=5,
- [1649]=3,
- [1650]=3,
- [1651]=3,
- [1652]=4,
- [1653]=3,
- [1654]=3,
- [1655]=3,
- [1656]=2,
- [1657]=2,
- [1658]=2,
- [1659]=2,
- [1660]=2,
- [1661]=2,
- [1662]=2,
- [1663]=2,
- [1664]=2,
- [1665]=2,
- [1666]=2,
- [1667]=2,
- [1668]=2,
- [1669]=2,
- [1670]=2,
- [1671]=2,
- [1672]=3,
- [1673]=3,
- [1674]=3,
- [1675]=3,
- [1676]=3,
- [1677]=3,
- [1678]=3,
- [1679]=3,
- [1680]=3,
- [1681]=3,
- [1682]=3,
- [1683]=3,
- [1684]=3,
- [1685]=3,
- [1686]=3,
- [1687]=3,
- [1688]=3,
- [1689]=3,
- [1690]=2,
- [1691]=2,
- [1692]=2,
- [1693]=2,
- [1694]=2,
- [1695]=2,
- [1696]=2,
- [1697]=2,
- [1698]=2,
- [1699]=2,
- [1700]=2,
- [1701]=2,
- [1702]=2,
- [1703]=2,
- [1704]=2,
- [1705]=2,
- [1706]=2,
- [1707]=2,
- [1708]=2,
- [1709]=2,
- [1710]=2,
- [1711]=2,
- [1712]=2,
- [1713]=2,
- [1714]=2,
- [1715]=2,
- [1716]=2,
- [1717]=2,
- [1718]=2,
- [1719]=2,
- [1720]=2,
- [1721]=2,
- [1722]=2,
- [1723]=2,
- [1724]=2,
- [1725]=2,
- [1726]=2,
- [1727]=2,
- [1728]=3,
- [1729]=2,
- [1730]=2,
- [1731]=3,
- [1732]=3,
- [1733]=3,
- [1734]=3,
- [1735]=3,
- [1736]=3,
- [1737]=3,
- [1738]=3,
- [1739]=3,
- [1740]=2,
- [1741]=3,
- [1742]=2,
- [1743]=3,
- [1744]=2,
- [1745]=2,
- [1746]=3,
- [1747]=3,
- [1748]=6,
- [1749]=3,
- [1750]=5,
- [1751]=5,
- [1752]=5,
- [1753]=5,
- [1754]=5,
- [1755]=5,
- [1756]=5,
- [1757]=4,
- [1758]=6,
- [1759]=5,
- [1760]=5,
- [1761]=5,
- [1762]=5,
- [1763]=5,
- [1764]=5,
- [1765]=6,
- [1766]=6,
- [1767]=5,
- [1768]=5,
- [1769]=6,
- [1770]=5,
- [1771]=5,
- [1772]=5,
- [1773]=5,
- [1774]=3,
- [1775]=3,
- [1776]=6,
- [1777]=6,
- [1778]=6,
- [1779]=6,
- [1780]=6,
- [1781]=6,
- [1782]=6,
- [1783]=6,
- [1784]=6,
- [1785]=6,
- [1786]=2,
- [1787]=2,
- [1788]=2,
- [1789]=6,
- [1790]=6,
- [1791]=2,
- [1792]=6,
- [1793]=6,
- [1794]=6,
- [1795]=6,
- [1796]=6,
- [1797]=6,
- [1798]=6,
- [1799]=6,
- [1800]=6,
- [1801]=6,
- [1802]=6,
- [1803]=6,
- [1804]=6,
- [1805]=6,
- [1807]=6,
- [1808]=3,
- [1809]=5,
- [1810]=2,
- [1811]=2,
- [1812]=2,
- [1813]=3,
- [1814]=3,
- [1815]=3,
- [1816]=3,
- [1817]=3,
- [1818]=2,
- [1819]=2,
- [1820]=2,
- [1821]=2,
- [1822]=3,
- [1823]=2,
- [1824]=2,
- [1825]=2,
- [1826]=2,
- [1827]=2,
- [1828]=2,
- [1829]=2,
- [1830]=2,
- [1831]=2,
- [1832]=3,
- [1833]=2,
- [1834]=3,
- [1835]=2,
- [1836]=3,
- [1837]=2,
- [1838]=2,
- [1839]=3,
- [1840]=5,
- [1841]=5,
- [1842]=5,
- [1843]=5,
- [1844]=5,
- [1845]=5,
- [1846]=5,
- [1847]=5,
- [1848]=5,
- [1849]=5,
- [1850]=5,
- [1851]=5,
- [1852]=5,
- [1853]=5,
- [1854]=5,
- [1855]=5,
- [1856]=5,
- [1857]=5,
- [1858]=5,
- [1859]=5,
- [1860]=5,
- [1861]=5,
- [1862]=5,
- [1863]=5,
- [1864]=5,
- [1865]=5,
- [1866]=5,
- [1869]=3,
- [1870]=2,
- [1871]=2,
- [1872]=2,
- [1873]=2,
- [1874]=2,
- [1875]=2,
- [1876]=2,
- [1877]=2,
- [1878]=2,
- [1879]=2,
- [1880]=2,
- [1881]=3,
- [1882]=3,
- [1883]=3,
- [1884]=2,
- [1885]=2,
- [1886]=2,
- [1887]=2,
- [1888]=2,
- [1889]=2,
- [1890]=2,
- [1891]=2,
- [1892]=2,
- [1893]=2,
- [1894]=2,
- [1895]=2,
- [1896]=2,
- [1897]=2,
- [1898]=2,
- [1899]=3,
- [1900]=3,
- [1901]=2,
- [1902]=2,
- [1903]=2,
- [1904]=2,
- [1905]=3,
- [1906]=2,
- [1907]=3,
- [1908]=3,
- [1909]=2,
- [1910]=2,
- [1911]=2,
- [1912]=3,
- [1913]=3,
- [1914]=2,
- [1915]=2,
- [1916]=2,
- [1917]=2,
- [1918]=2,
- [1919]=2,
- [1958]=5,
- [1959]=5,
- [1960]=5,
- [1961]=5,
- [1962]=5,
- [1963]=5,
- [1964]=5,
- [1965]=5,
- [1966]=5,
- [1967]=5,
- [1968]=5,
- [1984]=6,
- [1985]=6,
- [1986]=6,
- [1987]=6,
- [1988]=6,
- [1989]=6,
- [1990]=6,
- [1991]=6,
- [1992]=6,
- [1993]=6,
- [1994]=2,
- [1995]=2,
- [1996]=2,
- [1997]=2,
- [1998]=2,
- [1999]=2,
- [2000]=2,
- [2001]=2,
- [2002]=2,
- [2003]=2,
- [2004]=2,
- [2005]=2,
- [2006]=2,
- [2007]=2,
- [2008]=2,
- [2009]=2,
- [2010]=2,
- [2011]=2,
- [2012]=2,
- [2013]=2,
- [2014]=2,
- [2015]=2,
- [2016]=2,
- [2017]=2,
- [2018]=2,
- [2019]=2,
- [2020]=2,
- [2021]=2,
- [2022]=2,
- [2023]=2,
- [2024]=2,
- [2025]=2,
- [2026]=2,
- [2027]=5,
- [2028]=5,
- [2029]=5,
- [2030]=5,
- [2031]=5,
- [2032]=5,
- [2033]=5,
- [2034]=5,
- [2035]=5,
- [2036]=6,
- [2037]=6,
- [2038]=6,
- [2039]=6,
- [2040]=6,
- [2041]=6,
- [2042]=2,
- [2070]=5,
- [2071]=5,
- [2072]=5,
- [2073]=5,
- [2075]=5,
- [2076]=5,
- [2077]=5,
- [2078]=5,
- [2079]=5,
- [2080]=5,
- [2081]=5,
- [2082]=5,
- [2083]=5,
- [2085]=5,
- [2086]=5,
- [2087]=5,
- [2089]=5,
- [2090]=5,
- [2091]=5,
- [2092]=5,
- [2093]=5,
- [2112]=3,
- [2113]=2,
- [2114]=2,
- [2115]=2,
- [2116]=2,
- [2117]=2,
- [2118]=3,
- [2119]=3,
- [2120]=2,
- [2121]=3,
- [2122]=2,
- [2123]=2,
- [2124]=2,
- [2125]=2,
- [2126]=2,
- [2127]=2,
- [2128]=2,
- [2129]=2,
- [2130]=2,
- [2131]=2,
- [2132]=3,
- [2133]=2,
- [2134]=4,
- [2135]=4,
- [2136]=4,
- [2137]=5,
- [2138]=5,
- [2139]=5,
- [2144]=2,
- [2145]=4,
- [2146]=2,
- [2147]=2,
- [2148]=2,
- [2149]=2,
- [2150]=4,
- [2151]=3,
- [2152]=2,
- [2153]=3,
- [2154]=3,
- [2208]=2,
- [2209]=2,
- [2210]=2,
- [2211]=2,
- [2212]=2,
- [2213]=2,
- [2214]=2,
- [2215]=2,
- [2216]=2,
- [2217]=2,
- [2218]=3,
- [2219]=3,
- [2220]=3,
- [2221]=4,
- [2222]=3,
- [2223]=2,
- [2224]=2,
- [2225]=3,
- [2226]=3,
- [2227]=2,
- [2228]=2,
- [2230]=2,
- [2231]=2,
- [2232]=2,
- [2233]=3,
- [2234]=2,
- [2235]=2,
- [2236]=2,
- [2237]=2,
- [2260]=5,
- [2261]=5,
- [2262]=5,
- [2263]=5,
- [2264]=5,
- [2265]=5,
- [2266]=5,
- [2267]=5,
- [2268]=5,
- [2269]=5,
- [2270]=5,
- [2271]=5,
- [2272]=5,
- [2273]=5,
- [2274]=4,
- [2275]=5,
- [2276]=5,
- [2277]=5,
- [2278]=5,
- [2279]=5,
- [2280]=5,
- [2281]=5,
- [2282]=5,
- [2283]=5,
- [2284]=5,
- [2285]=5,
- [2286]=5,
- [2287]=5,
- [2288]=5,
- [2289]=5,
- [2290]=5,
- [2291]=5,
- [2292]=5,
- [2293]=5,
- [2294]=5,
- [2295]=5,
- [2296]=5,
- [2297]=5,
- [2298]=5,
- [2299]=5,
- [2300]=5,
- [2301]=5,
- [2302]=5,
- [2303]=5,
- [2304]=5,
- [2305]=5,
- [2306]=5,
- [2362]=5,
- [2364]=5,
- [2369]=5,
- [2370]=5,
- [2371]=5,
- [2372]=5,
- [2373]=5,
- [2374]=5,
- [2375]=5,
- [2376]=5,
- [2381]=5,
- [2385]=5,
- [2386]=5,
- [2387]=5,
- [2388]=5,
- [2389]=5,
- [2390]=5,
- [2391]=5,
- [2402]=5,
- [2403]=5,
- [2433]=5,
- [2492]=5,
- [2497]=5,
- [2498]=5,
- [2499]=5,
- [2500]=5,
- [2509]=5,
- [2530]=5,
- [2531]=5,
- [2561]=5,
- [2562]=5,
- [2620]=5,
- [2625]=5,
- [2626]=5,
- [2631]=5,
- [2632]=5,
- [2635]=5,
- [2636]=5,
- [2637]=5,
- [2641]=5,
- [2672]=5,
- [2673]=5,
- [2677]=5,
- [2689]=5,
- [2690]=5,
- [2748]=5,
- [2753]=5,
- [2754]=5,
- [2755]=5,
- [2756]=5,
- [2757]=5,
- [2759]=5,
- [2760]=5,
- [2765]=5,
- [2786]=5,
- [2787]=5,
- [2810]=5,
- [2811]=5,
- [2812]=5,
- [2813]=5,
- [2814]=5,
- [2815]=5,
- [2817]=5,
- [2876]=5,
- [2879]=5,
- [2881]=5,
- [2882]=5,
- [2883]=5,
- [2884]=5,
- [2893]=5,
- [2902]=5,
- [2914]=5,
- [2915]=5,
- [2946]=5,
- [3008]=5,
- [3021]=5,
- [3072]=5,
- [3134]=5,
- [3135]=5,
- [3136]=5,
- [3142]=5,
- [3143]=5,
- [3144]=5,
- [3146]=5,
- [3147]=5,
- [3148]=5,
- [3149]=5,
- [3157]=5,
- [3158]=5,
- [3170]=5,
- [3171]=5,
- [3201]=5,
- [3260]=5,
- [3263]=5,
- [3270]=5,
- [3276]=5,
- [3277]=5,
- [3298]=5,
- [3299]=5,
- [3328]=5,
- [3329]=5,
- [3387]=5,
- [3388]=5,
- [3393]=5,
- [3394]=5,
- [3395]=5,
- [3396]=5,
- [3405]=5,
- [3426]=5,
- [3427]=5,
- [3530]=5,
- [3538]=5,
- [3539]=5,
- [3540]=5,
- [3542]=5,
- [3633]=5,
- [3636]=5,
- [3637]=5,
- [3638]=5,
- [3639]=5,
- [3640]=5,
- [3641]=5,
- [3642]=5,
- [3655]=5,
- [3656]=5,
- [3657]=5,
- [3658]=5,
- [3659]=5,
- [3660]=5,
- [3661]=5,
- [3662]=5,
- [3761]=5,
- [3764]=5,
- [3765]=5,
- [3766]=5,
- [3767]=5,
- [3768]=5,
- [3769]=5,
- [3771]=5,
- [3772]=5,
- [3784]=5,
- [3785]=5,
- [3786]=5,
- [3787]=5,
- [3788]=5,
- [3789]=5,
- [3864]=5,
- [3865]=5,
- [3893]=5,
- [3895]=5,
- [3897]=5,
- [3953]=5,
- [3954]=5,
- [3955]=5,
- [3956]=5,
- [3957]=5,
- [3958]=5,
- [3959]=5,
- [3960]=5,
- [3961]=5,
- [3962]=5,
- [3963]=5,
- [3964]=5,
- [3965]=5,
- [3966]=5,
- [3968]=5,
- [3969]=5,
- [3970]=5,
- [3971]=5,
- [3972]=5,
- [3974]=5,
- [3975]=5,
- [3981]=5,
- [3982]=5,
- [3983]=5,
- [3984]=5,
- [3985]=5,
- [3986]=5,
- [3987]=5,
- [3988]=5,
- [3989]=5,
- [3990]=5,
- [3991]=5,
- [3993]=5,
- [3994]=5,
- [3995]=5,
- [3996]=5,
- [3997]=5,
- [3998]=5,
- [3999]=5,
- [4000]=5,
- [4001]=5,
- [4002]=5,
- [4003]=5,
- [4004]=5,
- [4005]=5,
- [4006]=5,
- [4007]=5,
- [4008]=5,
- [4009]=5,
- [4010]=5,
- [4011]=5,
- [4012]=5,
- [4013]=5,
- [4014]=5,
- [4015]=5,
- [4016]=5,
- [4017]=5,
- [4018]=5,
- [4019]=5,
- [4020]=5,
- [4021]=5,
- [4022]=5,
- [4023]=5,
- [4024]=5,
- [4025]=5,
- [4026]=5,
- [4027]=5,
- [4028]=5,
- [4038]=5,
- [4141]=5,
- [4142]=5,
- [4143]=5,
- [4144]=5,
- [4146]=5,
- [4147]=5,
- [4148]=5,
- [4149]=5,
- [4150]=5,
- [4151]=5,
- [4153]=5,
- [4154]=5,
- [4157]=5,
- [4158]=5,
- [4184]=5,
- [4185]=5,
- [4190]=5,
- [4191]=5,
- [4192]=5,
- [4209]=5,
- [4210]=5,
- [4211]=5,
- [4212]=5,
- [4226]=5,
- [4229]=5,
- [4230]=5,
- [4237]=5,
- [4253]=5,
- [4957]=5,
- [4958]=5,
- [4959]=5,
- [5906]=5,
- [5907]=5,
- [5908]=5,
- [5938]=5,
- [5939]=5,
- [5940]=5,
- [5970]=5,
- [5971]=5,
- [6002]=5,
- [6003]=5,
- [6071]=5,
- [6072]=5,
- [6073]=5,
- [6074]=5,
- [6075]=5,
- [6076]=5,
- [6077]=5,
- [6086]=5,
- [6089]=5,
- [6090]=5,
- [6091]=5,
- [6092]=5,
- [6093]=5,
- [6094]=5,
- [6095]=5,
- [6096]=5,
- [6097]=5,
- [6098]=5,
- [6099]=5,
- [6109]=5,
- [6150]=4,
- [6151]=2,
- [6154]=2,
- [6155]=5,
- [6156]=5,
- [6157]=5,
- [6158]=4,
- [6176]=2,
- [6177]=2,
- [6178]=2,
- [6179]=2,
- [6180]=2,
- [6181]=2,
- [6182]=2,
- [6183]=2,
- [6184]=2,
- [6185]=2,
- [6186]=2,
- [6187]=2,
- [6188]=2,
- [6189]=2,
- [6190]=2,
- [6191]=2,
- [6192]=2,
- [6193]=2,
- [6194]=2,
- [6195]=2,
- [6196]=2,
- [6197]=2,
- [6198]=2,
- [6199]=2,
- [6200]=2,
- [6201]=2,
- [6202]=2,
- [6203]=2,
- [6204]=2,
- [6205]=2,
- [6206]=2,
- [6207]=2,
- [6208]=2,
- [6209]=2,
- [6210]=2,
- [6211]=2,
- [6212]=2,
- [6213]=2,
- [6214]=2,
- [6215]=2,
- [6216]=2,
- [6217]=2,
- [6218]=2,
- [6219]=2,
- [6220]=2,
- [6221]=2,
- [6222]=2,
- [6223]=2,
- [6224]=2,
- [6225]=2,
- [6226]=2,
- [6227]=2,
- [6228]=2,
- [6229]=2,
- [6230]=2,
- [6231]=2,
- [6232]=2,
- [6233]=2,
- [6234]=2,
- [6235]=2,
- [6236]=2,
- [6237]=2,
- [6238]=2,
- [6239]=2,
- [6240]=2,
- [6241]=2,
- [6242]=2,
- [6243]=2,
- [6244]=2,
- [6245]=2,
- [6246]=2,
- [6247]=2,
- [6248]=2,
- [6249]=2,
- [6250]=2,
- [6251]=2,
- [6252]=2,
- [6253]=2,
- [6254]=2,
- [6255]=2,
- [6256]=2,
- [6257]=2,
- [6258]=2,
- [6259]=2,
- [6260]=2,
- [6261]=2,
- [6262]=2,
- [6263]=2,
- [6272]=4,
- [6273]=4,
- [6274]=4,
- [6275]=4,
- [6276]=4,
- [6279]=2,
- [6280]=2,
- [6281]=2,
- [6282]=2,
- [6283]=2,
- [6284]=2,
- [6285]=2,
- [6286]=2,
- [6287]=2,
- [6288]=2,
- [6289]=2,
- [6290]=2,
- [6291]=2,
- [6292]=2,
- [6293]=2,
- [6294]=2,
- [6295]=2,
- [6296]=2,
- [6297]=2,
- [6298]=2,
- [6299]=2,
- [6300]=2,
- [6301]=2,
- [6302]=2,
- [6303]=2,
- [6304]=2,
- [6305]=2,
- [6306]=2,
- [6307]=2,
- [6308]=2,
- [6309]=2,
- [6310]=2,
- [6311]=2,
- [6312]=2,
- [6313]=5,
- [6314]=2,
- [6432]=5,
- [6433]=5,
- [6434]=5,
- [6439]=5,
- [6440]=5,
- [6450]=5,
- [6457]=5,
- [6458]=5,
- [6459]=5,
- [6679]=5,
- [6680]=5,
- [6742]=5,
- [6744]=5,
- [6745]=5,
- [6746]=5,
- [6747]=5,
- [6748]=5,
- [6749]=5,
- [6750]=5,
- [6752]=5,
- [6754]=5,
- [6757]=5,
- [6758]=5,
- [6759]=5,
- [6760]=5,
- [6761]=5,
- [6762]=5,
- [6763]=5,
- [6764]=5,
- [6771]=5,
- [6772]=5,
- [6773]=5,
- [6774]=5,
- [6775]=5,
- [6776]=5,
- [6777]=5,
- [6778]=5,
- [6779]=5,
- [6780]=5,
- [6783]=5,
- [6832]=5,
- [6833]=5,
- [6834]=5,
- [6835]=5,
- [6836]=5,
- [6837]=5,
- [6838]=5,
- [6839]=5,
- [6840]=5,
- [6841]=5,
- [6842]=5,
- [6843]=5,
- [6844]=5,
- [6845]=5,
- [6912]=5,
- [6913]=5,
- [6914]=5,
- [6915]=5,
- [6964]=5,
- [6966]=5,
- [6967]=5,
- [6968]=5,
- [6969]=5,
- [6970]=5,
- [6972]=5,
- [6978]=5,
- [7019]=5,
- [7020]=5,
- [7021]=5,
- [7022]=5,
- [7023]=5,
- [7024]=5,
- [7025]=5,
- [7026]=5,
- [7027]=5,
- [7040]=5,
- [7041]=5,
- [7074]=5,
- [7075]=5,
- [7076]=5,
- [7077]=5,
- [7080]=5,
- [7081]=5,
- [7083]=5,
- [7142]=5,
- [7144]=5,
- [7145]=5,
- [7149]=5,
- [7151]=5,
- [7152]=5,
- [7153]=5,
- [7212]=5,
- [7213]=5,
- [7214]=5,
- [7215]=5,
- [7216]=5,
- [7217]=5,
- [7218]=5,
- [7219]=5,
- [7222]=5,
- [7223]=5,
- [7376]=5,
- [7377]=5,
- [7378]=5,
- [7380]=5,
- [7381]=5,
- [7382]=5,
- [7383]=5,
- [7384]=5,
- [7385]=5,
- [7386]=5,
- [7387]=5,
- [7388]=5,
- [7389]=5,
- [7390]=5,
- [7391]=5,
- [7392]=5,
- [7394]=5,
- [7395]=5,
- [7396]=5,
- [7397]=5,
- [7398]=5,
- [7399]=5,
- [7400]=5,
- [7405]=5,
- [7412]=5,
- [7416]=5,
- [7417]=5,
- [7616]=5,
- [7617]=5,
- [7618]=5,
- [7619]=5,
- [7620]=5,
- [7621]=5,
- [7622]=5,
- [7623]=5,
- [7624]=5,
- [7625]=5,
- [7626]=5,
- [7627]=5,
- [7628]=5,
- [7629]=5,
- [7630]=5,
- [7631]=5,
- [7632]=5,
- [7633]=5,
- [7634]=5,
- [7635]=5,
- [7636]=5,
- [7637]=5,
- [7638]=5,
- [7639]=5,
- [7640]=5,
- [7641]=5,
- [7642]=5,
- [7643]=5,
- [7644]=5,
- [7645]=5,
- [7646]=5,
- [7647]=5,
- [7648]=5,
- [7649]=5,
- [7650]=5,
- [7651]=5,
- [7652]=5,
- [7653]=5,
- [7654]=5,
- [7655]=5,
- [7656]=5,
- [7657]=5,
- [7658]=5,
- [7659]=5,
- [7660]=5,
- [7661]=5,
- [7662]=5,
- [7663]=5,
- [7664]=5,
- [7665]=5,
- [7666]=5,
- [7667]=5,
- [7668]=5,
- [7669]=5,
- [7670]=5,
- [7671]=5,
- [7672]=5,
- [7673]=5,
- [7675]=5,
- [7676]=5,
- [7677]=5,
- [7678]=5,
- [7679]=5,
- [8204]=4,
- [8205]=2,
- [8239]=4,
- [8294]=4,
- [8295]=4,
- [8296]=4,
- [8297]=4,
- [8400]=5,
- [8401]=5,
- [8402]=5,
- [8403]=5,
- [8404]=5,
- [8405]=5,
- [8406]=5,
- [8407]=5,
- [8408]=5,
- [8409]=5,
- [8410]=5,
- [8411]=5,
- [8412]=5,
- [8417]=5,
- [8421]=5,
- [8422]=5,
- [8423]=5,
- [8424]=5,
- [8425]=5,
- [8426]=5,
- [8427]=5,
- [8428]=5,
- [8429]=5,
- [8430]=5,
- [8431]=5,
- [8432]=5,
- [11503]=5,
- [11504]=5,
- [11505]=5,
- [11647]=5,
- [11744]=5,
- [11745]=5,
- [11746]=5,
- [11747]=5,
- [11748]=5,
- [11749]=5,
- [11750]=5,
- [11751]=5,
- [11752]=5,
- [11753]=5,
- [11754]=5,
- [11755]=5,
- [11756]=5,
- [11757]=5,
- [11758]=5,
- [11759]=5,
- [11760]=5,
- [11761]=5,
- [11762]=5,
- [11763]=5,
- [11764]=5,
- [11765]=5,
- [11766]=5,
- [11767]=5,
- [11768]=5,
- [11769]=5,
- [11770]=5,
- [11771]=5,
- [11772]=5,
- [11773]=5,
- [11774]=5,
- [11775]=5,
- [12330]=5,
- [12331]=5,
- [12332]=5,
- [12333]=5,
- [12334]=5,
- [12335]=5,
- [12441]=5,
- [12442]=5,
- [42607]=5,
- [42612]=5,
- [42613]=5,
- [42614]=5,
- [42615]=5,
- [42616]=5,
- [42617]=5,
- [42618]=5,
- [42619]=5,
- [42620]=5,
- [42621]=5,
- [42654]=5,
- [42655]=5,
- [42736]=5,
- [42737]=5,
- [43014]=5,
- [43019]=5,
- [43045]=5,
- [43046]=5,
- [43072]=2,
- [43073]=2,
- [43074]=2,
- [43075]=2,
- [43076]=2,
- [43077]=2,
- [43078]=2,
- [43079]=2,
- [43080]=2,
- [43081]=2,
- [43082]=2,
- [43083]=2,
- [43084]=2,
- [43085]=2,
- [43086]=2,
- [43087]=2,
- [43088]=2,
- [43089]=2,
- [43090]=2,
- [43091]=2,
- [43092]=2,
- [43093]=2,
- [43094]=2,
- [43095]=2,
- [43096]=2,
- [43097]=2,
- [43098]=2,
- [43099]=2,
- [43100]=2,
- [43101]=2,
- [43102]=2,
- [43103]=2,
- [43104]=2,
- [43105]=2,
- [43106]=2,
- [43107]=2,
- [43108]=2,
- [43109]=2,
- [43110]=2,
- [43111]=2,
- [43112]=2,
- [43113]=2,
- [43114]=2,
- [43115]=2,
- [43116]=2,
- [43117]=2,
- [43118]=2,
- [43119]=2,
- [43120]=2,
- [43121]=2,
- [43122]=1,
- [43123]=4,
- [43204]=5,
- [43205]=5,
- [43232]=5,
- [43233]=5,
- [43234]=5,
- [43235]=5,
- [43236]=5,
- [43237]=5,
- [43238]=5,
- [43239]=5,
- [43240]=5,
- [43241]=5,
- [43242]=5,
- [43243]=5,
- [43244]=5,
- [43245]=5,
- [43246]=5,
- [43247]=5,
- [43248]=5,
- [43249]=5,
- [43302]=5,
- [43303]=5,
- [43304]=5,
- [43305]=5,
- [43306]=5,
- [43307]=5,
- [43308]=5,
- [43309]=5,
- [43335]=5,
- [43336]=5,
- [43337]=5,
- [43338]=5,
- [43339]=5,
- [43340]=5,
- [43341]=5,
- [43342]=5,
- [43343]=5,
- [43344]=5,
- [43345]=5,
- [43392]=5,
- [43393]=5,
- [43394]=5,
- [43443]=5,
- [43446]=5,
- [43447]=5,
- [43448]=5,
- [43449]=5,
- [43452]=5,
- [43493]=5,
- [43561]=5,
- [43562]=5,
- [43563]=5,
- [43564]=5,
- [43565]=5,
- [43566]=5,
- [43569]=5,
- [43570]=5,
- [43573]=5,
- [43574]=5,
- [43587]=5,
- [43596]=5,
- [43644]=5,
- [43696]=5,
- [43698]=5,
- [43699]=5,
- [43700]=5,
- [43703]=5,
- [43704]=5,
- [43710]=5,
- [43711]=5,
- [43713]=5,
- [43756]=5,
- [43757]=5,
- [43766]=5,
- [44005]=5,
- [44008]=5,
- [44013]=5,
- [64286]=5,
- [65056]=5,
- [65057]=5,
- [65058]=5,
- [65059]=5,
- [65060]=5,
- [65061]=5,
- [65062]=5,
- [65063]=5,
- [65064]=5,
- [65065]=5,
- [65066]=5,
- [65067]=5,
- [65068]=5,
- [65069]=5,
- [65070]=5,
- [65071]=5,
- [66045]=5,
- [66272]=5,
- [66422]=5,
- [66423]=5,
- [66424]=5,
- [66425]=5,
- [66426]=5,
- [68097]=5,
- [68098]=5,
- [68099]=5,
- [68101]=5,
- [68102]=5,
- [68108]=5,
- [68109]=5,
- [68110]=5,
- [68111]=5,
- [68152]=5,
- [68153]=5,
- [68154]=5,
- [68159]=5,
- [68288]=2,
- [68289]=2,
- [68290]=2,
- [68291]=2,
- [68292]=2,
- [68293]=3,
- [68294]=4,
- [68295]=3,
- [68296]=4,
- [68297]=3,
- [68298]=3,
- [68299]=4,
- [68300]=4,
- [68301]=1,
- [68302]=3,
- [68303]=3,
- [68304]=3,
- [68305]=3,
- [68306]=3,
- [68307]=2,
- [68308]=2,
- [68309]=2,
- [68310]=2,
- [68311]=1,
- [68312]=2,
- [68313]=2,
- [68314]=2,
- [68315]=2,
- [68316]=2,
- [68317]=3,
- [68318]=2,
- [68319]=2,
- [68320]=2,
- [68321]=3,
- [68322]=4,
- [68323]=4,
- [68324]=3,
- [68325]=5,
- [68326]=5,
- [68331]=2,
- [68332]=2,
- [68333]=2,
- [68334]=2,
- [68335]=3,
- [68480]=2,
- [68481]=3,
- [68482]=2,
- [68483]=3,
- [68484]=3,
- [68485]=3,
- [68486]=2,
- [68487]=2,
- [68488]=2,
- [68489]=3,
- [68490]=2,
- [68491]=2,
- [68492]=3,
- [68493]=2,
- [68494]=3,
- [68495]=3,
- [68496]=2,
- [68497]=3,
- [68521]=3,
- [68522]=3,
- [68523]=3,
- [68524]=3,
- [68525]=2,
- [68526]=2,
- [68527]=4,
- [69633]=5,
- [69688]=5,
- [69689]=5,
- [69690]=5,
- [69691]=5,
- [69692]=5,
- [69693]=5,
- [69694]=5,
- [69695]=5,
- [69696]=5,
- [69697]=5,
- [69698]=5,
- [69699]=5,
- [69700]=5,
- [69701]=5,
- [69702]=5,
- [69759]=5,
- [69760]=5,
- [69761]=5,
- [69811]=5,
- [69812]=5,
- [69813]=5,
- [69814]=5,
- [69817]=5,
- [69818]=5,
- [69888]=5,
- [69889]=5,
- [69890]=5,
- [69927]=5,
- [69928]=5,
- [69929]=5,
- [69930]=5,
- [69931]=5,
- [69933]=5,
- [69934]=5,
- [69935]=5,
- [69936]=5,
- [69937]=5,
- [69938]=5,
- [69939]=5,
- [69940]=5,
- [70003]=5,
- [70016]=5,
- [70017]=5,
- [70070]=5,
- [70071]=5,
- [70072]=5,
- [70073]=5,
- [70074]=5,
- [70075]=5,
- [70076]=5,
- [70077]=5,
- [70078]=5,
- [70090]=5,
- [70091]=5,
- [70092]=5,
- [70191]=5,
- [70192]=5,
- [70193]=5,
- [70196]=5,
- [70198]=5,
- [70199]=5,
- [70206]=5,
- [70367]=5,
- [70371]=5,
- [70372]=5,
- [70373]=5,
- [70374]=5,
- [70375]=5,
- [70376]=5,
- [70377]=5,
- [70378]=5,
- [70400]=5,
- [70401]=5,
- [70460]=5,
- [70464]=5,
- [70502]=5,
- [70503]=5,
- [70504]=5,
- [70505]=5,
- [70506]=5,
- [70507]=5,
- [70508]=5,
- [70512]=5,
- [70513]=5,
- [70514]=5,
- [70515]=5,
- [70516]=5,
- [70712]=5,
- [70713]=5,
- [70714]=5,
- [70715]=5,
- [70716]=5,
- [70717]=5,
- [70718]=5,
- [70719]=5,
- [70722]=5,
- [70723]=5,
- [70724]=5,
- [70726]=5,
- [70835]=5,
- [70836]=5,
- [70837]=5,
- [70838]=5,
- [70839]=5,
- [70840]=5,
- [70842]=5,
- [70847]=5,
- [70848]=5,
- [70850]=5,
- [70851]=5,
- [71090]=5,
- [71091]=5,
- [71092]=5,
- [71093]=5,
- [71100]=5,
- [71101]=5,
- [71103]=5,
- [71104]=5,
- [71132]=5,
- [71133]=5,
- [71219]=5,
- [71220]=5,
- [71221]=5,
- [71222]=5,
- [71223]=5,
- [71224]=5,
- [71225]=5,
- [71226]=5,
- [71229]=5,
- [71231]=5,
- [71232]=5,
- [71339]=5,
- [71341]=5,
- [71344]=5,
- [71345]=5,
- [71346]=5,
- [71347]=5,
- [71348]=5,
- [71349]=5,
- [71351]=5,
- [71453]=5,
- [71454]=5,
- [71455]=5,
- [71458]=5,
- [71459]=5,
- [71460]=5,
- [71461]=5,
- [71463]=5,
- [71464]=5,
- [71465]=5,
- [71466]=5,
- [71467]=5,
- [72193]=5,
- [72194]=5,
- [72195]=5,
- [72196]=5,
- [72197]=5,
- [72198]=5,
- [72201]=5,
- [72202]=5,
- [72243]=5,
- [72244]=5,
- [72245]=5,
- [72246]=5,
- [72247]=5,
- [72248]=5,
- [72251]=5,
- [72252]=5,
- [72253]=5,
- [72254]=5,
- [72263]=5,
- [72273]=5,
- [72274]=5,
- [72275]=5,
- [72276]=5,
- [72277]=5,
- [72278]=5,
- [72281]=5,
- [72282]=5,
- [72283]=5,
- [72330]=5,
- [72331]=5,
- [72332]=5,
- [72333]=5,
- [72334]=5,
- [72335]=5,
- [72336]=5,
- [72337]=5,
- [72338]=5,
- [72339]=5,
- [72340]=5,
- [72341]=5,
- [72342]=5,
- [72344]=5,
- [72345]=5,
- [72752]=5,
- [72753]=5,
- [72754]=5,
- [72755]=5,
- [72756]=5,
- [72757]=5,
- [72758]=5,
- [72760]=5,
- [72761]=5,
- [72762]=5,
- [72763]=5,
- [72764]=5,
- [72765]=5,
- [72767]=5,
- [72850]=5,
- [72851]=5,
- [72852]=5,
- [72853]=5,
- [72854]=5,
- [72855]=5,
- [72856]=5,
- [72857]=5,
- [72858]=5,
- [72859]=5,
- [72860]=5,
- [72861]=5,
- [72862]=5,
- [72863]=5,
- [72864]=5,
- [72865]=5,
- [72866]=5,
- [72867]=5,
- [72868]=5,
- [72869]=5,
- [72870]=5,
- [72871]=5,
- [72874]=5,
- [72875]=5,
- [72876]=5,
- [72877]=5,
- [72878]=5,
- [72879]=5,
- [72880]=5,
- [72882]=5,
- [72883]=5,
- [72885]=5,
- [72886]=5,
- [73009]=5,
- [73010]=5,
- [73011]=5,
- [73012]=5,
- [73013]=5,
- [73014]=5,
- [73018]=5,
- [73020]=5,
- [73021]=5,
- [73023]=5,
- [73024]=5,
- [73025]=5,
- [73026]=5,
- [73027]=5,
- [73028]=5,
- [73029]=5,
- [73031]=5,
- [92912]=5,
- [92913]=5,
- [92914]=5,
- [92915]=5,
- [92916]=5,
- [92976]=5,
- [92977]=5,
- [92978]=5,
- [92979]=5,
- [92980]=5,
- [92981]=5,
- [92982]=5,
- [94095]=5,
- [94096]=5,
- [94097]=5,
- [94098]=5,
- [113821]=5,
- [113822]=5,
- [119143]=5,
- [119144]=5,
- [119145]=5,
- [119163]=5,
- [119164]=5,
- [119165]=5,
- [119166]=5,
- [119167]=5,
- [119168]=5,
- [119169]=5,
- [119170]=5,
- [119173]=5,
- [119174]=5,
- [119175]=5,
- [119176]=5,
- [119177]=5,
- [119178]=5,
- [119179]=5,
- [119210]=5,
- [119211]=5,
- [119212]=5,
- [119213]=5,
- [119362]=5,
- [119363]=5,
- [119364]=5,
- [121344]=5,
- [121345]=5,
- [121346]=5,
- [121347]=5,
- [121348]=5,
- [121349]=5,
- [121350]=5,
- [121351]=5,
- [121352]=5,
- [121353]=5,
- [121354]=5,
- [121355]=5,
- [121356]=5,
- [121357]=5,
- [121358]=5,
- [121359]=5,
- [121360]=5,
- [121361]=5,
- [121362]=5,
- [121363]=5,
- [121364]=5,
- [121365]=5,
- [121366]=5,
- [121367]=5,
- [121368]=5,
- [121369]=5,
- [121370]=5,
- [121371]=5,
- [121372]=5,
- [121373]=5,
- [121374]=5,
- [121375]=5,
- [121376]=5,
- [121377]=5,
- [121378]=5,
- [121379]=5,
- [121380]=5,
- [121381]=5,
- [121382]=5,
- [121383]=5,
- [121384]=5,
- [121385]=5,
- [121386]=5,
- [121387]=5,
- [121388]=5,
- [121389]=5,
- [121390]=5,
- [121391]=5,
- [121392]=5,
- [121393]=5,
- [121394]=5,
- [121395]=5,
- [121396]=5,
- [121397]=5,
- [121398]=5,
- [121403]=5,
- [121404]=5,
- [121405]=5,
- [121406]=5,
- [121407]=5,
- [121408]=5,
- [121409]=5,
- [121410]=5,
- [121411]=5,
- [121412]=5,
- [121413]=5,
- [121414]=5,
- [121415]=5,
- [121416]=5,
- [121417]=5,
- [121418]=5,
- [121419]=5,
- [121420]=5,
- [121421]=5,
- [121422]=5,
- [121423]=5,
- [121424]=5,
- [121425]=5,
- [121426]=5,
- [121427]=5,
- [121428]=5,
- [121429]=5,
- [121430]=5,
- [121431]=5,
- [121432]=5,
- [121433]=5,
- [121434]=5,
- [121435]=5,
- [121436]=5,
- [121437]=5,
- [121438]=5,
- [121439]=5,
- [121440]=5,
- [121441]=5,
- [121442]=5,
- [121443]=5,
- [121444]=5,
- [121445]=5,
- [121446]=5,
- [121447]=5,
- [121448]=5,
- [121449]=5,
- [121450]=5,
- [121451]=5,
- [121452]=5,
- [121461]=5,
- [121476]=5,
- [121499]=5,
- [121500]=5,
- [121501]=5,
- [121502]=5,
- [121503]=5,
- [121505]=5,
- [121506]=5,
- [121507]=5,
- [121508]=5,
- [121509]=5,
- [121510]=5,
- [121511]=5,
- [121512]=5,
- [121513]=5,
- [121514]=5,
- [121515]=5,
- [121516]=5,
- [121517]=5,
- [121518]=5,
- [121519]=5,
- [122880]=5,
- [122881]=5,
- [122882]=5,
- [122883]=5,
- [122884]=5,
- [122885]=5,
- [122886]=5,
- [122888]=5,
- [122889]=5,
- [122890]=5,
- [122891]=5,
- [122892]=5,
- [122893]=5,
- [122894]=5,
- [122895]=5,
- [122896]=5,
- [122897]=5,
- [122898]=5,
- [122899]=5,
- [122900]=5,
- [122901]=5,
- [122902]=5,
- [122903]=5,
- [122904]=5,
- [122907]=5,
- [122908]=5,
- [122909]=5,
- [122910]=5,
- [122911]=5,
- [122912]=5,
- [122913]=5,
- [122915]=5,
- [122916]=5,
- [122918]=5,
- [122919]=5,
- [122920]=5,
- [122921]=5,
- [122922]=5,
- [125136]=5,
- [125137]=5,
- [125138]=5,
- [125139]=5,
- [125140]=5,
- [125141]=5,
- [125142]=5,
- [125184]=2,
- [125185]=2,
- [125186]=2,
- [125187]=2,
- [125188]=2,
- [125189]=2,
- [125190]=2,
- [125191]=2,
- [125192]=2,
- [125193]=2,
- [125194]=2,
- [125195]=2,
- [125196]=2,
- [125197]=2,
- [125198]=2,
- [125199]=2,
- [125200]=2,
- [125201]=2,
- [125202]=2,
- [125203]=2,
- [125204]=2,
- [125205]=2,
- [125206]=2,
- [125207]=2,
- [125208]=2,
- [125209]=2,
- [125210]=2,
- [125211]=2,
- [125212]=2,
- [125213]=2,
- [125214]=2,
- [125215]=2,
- [125216]=2,
- [125217]=2,
- [125218]=2,
- [125219]=2,
- [125220]=2,
- [125221]=2,
- [125222]=2,
- [125223]=2,
- [125224]=2,
- [125225]=2,
- [125226]=2,
- [125227]=2,
- [125228]=2,
- [125229]=2,
- [125230]=2,
- [125231]=2,
- [125232]=2,
- [125233]=2,
- [125234]=2,
- [125235]=2,
- [125236]=2,
- [125237]=2,
- [125238]=2,
- [125239]=2,
- [125240]=2,
- [125241]=2,
- [125242]=2,
- [125243]=2,
- [125244]=2,
- [125245]=2,
- [125246]=2,
- [125247]=2,
- [125248]=2,
- [125249]=2,
- [125250]=2,
- [125251]=2,
- [125252]=5,
- [125253]=5,
- [125254]=5,
- [125255]=5,
- [125256]=5,
- [125257]=5,
- [125258]=5,
- [1042752]=5,
-}
-characters.indicgroups={
- ["above_mark"]={
- [2304]=true,
- [2305]=true,
- [2306]=true,
- [2362]=true,
- [2373]=true,
- [2374]=true,
- [2375]=true,
- [2376]=true,
- [2385]=true,
- [2387]=true,
- [2388]=true,
- [2389]=true,
- [2631]=true,
- [2632]=true,
- [2635]=true,
- [2636]=true,
- [2757]=true,
- [2759]=true,
- [2760]=true,
- [2879]=true,
- [3008]=true,
- [3021]=true,
- [3134]=true,
- [3135]=true,
- [3136]=true,
- [3142]=true,
- [3143]=true,
- [3144]=true,
- [3146]=true,
- [3147]=true,
- [3148]=true,
- [3149]=true,
- [3263]=true,
- [3270]=true,
- [3406]=true,
- [43232]=true,
- [43233]=true,
- [43234]=true,
- [43235]=true,
- [43236]=true,
- [43237]=true,
- [43238]=true,
- [43239]=true,
- [43240]=true,
- [43241]=true,
- [43242]=true,
- [43243]=true,
- [43244]=true,
- [43245]=true,
- [43246]=true,
- [43247]=true,
- [43248]=true,
- [43249]=true,
- },
- ["after_half"]={},
- ["after_main"]={
- [2864]=true,
- [2879]=true,
- [2902]=true,
- [3376]=true,
- },
- ["after_postscript"]={
- [2433]=true,
- [2494]=true,
- [2496]=true,
- [2519]=true,
- [2561]=true,
- [2562]=true,
- [2622]=true,
- [2624]=true,
- [2625]=true,
- [2626]=true,
- [2672]=true,
- [2673]=true,
- [2750]=true,
- [2752]=true,
- [2753]=true,
- [2754]=true,
- [2755]=true,
- [2756]=true,
- [2761]=true,
- [2763]=true,
- [2764]=true,
- [2786]=true,
- [2787]=true,
- [2878]=true,
- [2880]=true,
- [2903]=true,
- [2992]=true,
- [3006]=true,
- [3007]=true,
- [3009]=true,
- [3010]=true,
- [3031]=true,
- [3120]=true,
- [3248]=true,
- [3390]=true,
- [3391]=true,
- [3392]=true,
- [3393]=true,
- [3394]=true,
- [3395]=true,
- [3415]=true,
- },
- ["after_subscript"]={
- [2366]=true,
- [2368]=true,
- [2369]=true,
- [2370]=true,
- [2371]=true,
- [2372]=true,
- [2373]=true,
- [2374]=true,
- [2375]=true,
- [2376]=true,
- [2377]=true,
- [2378]=true,
- [2379]=true,
- [2380]=true,
- [2402]=true,
- [2403]=true,
- [2480]=true,
- [2497]=true,
- [2498]=true,
- [2499]=true,
- [2500]=true,
- [2530]=true,
- [2531]=true,
- [2544]=true,
- [2631]=true,
- [2632]=true,
- [2635]=true,
- [2636]=true,
- [2757]=true,
- [2759]=true,
- [2760]=true,
- [2881]=true,
- [2882]=true,
- [2883]=true,
- [3008]=true,
- [3139]=true,
- [3140]=true,
- [3267]=true,
- [3268]=true,
- [3285]=true,
- [3286]=true,
- },
- ["anudatta"]={
- [2386]=true,
- },
- ["before_half"]={
- [2367]=true,
- [2382]=true,
- [2495]=true,
- [2503]=true,
- [2504]=true,
- [2623]=true,
- [2751]=true,
- [2887]=true,
- },
- ["before_main"]={
- [3014]=true,
- [3015]=true,
- [3016]=true,
- [3398]=true,
- [3399]=true,
- [3400]=true,
- },
- ["before_postscript"]={
- [2352]=true,
- [2736]=true,
- },
- ["before_subscript"]={
- [2608]=true,
- [2817]=true,
- [3134]=true,
- [3135]=true,
- [3136]=true,
- [3137]=true,
- [3138]=true,
- [3142]=true,
- [3143]=true,
- [3146]=true,
- [3147]=true,
- [3148]=true,
- [3157]=true,
- [3158]=true,
- [3262]=true,
- [3263]=true,
- [3265]=true,
- [3266]=true,
- [3270]=true,
- [3276]=true,
- [3298]=true,
- [3299]=true,
- },
- ["below_mark"]={
- [2364]=true,
- [2369]=true,
- [2370]=true,
- [2371]=true,
- [2372]=true,
- [2381]=true,
- [2386]=true,
- [2390]=true,
- [2391]=true,
- [2402]=true,
- [2403]=true,
- [2492]=true,
- [2497]=true,
- [2498]=true,
- [2499]=true,
- [2500]=true,
- [2509]=true,
- [2620]=true,
- [2625]=true,
- [2626]=true,
- [2637]=true,
- [2748]=true,
- [2753]=true,
- [2754]=true,
- [2755]=true,
- [2756]=true,
- [2765]=true,
- [2876]=true,
- [2881]=true,
- [2882]=true,
- [2883]=true,
- [2884]=true,
- [2893]=true,
- [2914]=true,
- [2915]=true,
- [3009]=true,
- [3010]=true,
- [3170]=true,
- [3171]=true,
- [3260]=true,
- [3298]=true,
- [3299]=true,
- [3426]=true,
- [3427]=true,
- },
- ["consonant"]={
- [2325]=true,
- [2326]=true,
- [2327]=true,
- [2328]=true,
- [2329]=true,
- [2330]=true,
- [2331]=true,
- [2332]=true,
- [2333]=true,
- [2334]=true,
- [2335]=true,
- [2336]=true,
- [2337]=true,
- [2338]=true,
- [2339]=true,
- [2340]=true,
- [2341]=true,
- [2342]=true,
- [2343]=true,
- [2344]=true,
- [2345]=true,
- [2346]=true,
- [2347]=true,
- [2348]=true,
- [2349]=true,
- [2350]=true,
- [2351]=true,
- [2352]=true,
- [2353]=true,
- [2354]=true,
- [2355]=true,
- [2356]=true,
- [2357]=true,
- [2358]=true,
- [2359]=true,
- [2360]=true,
- [2361]=true,
- [2392]=true,
- [2393]=true,
- [2394]=true,
- [2395]=true,
- [2396]=true,
- [2397]=true,
- [2398]=true,
- [2399]=true,
- [2424]=true,
- [2425]=true,
- [2426]=true,
- [2453]=true,
- [2454]=true,
- [2455]=true,
- [2456]=true,
- [2457]=true,
- [2458]=true,
- [2459]=true,
- [2460]=true,
- [2461]=true,
- [2462]=true,
- [2463]=true,
- [2464]=true,
- [2465]=true,
- [2466]=true,
- [2467]=true,
- [2468]=true,
- [2469]=true,
- [2470]=true,
- [2471]=true,
- [2472]=true,
- [2474]=true,
- [2475]=true,
- [2476]=true,
- [2477]=true,
- [2478]=true,
- [2479]=true,
- [2480]=true,
- [2482]=true,
- [2486]=true,
- [2487]=true,
- [2488]=true,
- [2489]=true,
- [2510]=true,
- [2524]=true,
- [2525]=true,
- [2527]=true,
- [2581]=true,
- [2582]=true,
- [2583]=true,
- [2584]=true,
- [2585]=true,
- [2586]=true,
- [2587]=true,
- [2588]=true,
- [2589]=true,
- [2590]=true,
- [2591]=true,
- [2592]=true,
- [2593]=true,
- [2594]=true,
- [2595]=true,
- [2596]=true,
- [2597]=true,
- [2598]=true,
- [2599]=true,
- [2600]=true,
- [2602]=true,
- [2603]=true,
- [2604]=true,
- [2605]=true,
- [2606]=true,
- [2607]=true,
- [2608]=true,
- [2610]=true,
- [2611]=true,
- [2613]=true,
- [2614]=true,
- [2616]=true,
- [2617]=true,
- [2649]=true,
- [2650]=true,
- [2651]=true,
- [2652]=true,
- [2654]=true,
- [2709]=true,
- [2710]=true,
- [2711]=true,
- [2712]=true,
- [2713]=true,
- [2714]=true,
- [2715]=true,
- [2716]=true,
- [2717]=true,
- [2718]=true,
- [2719]=true,
- [2720]=true,
- [2721]=true,
- [2722]=true,
- [2723]=true,
- [2724]=true,
- [2725]=true,
- [2726]=true,
- [2727]=true,
- [2728]=true,
- [2730]=true,
- [2731]=true,
- [2732]=true,
- [2733]=true,
- [2734]=true,
- [2735]=true,
- [2736]=true,
- [2738]=true,
- [2739]=true,
- [2741]=true,
- [2742]=true,
- [2743]=true,
- [2744]=true,
- [2745]=true,
- [2837]=true,
- [2838]=true,
- [2839]=true,
- [2840]=true,
- [2841]=true,
- [2842]=true,
- [2843]=true,
- [2844]=true,
- [2845]=true,
- [2846]=true,
- [2847]=true,
- [2848]=true,
- [2849]=true,
- [2850]=true,
- [2851]=true,
- [2852]=true,
- [2853]=true,
- [2854]=true,
- [2855]=true,
- [2856]=true,
- [2858]=true,
- [2859]=true,
- [2860]=true,
- [2861]=true,
- [2862]=true,
- [2863]=true,
- [2864]=true,
- [2866]=true,
- [2867]=true,
- [2869]=true,
- [2870]=true,
- [2871]=true,
- [2872]=true,
- [2873]=true,
- [2908]=true,
- [2909]=true,
- [2929]=true,
- [2965]=true,
- [2969]=true,
- [2970]=true,
- [2972]=true,
- [2974]=true,
- [2975]=true,
- [2979]=true,
- [2980]=true,
- [2984]=true,
- [2985]=true,
- [2986]=true,
- [2990]=true,
- [2991]=true,
- [2992]=true,
- [2993]=true,
- [2994]=true,
- [2995]=true,
- [2996]=true,
- [2997]=true,
- [2998]=true,
- [2999]=true,
- [3000]=true,
- [3001]=true,
- [3093]=true,
- [3094]=true,
- [3095]=true,
- [3096]=true,
- [3097]=true,
- [3098]=true,
- [3099]=true,
- [3100]=true,
- [3101]=true,
- [3102]=true,
- [3103]=true,
- [3104]=true,
- [3105]=true,
- [3106]=true,
- [3107]=true,
- [3108]=true,
- [3109]=true,
- [3110]=true,
- [3111]=true,
- [3112]=true,
- [3114]=true,
- [3115]=true,
- [3116]=true,
- [3117]=true,
- [3118]=true,
- [3119]=true,
- [3120]=true,
- [3121]=true,
- [3122]=true,
- [3123]=true,
- [3124]=true,
- [3125]=true,
- [3126]=true,
- [3127]=true,
- [3128]=true,
- [3129]=true,
- [3133]=true,
- [3221]=true,
- [3222]=true,
- [3223]=true,
- [3224]=true,
- [3225]=true,
- [3226]=true,
- [3227]=true,
- [3228]=true,
- [3229]=true,
- [3230]=true,
- [3231]=true,
- [3232]=true,
- [3233]=true,
- [3234]=true,
- [3235]=true,
- [3236]=true,
- [3237]=true,
- [3238]=true,
- [3239]=true,
- [3240]=true,
- [3242]=true,
- [3243]=true,
- [3244]=true,
- [3245]=true,
- [3246]=true,
- [3247]=true,
- [3248]=true,
- [3249]=true,
- [3250]=true,
- [3251]=true,
- [3253]=true,
- [3254]=true,
- [3255]=true,
- [3256]=true,
- [3257]=true,
- [3294]=true,
- [3349]=true,
- [3350]=true,
- [3351]=true,
- [3352]=true,
- [3353]=true,
- [3354]=true,
- [3355]=true,
- [3356]=true,
- [3357]=true,
- [3358]=true,
- [3359]=true,
- [3360]=true,
- [3361]=true,
- [3362]=true,
- [3363]=true,
- [3364]=true,
- [3365]=true,
- [3366]=true,
- [3367]=true,
- [3368]=true,
- [3369]=true,
- [3370]=true,
- [3371]=true,
- [3372]=true,
- [3373]=true,
- [3374]=true,
- [3375]=true,
- [3376]=true,
- [3377]=true,
- [3378]=true,
- [3379]=true,
- [3380]=true,
- [3381]=true,
- [3382]=true,
- [3383]=true,
- [3384]=true,
- [3385]=true,
- [3386]=true,
- },
- ["dependent_vowel"]={
- [2362]=true,
- [2363]=true,
- [2366]=true,
- [2367]=true,
- [2368]=true,
- [2369]=true,
- [2370]=true,
- [2371]=true,
- [2372]=true,
- [2373]=true,
- [2374]=true,
- [2375]=true,
- [2376]=true,
- [2377]=true,
- [2378]=true,
- [2379]=true,
- [2380]=true,
- [2382]=true,
- [2383]=true,
- [2389]=true,
- [2390]=true,
- [2391]=true,
- [2402]=true,
- [2403]=true,
- [2494]=true,
- [2495]=true,
- [2496]=true,
- [2497]=true,
- [2498]=true,
- [2499]=true,
- [2500]=true,
- [2503]=true,
- [2504]=true,
- [2622]=true,
- [2623]=true,
- [2624]=true,
- [2625]=true,
- [2626]=true,
- [2631]=true,
- [2632]=true,
- [2635]=true,
- [2636]=true,
- [2750]=true,
- [2751]=true,
- [2752]=true,
- [2753]=true,
- [2754]=true,
- [2755]=true,
- [2756]=true,
- [2757]=true,
- [2759]=true,
- [2760]=true,
- [2761]=true,
- [2763]=true,
- [2764]=true,
- [2878]=true,
- [2879]=true,
- [2880]=true,
- [2881]=true,
- [2882]=true,
- [2883]=true,
- [2884]=true,
- [2887]=true,
- [2888]=true,
- [2891]=true,
- [2892]=true,
- [2914]=true,
- [2915]=true,
- [3006]=true,
- [3007]=true,
- [3008]=true,
- [3009]=true,
- [3010]=true,
- [3014]=true,
- [3015]=true,
- [3016]=true,
- [3018]=true,
- [3019]=true,
- [3020]=true,
- [3134]=true,
- [3135]=true,
- [3136]=true,
- [3137]=true,
- [3138]=true,
- [3139]=true,
- [3140]=true,
- [3142]=true,
- [3143]=true,
- [3144]=true,
- [3146]=true,
- [3147]=true,
- [3148]=true,
- [3170]=true,
- [3171]=true,
- [3262]=true,
- [3263]=true,
- [3264]=true,
- [3265]=true,
- [3266]=true,
- [3267]=true,
- [3268]=true,
- [3270]=true,
- [3271]=true,
- [3272]=true,
- [3274]=true,
- [3275]=true,
- [3276]=true,
- [3298]=true,
- [3299]=true,
- [3390]=true,
- [3391]=true,
- [3392]=true,
- [3393]=true,
- [3394]=true,
- [3395]=true,
- [3396]=true,
- [3398]=true,
- [3399]=true,
- [3400]=true,
- [3402]=true,
- [3403]=true,
- [3404]=true,
- [3415]=true,
- [3426]=true,
- [3427]=true,
- },
- ["halant"]={
- [2381]=true,
- [2509]=true,
- [2637]=true,
- [2765]=true,
- [2893]=true,
- [3021]=true,
- [3149]=true,
- [3277]=true,
- [3405]=true,
- },
- ["independent_vowel"]={
- [2308]=true,
- [2309]=true,
- [2310]=true,
- [2311]=true,
- [2312]=true,
- [2313]=true,
- [2314]=true,
- [2315]=true,
- [2316]=true,
- [2317]=true,
- [2318]=true,
- [2319]=true,
- [2320]=true,
- [2321]=true,
- [2322]=true,
- [2323]=true,
- [2324]=true,
- [2400]=true,
- [2401]=true,
- [2418]=true,
- [2419]=true,
- [2420]=true,
- [2421]=true,
- [2422]=true,
- [2423]=true,
- [2437]=true,
- [2438]=true,
- [2439]=true,
- [2440]=true,
- [2441]=true,
- [2442]=true,
- [2443]=true,
- [2444]=true,
- [2447]=true,
- [2448]=true,
- [2451]=true,
- [2452]=true,
- [2528]=true,
- [2529]=true,
- [2530]=true,
- [2531]=true,
- [2565]=true,
- [2566]=true,
- [2567]=true,
- [2568]=true,
- [2569]=true,
- [2570]=true,
- [2575]=true,
- [2576]=true,
- [2579]=true,
- [2580]=true,
- [2693]=true,
- [2694]=true,
- [2695]=true,
- [2696]=true,
- [2697]=true,
- [2698]=true,
- [2699]=true,
- [2700]=true,
- [2701]=true,
- [2703]=true,
- [2704]=true,
- [2705]=true,
- [2707]=true,
- [2708]=true,
- [2784]=true,
- [2785]=true,
- [2786]=true,
- [2787]=true,
- [2821]=true,
- [2822]=true,
- [2823]=true,
- [2824]=true,
- [2825]=true,
- [2826]=true,
- [2827]=true,
- [2828]=true,
- [2831]=true,
- [2832]=true,
- [2835]=true,
- [2836]=true,
- [2912]=true,
- [2913]=true,
- [2949]=true,
- [2950]=true,
- [2951]=true,
- [2952]=true,
- [2953]=true,
- [2954]=true,
- [2958]=true,
- [2959]=true,
- [2960]=true,
- [2962]=true,
- [2963]=true,
- [2964]=true,
- [3077]=true,
- [3078]=true,
- [3079]=true,
- [3080]=true,
- [3081]=true,
- [3082]=true,
- [3083]=true,
- [3084]=true,
- [3086]=true,
- [3087]=true,
- [3088]=true,
- [3090]=true,
- [3091]=true,
- [3092]=true,
- [3168]=true,
- [3169]=true,
- [3205]=true,
- [3206]=true,
- [3207]=true,
- [3208]=true,
- [3209]=true,
- [3210]=true,
- [3211]=true,
- [3212]=true,
- [3214]=true,
- [3215]=true,
- [3216]=true,
- [3218]=true,
- [3219]=true,
- [3220]=true,
- [3296]=true,
- [3297]=true,
- [3333]=true,
- [3334]=true,
- [3335]=true,
- [3336]=true,
- [3337]=true,
- [3338]=true,
- [3339]=true,
- [3340]=true,
- [3342]=true,
- [3343]=true,
- [3344]=true,
- [3346]=true,
- [3347]=true,
- [3348]=true,
- [3423]=true,
- [3424]=true,
- [3425]=true,
- },
- ["nukta"]={
- [2364]=true,
- [2492]=true,
- [2620]=true,
- [2748]=true,
- [2876]=true,
- [3260]=true,
- },
- ["post_mark"]={
- [2307]=true,
- [2363]=true,
- [2366]=true,
- [2368]=true,
- [2377]=true,
- [2378]=true,
- [2379]=true,
- [2380]=true,
- [2383]=true,
- [2494]=true,
- [2496]=true,
- [2503]=true,
- [2504]=true,
- [2622]=true,
- [2624]=true,
- [2750]=true,
- [2752]=true,
- [2761]=true,
- [2763]=true,
- [2764]=true,
- [2878]=true,
- [2880]=true,
- [3006]=true,
- [3007]=true,
- [3137]=true,
- [3138]=true,
- [3139]=true,
- [3140]=true,
- [3262]=true,
- [3264]=true,
- [3265]=true,
- [3266]=true,
- [3267]=true,
- [3268]=true,
- [3271]=true,
- [3272]=true,
- [3274]=true,
- [3275]=true,
- [3276]=true,
- [3390]=true,
- [3391]=true,
- [3392]=true,
- [3393]=true,
- [3394]=true,
- [3395]=true,
- [3396]=true,
- [3415]=true,
- },
- ["pre_mark"]={
- [2367]=true,
- [2382]=true,
- [2495]=true,
- [2623]=true,
- [2751]=true,
- [2887]=true,
- [2888]=true,
- [3014]=true,
- [3015]=true,
- [3016]=true,
- [3398]=true,
- [3399]=true,
- [3400]=true,
- },
- ["ra"]={
- [2352]=true,
- [2480]=true,
- [2608]=true,
- [2736]=true,
- [2864]=true,
- [2992]=true,
- [3120]=true,
- [3248]=true,
- [3376]=true,
- },
- ["stress_tone_mark"]={
- [2385]=true,
- [2386]=true,
- [2387]=true,
- [2388]=true,
- [2507]=true,
- [2508]=true,
- [3277]=true,
- [3405]=true,
- },
- ["twopart_mark"]={
- [2891]={ 2887,2878 },
- [2892]={ 2887,2903 },
- [3018]={ 3014,3006 },
- [3019]={ 3015,3006 },
- [3020]={ 3014,3031 },
- [3402]={ 3398,3390 },
- [3403]={ 3399,3390 },
- [3404]={ 3398,3415 },
- },
- ["vowel_modifier"]={
- [2304]=true,
- [2305]=true,
- [2306]=true,
- [2307]=true,
- [3330]=true,
- [3331]=true,
- [43232]=true,
- [43233]=true,
- [43234]=true,
- [43235]=true,
- [43236]=true,
- [43237]=true,
- [43238]=true,
- [43239]=true,
- [43240]=true,
- [43241]=true,
- [43242]=true,
- [43243]=true,
- [43244]=true,
- [43245]=true,
- [43246]=true,
- [43247]=true,
- [43248]=true,
- [43249]=true,
- },
-}
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “basics-chr”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-ini” 4299a02110bbd7c0d27e131235c5319d] ---
-
-if not modules then modules={} end modules ['font-ini']={
-  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"
-}
-local allocate=utilities.storage.allocate
-local sortedhash=table.sortedhash
-fonts=fonts or {}
-local fonts=fonts
-local identifiers=allocate()
-fonts.hashes=fonts.hashes   or { identifiers=identifiers }
-fonts.tables=fonts.tables   or {}
-fonts.helpers=fonts.helpers  or {}
-fonts.tracers=fonts.tracers  or {} 
-fonts.specifiers=fonts.specifiers or {} 
-fonts.analyzers={} 
-fonts.readers={}
-fonts.definers={ methods={} }
-fonts.loggers={ register=function() end }
-if context then
-  font.originaleach=font.each
-  function font.each()
-    return sortedhash(identifiers)
-  end
-  fontloader=nil
-end
-fonts.privateoffsets={
-  textbase=0xF0000,
-  textextrabase=0xFD000,
-  mathextrabase=0xFE000,
-  mathbase=0xFF000,
-  keepnames=false,
-}
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-ini”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] ---
-
-if not modules then modules={} end modules ['luatex-font-mis']={
-  version=1.001,
-  comment="companion to luatex-*.tex",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  os.exit()
-end
-local currentfont=font.current
-local hashes=fonts.hashes
-local identifiers=hashes.identifiers or {}
-local marks=hashes.marks    or {}
-hashes.identifiers=identifiers
-hashes.marks=marks
-table.setmetatableindex(marks,function(t,k)
-  if k==true then
-    return marks[currentfont()]
-  else
-    local resources=identifiers[k].resources or {}
-    local marks=resources.marks or {}
-    t[k]=marks
-    return marks
-  end
-end)
-function font.each()
-  return table.sortedhash(fonts.hashes.identifiers)
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “fonts-mis”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-con” 6308f40e1b4fecfbe05b01c571d46936] ---
-
-if not modules then modules={} end modules ['font-con']={
-  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"
-}
-local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget
-local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find
-local sort,insert,concat=table.sort,table.insert,table.concat
-local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy
-local derivetable=table.derive
-local ioflush=io.flush
-local round=math.round
-local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
-local report_defining=logs.reporter("fonts","defining")
-local fonts=fonts
-local constructors=fonts.constructors or {}
-fonts.constructors=constructors
-local handlers=fonts.handlers or {} 
-fonts.handlers=handlers
-local allocate=utilities.storage.allocate
-local setmetatableindex=table.setmetatableindex
-constructors.dontembed=allocate()
-constructors.autocleanup=true
-constructors.namemode="fullpath" 
-constructors.version=1.01
-constructors.cache=containers.define("fonts","constructors",constructors.version,false)
-constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000
-constructors.cacheintex=true
-local designsizes=allocate()
-constructors.designsizes=designsizes
-local loadedfonts=allocate()
-constructors.loadedfonts=loadedfonts
-local factors={
-  pt=65536.0,
-  bp=65781.8,
-}
-function constructors.setfactor(f)
-  constructors.factor=factors[f or 'pt'] or factors.pt
-end
-constructors.setfactor()
-function constructors.scaled(scaledpoints,designsize) 
-  if scaledpoints<0 then
-    local factor=constructors.factor
-    if designsize then
-      if designsize>factor then 
-        return (- scaledpoints/1000)*designsize 
-      else
-        return (- scaledpoints/1000)*designsize*factor
-      end
-    else
-      return (- scaledpoints/1000)*10*factor
-    end
-  else
-    return scaledpoints
-  end
-end
-function constructors.getprivate(tfmdata)
-  local properties=tfmdata.properties
-  local private=properties.private
-  properties.private=private+1
-  return private
-end
-function constructors.setmathparameter(tfmdata,name,value)
-  local m=tfmdata.mathparameters
-  local c=tfmdata.MathConstants
-  if m then
-    m[name]=value
-  end
-  if c and c~=m then
-    c[name]=value
-  end
-end
-function constructors.getmathparameter(tfmdata,name)
-  local p=tfmdata.mathparameters or tfmdata.MathConstants
-  if p then
-    return p[name]
-  end
-end
-function constructors.cleanuptable(tfmdata)
-  if constructors.autocleanup and tfmdata.properties.virtualized then
-    for k,v in next,tfmdata.characters do
-      if v.commands then v.commands=nil end
-    end
-  end
-end
-function constructors.calculatescale(tfmdata,scaledpoints)
-  local parameters=tfmdata.parameters
-  if scaledpoints<0 then
-    scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) 
-  end
-  return scaledpoints,scaledpoints/(parameters.units or 1000) 
-end
-local unscaled={
-  ScriptPercentScaleDown=true,
-  ScriptScriptPercentScaleDown=true,
-  RadicalDegreeBottomRaisePercent=true,
-  NoLimitSupFactor=true,
-  NoLimitSubFactor=true,
-}
-function constructors.assignmathparameters(target,original)
-  local mathparameters=original.mathparameters
-  if mathparameters and next(mathparameters) then
-    local targetparameters=target.parameters
-    local targetproperties=target.properties
-    local targetmathparameters={}
-    local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
-    for name,value in next,mathparameters do
-      if unscaled[name] then
-        targetmathparameters[name]=value
-      else
-        targetmathparameters[name]=value*factor
-      end
-    end
-    if not targetmathparameters.FractionDelimiterSize then
-      targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
-    end
-    if not mathparameters.FractionDelimiterDisplayStyleSize then
-      targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
-    end
-    target.mathparameters=targetmathparameters
-  end
-end
-function constructors.beforecopyingcharacters(target,original)
-end
-function constructors.aftercopyingcharacters(target,original)
-end
-constructors.sharefonts=false
-constructors.nofsharedfonts=0
-local sharednames={}
-function constructors.trytosharefont(target,tfmdata)
-  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[k].index or k
-    end
-    local h=md5.HEX(concat(t," "))
-    local s=sharednames[h]
-    if s then
-      if trace_defining then
-        report_defining("font %a uses backend resources of font %a",target.fullname,s)
-      end
-      target.fullname=s
-      constructors.nofsharedfonts=constructors.nofsharedfonts+1
-      target.properties.sharedwith=s
-    else
-      sharednames[h]=target.fullname
-    end
-  end
-end
-local synonyms={
-  exheight="x_height",
-  xheight="x_height",
-  ex="x_height",
-  emwidth="quad",
-  em="quad",
-  spacestretch="space_stretch",
-  stretch="space_stretch",
-  spaceshrink="space_shrink",
-  shrink="space_shrink",
-  extraspace="extra_space",
-  xspace="extra_space",
-  slantperpoint="slant",
-}
-function constructors.enhanceparameters(parameters)
-  local mt=getmetatable(parameters)
-  local getter=function(t,k)
-    if not k then
-      return nil
-    end
-    local s=synonyms[k]
-    if s then
-      return rawget(t,s) or (mt and mt[s]) or nil
-    end
-    if k=="spacing" then
-      return {
-        width=t.space,
-        stretch=t.space_stretch,
-        shrink=t.space_shrink,
-        extra=t.extra_space,
-      }
-    end
-    return mt and mt[k] or nil
-  end
-  local setter=function(t,k,v)
-    if not k then
-      return 0
-    end
-    local s=synonyms[k]
-    if s then
-      rawset(t,s,v)
-    elseif k=="spacing" then
-      if type(v)=="table" then
-        rawset(t,"space",v.width or 0)
-        rawset(t,"space_stretch",v.stretch or 0)
-        rawset(t,"space_shrink",v.shrink or 0)
-        rawset(t,"extra_space",v.extra or 0)
-      end
-    else
-      rawset(t,k,v)
-    end
-  end
-  setmetatable(parameters,{
-    __index=getter,
-    __newindex=setter,
-  })
-end
-local function mathkerns(v,vdelta)
-  local k={}
-  for i=1,#v do
-    local entry=v[i]
-    local height=entry.height
-    local kern=entry.kern
-    k[i]={
-      height=height and vdelta*height or 0,
-      kern=kern  and vdelta*kern  or 0,
-    }
-  end
-  return k
-end
-local psfake=0
-local function fixedpsname(psname,fallback)
-  local usedname=psname
-  if psname and psname~="" then
-    if find(psname," ",1,true) then
-      usedname=gsub(psname,"[%s]+","-")
-    else
-    end
-  elseif not fallback or fallback=="" then
-    psfake=psfake+1
-    psname="fakename-"..psfake
-  else
-    psname=fallback
-    usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
-  end
-  return usedname,psname~=usedname
-end
-function constructors.scale(tfmdata,specification)
-  local target={}
-  if tonumber(specification) then
-    specification={ size=specification }
-  end
-  target.specification=specification
-  local scaledpoints=specification.size
-  local relativeid=specification.relativeid
-  local properties=tfmdata.properties   or {}
-  local goodies=tfmdata.goodies    or {}
-  local resources=tfmdata.resources   or {}
-  local descriptions=tfmdata.descriptions  or {} 
-  local characters=tfmdata.characters   or {} 
-  local changed=tfmdata.changed    or {} 
-  local shared=tfmdata.shared     or {}
-  local parameters=tfmdata.parameters   or {}
-  local mathparameters=tfmdata.mathparameters or {}
-  local targetcharacters={}
-  local targetdescriptions=derivetable(descriptions)
-  local targetparameters=derivetable(parameters)
-  local targetproperties=derivetable(properties)
-  local targetgoodies=goodies            
-  target.characters=targetcharacters
-  target.descriptions=targetdescriptions
-  target.parameters=targetparameters
-  target.properties=targetproperties
-  target.goodies=targetgoodies
-  target.shared=shared
-  target.resources=resources
-  target.unscaled=tfmdata
-  local mathsize=tonumber(specification.mathsize) or 0
-  local textsize=tonumber(specification.textsize) or scaledpoints
-  local forcedsize=tonumber(parameters.mathsize  ) or 0 
-  local extrafactor=tonumber(specification.factor ) or 1
-  if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
-    scaledpoints=parameters.scriptpercentage*textsize/100
-  elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
-    scaledpoints=parameters.scriptscriptpercentage*textsize/100
-  elseif forcedsize>1000 then 
-    scaledpoints=forcedsize
-  else
-  end
-  targetparameters.mathsize=mathsize  
-  targetparameters.textsize=textsize  
-  targetparameters.forcedsize=forcedsize 
-  targetparameters.extrafactor=extrafactor
-  local tounicode=fonts.mappings.tounicode
-  local unknowncode=tounicode(0xFFFD)
-  local defaultwidth=resources.defaultwidth or 0
-  local defaultheight=resources.defaultheight or 0
-  local defaultdepth=resources.defaultdepth or 0
-  local units=parameters.units or 1000
-  targetproperties.language=properties.language or "dflt" 
-  targetproperties.script=properties.script  or "dflt" 
-  targetproperties.mode=properties.mode   or "base"
-  local askedscaledpoints=scaledpoints
-  local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
-  local hdelta=delta
-  local vdelta=delta
-  target.designsize=parameters.designsize 
-  target.units=units
-  target.units_per_em=units
-  local direction=properties.direction or tfmdata.direction or 0 
-  target.direction=direction
-  properties.direction=direction
-  target.size=scaledpoints
-  target.encodingbytes=properties.encodingbytes or 1
-  target.embedding=properties.embedding or "subset"
-  target.tounicode=1
-  target.cidinfo=properties.cidinfo
-  target.format=properties.format
-  target.cache=constructors.cacheintex and "yes" or "renew"
-  local fontname=properties.fontname or tfmdata.fontname
-  local fullname=properties.fullname or tfmdata.fullname
-  local filename=properties.filename or tfmdata.filename
-  local psname=properties.psname  or tfmdata.psname
-  local name=properties.name   or tfmdata.name
-  local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
-  target.fontname=fontname
-  target.fullname=fullname
-  target.filename=filename
-  target.psname=psname
-  target.name=name
-  properties.fontname=fontname
-  properties.fullname=fullname
-  properties.filename=filename
-  properties.psname=psname
-  properties.name=name
-  local expansion=parameters.expansion
-  if expansion then
-    target.stretch=expansion.stretch
-    target.shrink=expansion.shrink
-    target.step=expansion.step
-  end
-  local slantfactor=parameters.slantfactor or 0
-  if slantfactor~=0 then
-    target.slant=slantfactor*1000
-  else
-    target.slant=0
-  end
-  local extendfactor=parameters.extendfactor or 0
-  if extendfactor~=0 and extendfactor~=1 then
-    hdelta=hdelta*extendfactor
-    target.extend=extendfactor*1000
-  else
-    target.extend=1000 
-  end
-  local squeezefactor=parameters.squeezefactor or 0
-  if squeezefactor~=0 and squeezefactor~=1 then
-    vdelta=vdelta*squeezefactor
-    target.squeeze=squeezefactor*1000
-  else
-    target.squeeze=1000 
-  end
-  local mode=parameters.mode or 0
-  if mode~=0 then
-    target.mode=mode
-  end
-  local width=parameters.width or 0
-  if width~=0 then
-    target.width=width*delta*1000/655360
-  end
-  targetparameters.factor=delta
-  targetparameters.hfactor=hdelta
-  targetparameters.vfactor=vdelta
-  targetparameters.size=scaledpoints
-  targetparameters.units=units
-  targetparameters.scaledpoints=askedscaledpoints
-  targetparameters.mode=mode
-  targetparameters.width=width
-  local isvirtual=properties.virtualized or tfmdata.type=="virtual"
-  local hasquality=parameters.expansion or parameters.protrusion
-  local hasitalics=properties.hasitalics
-  local autoitalicamount=properties.autoitalicamount
-  local stackmath=not properties.nostackmath
-  local nonames=properties.noglyphnames
-  local haskerns=properties.haskerns   or properties.mode=="base" 
-  local hasligatures=properties.hasligatures or properties.mode=="base" 
-  local realdimensions=properties.realdimensions
-  local writingmode=properties.writingmode or "horizontal"
-  local identity=properties.identity or "horizontal"
-  local vfonts=target.fonts
-  if vfonts and #vfonts>0 then
-    target.fonts=fastcopy(vfonts) 
-  elseif isvirtual then
-    target.fonts={ { id=0 } } 
-  end
-  if changed and not next(changed) then
-    changed=false
-  end
-  target.type=isvirtual and "virtual" or "real"
-  target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
-  target.identity=identity=="vertical" and "vertical" or "horizontal"
-  target.postprocessors=tfmdata.postprocessors
-  local targetslant=(parameters.slant     or parameters[1] or 0)*factors.pt 
-  local targetspace=(parameters.space     or parameters[2] or 0)*hdelta
-  local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
-  local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
-  local targetx_height=(parameters.x_height   or parameters[5] or 0)*vdelta
-  local targetquad=(parameters.quad     or parameters[6] or 0)*hdelta
-  local targetextra_space=(parameters.extra_space  or parameters[7] or 0)*hdelta
-  targetparameters.slant=targetslant 
-  targetparameters.space=targetspace
-  targetparameters.space_stretch=targetspace_stretch
-  targetparameters.space_shrink=targetspace_shrink
-  targetparameters.x_height=targetx_height
-  targetparameters.quad=targetquad
-  targetparameters.extra_space=targetextra_space
-  local ascender=parameters.ascender
-  if ascender then
-    targetparameters.ascender=delta*ascender
-  end
-  local descender=parameters.descender
-  if descender then
-    targetparameters.descender=delta*descender
-  end
-  constructors.enhanceparameters(targetparameters)
-  local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
-  local scaledwidth=defaultwidth*hdelta
-  local scaledheight=defaultheight*vdelta
-  local scaleddepth=defaultdepth*vdelta
-  local hasmath=(properties.hasmath or next(mathparameters)) and true
-  if hasmath then
-    constructors.assignmathparameters(target,tfmdata) 
-    properties.hasmath=true
-    target.nomath=false
-    target.MathConstants=target.mathparameters
-  else
-    properties.hasmath=false
-    target.nomath=true
-    target.mathparameters=nil 
-  end
-  if hasmath then
-    local mathitalics=properties.mathitalics
-    if mathitalics==false then
-      if trace_defining then
-        report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
-      end
-      hasitalics=false
-      autoitalicamount=false
-    end
-  else
-    local textitalics=properties.textitalics
-    if textitalics==false then
-      if trace_defining then
-        report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
-      end
-      hasitalics=false
-      autoitalicamount=false
-    end
-  end
-  if trace_defining then
-    report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
-      name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
-      hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
-  end
-  constructors.beforecopyingcharacters(target,tfmdata)
-  local sharedkerns={}
-  for unicode,character in next,characters do
-    local chr,description,index
-    if changed then
-      local c=changed[unicode]
-      if c and c~=unicode then
-        if c then
-          description=descriptions[c] or descriptions[unicode] or character
-          character=characters[c] or character
-          index=description.index or c
-        else
-          description=descriptions[unicode] or character
-          index=description.index or unicode
-        end
-      else
-        description=descriptions[unicode] or character
-        index=description.index or unicode
-      end
-    else
-      description=descriptions[unicode] or character
-      index=description.index or unicode
-    end
-    local width=description.width
-    local height=description.height
-    local depth=description.depth
-    if realdimensions then
-      if not height or height==0 then
-        local bb=description.boundingbox
-        local ht=bb[4]
-        if ht~=0 then
-          height=ht
-        end
-        if not depth or depth==0 then
-          local dp=-bb[2]
-          if dp~=0 then
-            depth=dp
-          end
-        end
-      elseif not depth or depth==0 then
-        local dp=-description.boundingbox[2]
-        if dp~=0 then
-          depth=dp
-        end
-      end
-    end
-    if width then width=hdelta*width else width=scaledwidth end
-    if height then height=vdelta*height else height=scaledheight end
-    if depth and depth~=0 then
-      depth=delta*depth
-      if nonames then
-        chr={
-          index=index,
-          height=height,
-          depth=depth,
-          width=width,
-        }
-      else
-        chr={
-          name=description.name,
-          index=index,
-          height=height,
-          depth=depth,
-          width=width,
-        }
-      end
-    else
-      if nonames then
-        chr={
-          index=index,
-          height=height,
-          width=width,
-        }
-      else
-        chr={
-          name=description.name,
-          index=index,
-          height=height,
-          width=width,
-        }
-      end
-    end
-    local isunicode=description.unicode
-    if isunicode then
-      chr.unicode=isunicode
-      chr.tounicode=tounicode(isunicode)
-    else
-      chr.tounicode=unknowncode
-    end
-    if hasquality then
-      local ve=character.expansion_factor
-      if ve then
-        chr.expansion_factor=ve*1000 
-      end
-      local vl=character.left_protruding
-      if vl then
-        chr.left_protruding=protrusionfactor*width*vl
-      end
-      local vr=character.right_protruding
-      if vr then
-        chr.right_protruding=protrusionfactor*width*vr
-      end
-    end
-    if hasmath then
-      local vn=character.next
-      if vn then
-        chr.next=vn
-      else
-        local vv=character.vert_variants
-        if vv then
-          local t={}
-          for i=1,#vv do
-            local vvi=vv[i]
-            local s=vvi["start"]  or 0
-            local e=vvi["end"]   or 0
-            local a=vvi["advance"] or 0
-            t[i]={ 
-              ["start"]=s==0 and 0 or s*vdelta,
-              ["end"]=e==0 and 0 or e*vdelta,
-              ["advance"]=a==0 and 0 or a*vdelta,
-              ["extender"]=vvi["extender"],
-              ["glyph"]=vvi["glyph"],
-            }
-          end
-          chr.vert_variants=t
-        else
-          local hv=character.horiz_variants
-          if hv then
-            local t={}
-            for i=1,#hv do
-              local hvi=hv[i]
-              local s=hvi["start"]  or 0
-              local e=hvi["end"]   or 0
-              local a=hvi["advance"] or 0
-              t[i]={ 
-                ["start"]=s==0 and 0 or s*hdelta,
-                ["end"]=e==0 and 0 or e*hdelta,
-                ["advance"]=a==0 and 0 or a*hdelta,
-                ["extender"]=hvi["extender"],
-                ["glyph"]=hvi["glyph"],
-              }
-            end
-            chr.horiz_variants=t
-          end
-        end
-      end
-      local vi=character.vert_italic
-      if vi and vi~=0 then
-        chr.vert_italic=vi*hdelta
-      end
-      local va=character.accent
-      if va then
-        chr.top_accent=vdelta*va
-      end
-      if stackmath then
-        local mk=character.mathkerns
-        if mk then
-          local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft
-          chr.mathkern={ 
-            top_right=tr and mathkerns(tr,vdelta) or nil,
-            top_left=tl and mathkerns(tl,vdelta) or nil,
-            bottom_right=br and mathkerns(br,vdelta) or nil,
-            bottom_left=bl and mathkerns(bl,vdelta) or nil,
-          }
-        end
-      end
-      if hasitalics then
-        local vi=character.italic
-        if vi and vi~=0 then
-          chr.italic=vi*hdelta
-        end
-      end
-    elseif autoitalicamount then 
-      local vi=description.italic
-      if not vi then
-        local bb=description.boundingbox
-        if bb then
-          local vi=bb[3]-description.width+autoitalicamount
-          if vi>0 then 
-            chr.italic=vi*hdelta
-          end
-        else
-        end
-      elseif vi~=0 then
-        chr.italic=vi*hdelta
-      end
-    elseif hasitalics then 
-      local vi=character.italic
-      if vi and vi~=0 then
-        chr.italic=vi*hdelta
-      end
-    end
-    if haskerns then
-      local vk=character.kerns
-      if vk then
-        local s=sharedkerns[vk]
-        if not s then
-          s={}
-          for k,v in next,vk do s[k]=v*hdelta end
-          sharedkerns[vk]=s
-        end
-        chr.kerns=s
-      end
-    end
-    if hasligatures then
-      local vl=character.ligatures
-      if vl then
-        if true then
-          chr.ligatures=vl 
-        else
-          local tt={}
-          for i,l in next,vl do
-            tt[i]=l
-          end
-          chr.ligatures=tt
-        end
-      end
-    end
-    if isvirtual then
-      local vc=character.commands
-      if vc then
-        local ok=false
-        for i=1,#vc do
-          local key=vc[i][1]
-          if key=="right" or key=="down" or key=="rule" then
-            ok=true
-            break
-          end
-        end
-        if ok then
-          local tt={}
-          for i=1,#vc do
-            local ivc=vc[i]
-            local key=ivc[1]
-            if key=="right" then
-              tt[i]={ key,ivc[2]*hdelta }
-            elseif key=="down" then
-              tt[i]={ key,ivc[2]*vdelta }
-            elseif key=="rule" then
-              tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
-            else 
-              tt[i]=ivc 
-            end
-          end
-          chr.commands=tt
-        else
-          chr.commands=vc
-        end
-      end
-    end
-    targetcharacters[unicode]=chr
-  end
-  properties.setitalics=hasitalics
-  constructors.aftercopyingcharacters(target,tfmdata)
-  constructors.trytosharefont(target,tfmdata)
-  local vfonts=target.fonts
-  if isvirtual or target.type=="virtual" or properties.virtualized then
-    properties.virtualized=true
-    target.type="virtual"
-    if not vfonts or #vfonts==0 then
-      target.fonts={ { id=0 } }
-    end
-  elseif vfonts then
-    properties.virtualized=true
-    target.type="virtual"
-    if #vfonts==0 then
-      target.fonts={ { id=0 } }
-    end
-  end
-  return target
-end
-function constructors.finalize(tfmdata)
-  if tfmdata.properties and tfmdata.properties.finalized then
-    return
-  end
-  if not tfmdata.characters then
-    return nil
-  end
-  if not tfmdata.goodies then
-    tfmdata.goodies={} 
-  end
-  local parameters=tfmdata.parameters
-  if not parameters then
-    return nil
-  end
-  if not parameters.expansion then
-    parameters.expansion={
-      stretch=tfmdata.stretch or 0,
-      shrink=tfmdata.shrink or 0,
-      step=tfmdata.step  or 0,
-    }
-  end
-  if not parameters.size then
-    parameters.size=tfmdata.size
-  end
-  if not parameters.mode then
-    parameters.mode=0
-  end
-  if not parameters.width then
-    parameters.width=0
-  end
-  if not parameters.slantfactor then
-    parameters.slantfactor=tfmdata.slant or 0
-  end
-  if not parameters.extendfactor then
-    parameters.extendfactor=tfmdata.extend or 0
-  end
-  if not parameters.squeezefactor then
-    parameters.squeezefactor=tfmdata.squeeze or 0
-  end
-  local designsize=parameters.designsize
-  if designsize then
-    parameters.minsize=tfmdata.minsize or designsize
-    parameters.maxsize=tfmdata.maxsize or designsize
-  else
-    designsize=factors.pt*10
-    parameters.designsize=designsize
-    parameters.minsize=designsize
-    parameters.maxsize=designsize
-  end
-  parameters.minsize=tfmdata.minsize or parameters.designsize
-  parameters.maxsize=tfmdata.maxsize or parameters.designsize
-  if not parameters.units then
-    parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
-  end
-  if not tfmdata.descriptions then
-    local descriptions={} 
-    setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
-    tfmdata.descriptions=descriptions
-  end
-  local properties=tfmdata.properties
-  if not properties then
-    properties={}
-    tfmdata.properties=properties
-  end
-  if not properties.virtualized then
-    properties.virtualized=tfmdata.type=="virtual"
-  end
-  properties.fontname=tfmdata.fontname
-  properties.filename=tfmdata.filename
-  properties.fullname=tfmdata.fullname
-  properties.name=tfmdata.name
-  properties.psname=tfmdata.psname
-  properties.encodingbytes=tfmdata.encodingbytes or 1
-  properties.embedding=tfmdata.embedding   or "subset"
-  properties.tounicode=tfmdata.tounicode   or 1
-  properties.cidinfo=tfmdata.cidinfo    or nil
-  properties.format=tfmdata.format    or "type1"
-  properties.direction=tfmdata.direction   or 0
-  properties.writingmode=tfmdata.writingmode  or "horizontal"
-  properties.identity=tfmdata.identity   or "horizontal"
-  properties.usedbitmap=tfmdata.usedbitmap
-  if not tfmdata.resources then
-    tfmdata.resources={}
-  end
-  if not tfmdata.shared then
-    tfmdata.shared={}
-  end
-  if not properties.hasmath then
-    properties.hasmath=not tfmdata.nomath
-  end
-  tfmdata.MathConstants=nil
-  tfmdata.postprocessors=nil
-  tfmdata.fontname=nil
-  tfmdata.filename=nil
-  tfmdata.fullname=nil
-  tfmdata.name=nil 
-  tfmdata.psname=nil
-  tfmdata.encodingbytes=nil
-  tfmdata.embedding=nil
-  tfmdata.tounicode=nil
-  tfmdata.cidinfo=nil
-  tfmdata.format=nil
-  tfmdata.direction=nil
-  tfmdata.type=nil
-  tfmdata.nomath=nil
-  tfmdata.designsize=nil
-  tfmdata.size=nil
-  tfmdata.stretch=nil
-  tfmdata.shrink=nil
-  tfmdata.step=nil
-  tfmdata.slant=nil
-  tfmdata.extend=nil
-  tfmdata.squeeze=nil
-  tfmdata.mode=nil
-  tfmdata.width=nil
-  tfmdata.units=nil
-  tfmdata.units_per_em=nil
-  tfmdata.cache=nil
-  properties.finalized=true
-  return tfmdata
-end
-local hashmethods={}
-constructors.hashmethods=hashmethods
-function constructors.hashfeatures(specification) 
-  local features=specification.features
-  if features then
-    local t,n={},0
-    for category,list in sortedhash(features) do
-      if next(list) then
-        local hasher=hashmethods[category]
-        if hasher then
-          local hash=hasher(list)
-          if hash then
-            n=n+1
-            t[n]=category..":"..hash
-          end
-        end
-      end
-    end
-    if n>0 then
-      return concat(t," & ")
-    end
-  end
-  return "unknown"
-end
-hashmethods.normal=function(list)
-  local s={}
-  local n=0
-  for k,v in next,list do
-    if not k then
-    elseif k=="number" or k=="features" then
-    else
-      n=n+1
-      if type(v)=="table" then
-        local t={}
-        local m=0
-        for k,v in next,v do
-          m=m+1
-          t[m]=k..'='..tostring(v)
-        end
-        s[n]=k..'={'..concat(t,",").."}"
-      else
-        s[n]=k..'='..tostring(v)
-      end
-    end
-  end
-  if n>0 then
-    sort(s)
-    return concat(s,"+")
-  end
-end
-function constructors.hashinstance(specification,force)
-  local hash,size,fallbacks=specification.hash,specification.size,specification.fallbacks
-  if force or not hash then
-    hash=constructors.hashfeatures(specification)
-    specification.hash=hash
-  end
-  if size<1000 and designsizes[hash] then
-    size=round(constructors.scaled(size,designsizes[hash]))
-  else
-    size=round(size)
-  end
-  specification.size=size
-  if fallbacks then
-    return hash..' @ '..size..' @ '..fallbacks
-  else
-    return hash..' @ '..size
-  end
-end
-function constructors.setname(tfmdata,specification) 
-  if constructors.namemode=="specification" then
-    local specname=specification.specification
-    if specname then
-      tfmdata.properties.name=specname
-      if trace_defining then
-        report_otf("overloaded fontname %a",specname)
-      end
-    end
-  end
-end
-function constructors.checkedfilename(data)
-  local foundfilename=data.foundfilename
-  if not foundfilename then
-    local askedfilename=data.filename or ""
-    if askedfilename~="" then
-      askedfilename=resolvers.resolve(askedfilename) 
-      foundfilename=resolvers.findbinfile(askedfilename,"") or ""
-      if foundfilename=="" then
-        report_defining("source file %a is not found",askedfilename)
-        foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
-        if foundfilename~="" then
-          report_defining("using source file %a due to cache mismatch",foundfilename)
-        end
-      end
-    end
-    data.foundfilename=foundfilename
-  end
-  return foundfilename
-end
-local formats=allocate()
-fonts.formats=formats
-setmetatableindex(formats,function(t,k)
-  local l=lower(k)
-  if rawget(t,k) then
-    t[k]=l
-    return l
-  end
-  return rawget(t,file.suffix(l))
-end)
-do
-  local function setindeed(mode,source,target,group,name,position)
-    local action=source[mode]
-    if not action then
-      return
-    end
-    local t=target[mode]
-    if not t then
-      report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
-      os.exit()
-    elseif position then
-      insert(t,position,{ name=name,action=action })
-    else
-      for i=1,#t do
-        local ti=t[i]
-        if ti.name==name then
-          ti.action=action
-          return
-        end
-      end
-      insert(t,{ name=name,action=action })
-    end
-  end
-  local function set(group,name,target,source)
-    target=target[group]
-    if not target then
-      report_defining("fatal target error in setting feature %a, group %a",name,group)
-      os.exit()
-    end
-    local source=source[group]
-    if not source then
-      report_defining("fatal source error in setting feature %a, group %a",name,group)
-      os.exit()
-    end
-    local position=source.position
-    setindeed("node",source,target,group,name,position)
-    setindeed("base",source,target,group,name,position)
-    setindeed("plug",source,target,group,name,position)
-  end
-  local function register(where,specification)
-    local name=specification.name
-    if name and name~="" then
-      local default=specification.default
-      local description=specification.description
-      local initializers=specification.initializers
-      local processors=specification.processors
-      local manipulators=specification.manipulators
-      local modechecker=specification.modechecker
-      if default then
-        where.defaults[name]=default
-      end
-      if description and description~="" then
-        where.descriptions[name]=description
-      end
-      if initializers then
-        set('initializers',name,where,specification)
-      end
-      if processors then
-        set('processors',name,where,specification)
-      end
-      if manipulators then
-        set('manipulators',name,where,specification)
-      end
-      if modechecker then
-        where.modechecker=modechecker
-      end
-    end
-  end
-  constructors.registerfeature=register
-  function constructors.getfeatureaction(what,where,mode,name)
-    what=handlers[what].features
-    if what then
-      where=what[where]
-      if where then
-        mode=where[mode]
-        if mode then
-          for i=1,#mode do
-            local m=mode[i]
-            if m.name==name then
-              return m.action
-            end
-          end
-        end
-      end
-    end
-  end
-  local newfeatures={}
-  constructors.newfeatures=newfeatures 
-  constructors.features=newfeatures
-  local function setnewfeatures(what)
-    local handler=handlers[what]
-    local features=handler.features
-    if not features then
-      local tables=handler.tables   
-      local statistics=handler.statistics 
-      features=allocate {
-        defaults={},
-        descriptions=tables and tables.features or {},
-        used=statistics and statistics.usedfeatures or {},
-        initializers={ base={},node={},plug={} },
-        processors={ base={},node={},plug={} },
-        manipulators={ base={},node={},plug={} },
-      }
-      features.register=function(specification) return register(features,specification) end
-      handler.features=features 
-    end
-    return features
-  end
-  setmetatable(newfeatures,{
-    __call=function(t,k) local v=t[k] return v end,
-    __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
-  })
-end
-do
-  local newhandler={}
-  constructors.handlers=newhandler 
-  constructors.newhandler=newhandler
-  local function setnewhandler(what) 
-    local handler=handlers[what]
-    if not handler then
-      handler={}
-      handlers[what]=handler
-    end
-    return handler
-  end
-  setmetatable(newhandler,{
-    __call=function(t,k) local v=t[k] return v end,
-    __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
-  })
-end
-do
-  local newenhancer={}
-  constructors.enhancers=newenhancer
-  constructors.newenhancer=newenhancer
-  local function setnewenhancer(format)
-    local handler=handlers[format]
-    local enhancers=handler.enhancers
-    if not enhancers then
-      local actions=allocate() 
-      local before=allocate()
-      local after=allocate()
-      local order=allocate()
-      local known={}
-      local nofsteps=0
-      local patches={ before=before,after=after }
-      local trace=false
-      local report=logs.reporter("fonts",format.." enhancing")
-      trackers.register(format..".loading",function(v) trace=v end)
-      local function enhance(name,data,filename,raw)
-        local enhancer=actions[name]
-        if enhancer then
-          if trace then
-            report("apply enhancement %a to file %a",name,filename)
-            ioflush()
-          end
-          enhancer(data,filename,raw)
-        else
-        end
-      end
-      local function apply(data,filename,raw)
-        local basename=file.basename(lower(filename))
-        if trace then
-          report("%s enhancing file %a","start",filename)
-        end
-        ioflush() 
-        for e=1,nofsteps do
-          local enhancer=order[e]
-          local b=before[enhancer]
-          if b then
-            for pattern,action in next,b do
-              if find(basename,pattern) then
-                action(data,filename,raw)
-              end
-            end
-          end
-          enhance(enhancer,data,filename,raw) 
-          local a=after[enhancer]
-          if a then
-            for pattern,action in next,a do
-              if find(basename,pattern) then
-                action(data,filename,raw)
-              end
-            end
-          end
-          ioflush() 
-        end
-        if trace then
-          report("%s enhancing file %a","stop",filename)
-        end
-        ioflush() 
-      end
-      local function register(what,action)
-        if action then
-          if actions[what] then
-          else
-            nofsteps=nofsteps+1
-            order[nofsteps]=what
-            known[what]=nofsteps
-          end
-          actions[what]=action
-        else
-          report("bad enhancer %a",what)
-        end
-      end
-      local function patch(what,where,pattern,action)
-        local pw=patches[what]
-        if pw then
-          local ww=pw[where]
-          if ww then
-            ww[pattern]=action
-          else
-            pw[where]={ [pattern]=action }
-            if not known[where] then
-              nofsteps=nofsteps+1
-              order[nofsteps]=where
-              known[where]=nofsteps
-            end
-          end
-        end
-      end
-      enhancers={
-        register=register,
-        apply=apply,
-        patch=patch,
-        report=report,
-        patches={
-          register=patch,
-          report=report,
-        },
-      }
-      handler.enhancers=enhancers
-    end
-    return enhancers
-  end
-  setmetatable(newenhancer,{
-    __call=function(t,k) local v=t[k] return v end,
-    __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
-  })
-end
-function constructors.checkedfeatures(what,features)
-  local defaults=handlers[what].features.defaults
-  if features and next(features) then
-    features=fastcopy(features) 
-    for key,value in next,defaults do
-      if features[key]==nil then
-        features[key]=value
-      end
-    end
-    return features
-  else
-    return fastcopy(defaults) 
-  end
-end
-function constructors.initializefeatures(what,tfmdata,features,trace,report)
-  if features and next(features) then
-    local properties=tfmdata.properties or {} 
-    local whathandler=handlers[what]
-    local whatfeatures=whathandler.features
-    local whatmodechecker=whatfeatures.modechecker
-    local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
-    properties.mode=mode 
-    features.mode=mode
-    local done={}
-    while true do
-      local redo=false
-      local initializers=whatfeatures.initializers[mode]
-      if initializers then
-        for i=1,#initializers do
-          local step=initializers[i]
-          local feature=step.name
-          local value=features[feature]
-          if not value then
-          elseif done[feature] then
-          else
-            local action=step.action
-            if trace then
-              report("initializing feature %a to %a for mode %a for font %a",feature,
-                value,mode,tfmdata.properties.fullname)
-            end
-            action(tfmdata,value,features) 
-            if mode~=properties.mode or mode~=features.mode then
-              if whatmodechecker then
-                properties.mode=whatmodechecker(tfmdata,features,properties.mode) 
-                features.mode=properties.mode
-              end
-              if mode~=properties.mode then
-                mode=properties.mode
-                redo=true
-              end
-            end
-            done[feature]=true
-          end
-          if redo then
-            break
-          end
-        end
-        if not redo then
-          break
-        end
-      else
-        break
-      end
-    end
-    properties.mode=mode 
-    return true
-  else
-    return false
-  end
-end
-function constructors.collectprocessors(what,tfmdata,features,trace,report)
-  local processes,nofprocesses={},0
-  if features and next(features) then
-    local properties=tfmdata.properties
-    local whathandler=handlers[what]
-    local whatfeatures=whathandler.features
-    local whatprocessors=whatfeatures.processors
-    local mode=properties.mode
-    local processors=whatprocessors[mode]
-    if processors then
-      for i=1,#processors do
-        local step=processors[i]
-        local feature=step.name
-        if features[feature] then
-          local action=step.action
-          if trace then
-            report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
-          end
-          if action then
-            nofprocesses=nofprocesses+1
-            processes[nofprocesses]=action
-          end
-        end
-      end
-    elseif trace then
-      report("no feature processors for mode %a for font %a",mode,properties.fullname)
-    end
-  end
-  return processes
-end
-function constructors.applymanipulators(what,tfmdata,features,trace,report)
-  if features and next(features) then
-    local properties=tfmdata.properties
-    local whathandler=handlers[what]
-    local whatfeatures=whathandler.features
-    local whatmanipulators=whatfeatures.manipulators
-    local mode=properties.mode
-    local manipulators=whatmanipulators[mode]
-    if manipulators then
-      for i=1,#manipulators do
-        local step=manipulators[i]
-        local feature=step.name
-        local value=features[feature]
-        if value then
-          local action=step.action
-          if trace then
-            report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
-          end
-          if action then
-            action(tfmdata,feature,value)
-          end
-        end
-      end
-    end
-  end
-end
-function constructors.addcoreunicodes(unicodes) 
-  if not unicodes then
-    unicodes={}
-  end
-  unicodes.space=0x0020
-  unicodes.hyphen=0x002D
-  unicodes.zwj=0x200D
-  unicodes.zwnj=0x200C
-  return unicodes
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-con”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] ---
-
-if not modules then modules={} end modules ['luatex-font-enc']={
-  version=1.001,
-  comment="companion to luatex-*.tex",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  os.exit()
-end
-local fonts=fonts
-local encodings={}
-fonts.encodings=encodings
-encodings.agl={}
-encodings.known={}
-setmetatable(encodings.agl,{ __index=function(t,k)
-  if k=="unicodes" then
-    logs.report("fonts","loading (extended) adobe glyph list")
-    local unicodes=dofile(resolvers.findfile("font-age.lua"))
-    encodings.agl={ unicodes=unicodes }
-    return unicodes
-  else
-    return nil
-  end
-end })
-encodings.cache=containers.define("fonts","enc",encodings.version,true)
-function encodings.load(filename)
-  local name=file.removesuffix(filename)
-  local data=containers.read(encodings.cache,name)
-  if data then
-    return data
-  end
-  local vector,tag,hash,unicodes={},"",{},{}
-  local foundname=resolvers.findfile(filename,'enc')
-  if foundname and foundname~="" then
-    local ok,encoding,size=resolvers.loadbinfile(foundname)
-    if ok and encoding then
-      encoding=string.gsub(encoding,"%%(.-)\n","")
-      local unicoding=encodings.agl.unicodes
-      local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
-      local i=0
-      for ch in string.gmatch(vec,"/([%a%d%.]+)") do
-        if ch~=".notdef" then
-          vector[i]=ch
-          if not hash[ch] then
-            hash[ch]=i
-          else
-          end
-          local u=unicoding[ch]
-          if u then
-            unicodes[u]=i
-          end
-        end
-        i=i+1
-      end
-    end
-  end
-  local data={
-    name=name,
-    tag=tag,
-    vector=vector,
-    hash=hash,
-    unicodes=unicodes
-  }
-  return containers.write(encodings.cache,name,data)
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “fonts-enc”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] ---
-
-if not modules then modules={} end modules ['font-cid']={
-  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"
-}
-local format,match,lower=string.format,string.match,string.lower
-local tonumber=tonumber
-local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match
-local fonts,logs,trackers=fonts,logs,trackers
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local cid={}
-fonts.cid=cid
-local cidmap={}
-local cidmax=10
-local number=C(R("09","af","AF")^1)
-local space=S(" \n\r\t")
-local spaces=space^0
-local period=P(".")
-local periods=period*period
-local name=P("/")*C((1-space)^1)
-local unicodes,names={},{} 
-local function do_one(a,b)
-  unicodes[tonumber(a)]=tonumber(b,16)
-end
-local function do_range(a,b,c)
-  c=tonumber(c,16)
-  for i=tonumber(a),tonumber(b) do
-    unicodes[i]=c
-    c=c+1
-  end
-end
-local function do_name(a,b)
-  names[tonumber(a)]=b
-end
-local grammar=P { "start",
-  start=number*spaces*number*V("series"),
-  series=(spaces*(V("one")+V("range")+V("named")))^1,
-  one=(number*spaces*number)/do_one,
-  range=(number*periods*number*spaces*number)/do_range,
-  named=(number*spaces*name)/do_name
-}
-local function loadcidfile(filename)
-  local data=io.loaddata(filename)
-  if data then
-    unicodes,names={},{}
-    lpegmatch(grammar,data)
-    local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
-    return {
-      supplement=supplement,
-      registry=registry,
-      ordering=ordering,
-      filename=filename,
-      unicodes=unicodes,
-      names=names,
-    }
-  end
-end
-cid.loadfile=loadcidfile 
-local template="%s-%s-%s.cidmap"
-local function locate(registry,ordering,supplement)
-  local filename=format(template,registry,ordering,supplement)
-  local hashname=lower(filename)
-  local found=cidmap[hashname]
-  if not found then
-    if trace_loading then
-      report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
-    end
-    local fullname=resolvers.findfile(filename,'cid') or ""
-    if fullname~="" then
-      found=loadcidfile(fullname)
-      if found then
-        if trace_loading then
-          report_otf("using cidmap file %a",filename)
-        end
-        cidmap[hashname]=found
-        found.usedname=file.basename(filename)
-      end
-    end
-  end
-  return found
-end
-function cid.getmap(specification)
-  if not specification then
-    report_otf("invalid cidinfo specification, table expected")
-    return
-  end
-  local registry=specification.registry
-  local ordering=specification.ordering
-  local supplement=specification.supplement
-  local filename=format(registry,ordering,supplement)
-  local lowername=lower(filename)
-  local found=cidmap[lowername]
-  if found then
-    return found
-  end
-  if ordering=="Identity" then
-    local found={
-      supplement=supplement,
-      registry=registry,
-      ordering=ordering,
-      filename=filename,
-      unicodes={},
-      names={},
-    }
-    cidmap[lowername]=found
-    return found
-  end
-  if trace_loading then
-    report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
-  end
-  found=locate(registry,ordering,supplement)
-  if not found then
-    local supnum=tonumber(supplement)
-    local cidnum=nil
-    if supnum<cidmax then
-      for s=supnum+1,cidmax do
-        local c=locate(registry,ordering,s)
-        if c then
-          found,cidnum=c,s
-          break
-        end
-      end
-    end
-    if not found and supnum>0 then
-      for s=supnum-1,0,-1 do
-        local c=locate(registry,ordering,s)
-        if c then
-          found,cidnum=c,s
-          break
-        end
-      end
-    end
-    registry=lower(registry)
-    ordering=lower(ordering)
-    if found and cidnum>0 then
-      for s=0,cidnum-1 do
-        local filename=format(template,registry,ordering,s)
-        if not cidmap[filename] then
-          cidmap[filename]=found
-        end
-      end
-    end
-  end
-  return found
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-cid”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-map” 210b9288eef0df624da638b65d27291b] ---
-
-if not modules then modules={} end modules ['font-map']={
-  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"
-}
-local tonumber,next,type=tonumber,next,type
-local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower
-local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
-local formatters=string.formatters
-local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
-local rshift=bit32.rshift
-local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
-local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
-local report_fonts=logs.reporter("fonts","loading")
-local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
-local fonts=fonts or {}
-local mappings=fonts.mappings or {}
-fonts.mappings=mappings
-local allocate=utilities.storage.allocate
-local hex=R("AF","af","09")
-local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end
-local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end
-local dec=(R("09")^1)/tonumber
-local period=P(".")
-local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) 
-local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) 
-local index=P("index")*dec*Cc(false)
-local parser=unicode+ucode+index
-local parsers={}
-local function makenameparser(str)
-  if not str or str=="" then
-    return parser
-  else
-    local p=parsers[str]
-    if not p then
-      p=P(str)*period*dec*Cc(false)
-      parsers[str]=p
-    end
-    return p
-  end
-end
-local f_single=formatters["%04X"]
-local f_double=formatters["%04X%04X"]
-local function tounicode16(unicode)
-  if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
-    return f_single(unicode)
-  else
-    unicode=unicode-0x10000
-    return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
-  end
-end
-local function tounicode16sequence(unicodes)
-  local t={}
-  for l=1,#unicodes do
-    local u=unicodes[l]
-    if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
-      t[l]=f_single(u)
-    else
-      u=u-0x10000
-      t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
-    end
-  end
-  return concat(t)
-end
-local unknown=f_single(0xFFFD)
-local hash={}
-local conc={}
-table.setmetatableindex(hash,function(t,k)
-  if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
-    v=f_single(k)
-  else
-    local k=k-0x10000
-    v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
-  end
-  t[k]=v
-  return v
-end)
-local function tounicode(k)
-  if type(k)=="table" then
-    local n=#k
-    for l=1,n do
-      conc[l]=hash[k[l]]
-    end
-    return concat(conc,"",1,n)
-  elseif k>=0x00E000 and k<=0x00F8FF then
-    return unknown
-  elseif k>=0x0F0000 and k<=0x0FFFFF then
-    return unknown
-  elseif k>=0x100000 and k<=0x10FFFF then
-    return unknown
-  else
-    return hash[k]
-  end
-end
-local function fromunicode16(str)
-  if #str==4 then
-    return tonumber(str,16)
-  else
-    local l,r=match(str,"(....)(....)")
-    return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
-  end
-end
-mappings.makenameparser=makenameparser
-mappings.tounicode=tounicode
-mappings.tounicode16=tounicode16
-mappings.tounicode16sequence=tounicode16sequence
-mappings.fromunicode16=fromunicode16
-local ligseparator=P("_")
-local varseparator=P(".")
-local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0)
-do
-  local overloads={
-    IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
-    ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
-    ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
-    fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
-    fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
-    ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
-    ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
-    fj={ name="f_j",unicode={ 0x66,0x6A } },
-    fk={ name="f_k",unicode={ 0x66,0x6B } },
-  }
-  local o=allocate {}
-  for k,v in next,overloads do
-    local name=v.name
-    local mess=v.mess
-    if name then
-      o[name]=v
-    end
-    if mess then
-      o[mess]=v
-    end
-    o[k]=v
-  end
-  mappings.overloads=o
-end
-function mappings.addtounicode(data,filename,checklookups,forceligatures)
-  local resources=data.resources
-  local unicodes=resources.unicodes
-  if not unicodes then
-    if trace_mapping then
-      report_fonts("no unicode list, quitting tounicode for %a",filename)
-    end
-    return
-  end
-  local properties=data.properties
-  local descriptions=data.descriptions
-  local overloads=mappings.overloads
-  unicodes['space']=unicodes['space'] or 32
-  unicodes['hyphen']=unicodes['hyphen'] or 45
-  unicodes['zwj']=unicodes['zwj']  or 0x200D
-  unicodes['zwnj']=unicodes['zwnj']  or 0x200C
-  local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 
-  local unicodevector=fonts.encodings.agl.unicodes or {} 
-  local contextvector=fonts.encodings.agl.ctxcodes or {} 
-  local missing={}
-  local nofmissing=0
-  local oparser=nil
-  local cidnames=nil
-  local cidcodes=nil
-  local cidinfo=properties.cidinfo
-  local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
-  local uparser=makenameparser() 
-  if usedmap then
-     oparser=usedmap and makenameparser(cidinfo.ordering)
-     cidnames=usedmap.names
-     cidcodes=usedmap.unicodes
-  end
-  local ns=0
-  local nl=0
-  local dlist=sortedkeys(descriptions)
-  for i=1,#dlist do
-    local du=dlist[i]
-    local glyph=descriptions[du]
-    local name=glyph.name
-    if name then
-      local overload=overloads[name] or overloads[du]
-      if overload then
-        glyph.unicode=overload.unicode
-      else
-        local gu=glyph.unicode 
-        if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
-          local unicode=unicodevector[name] or contextvector[name]
-          if unicode then
-            glyph.unicode=unicode
-            ns=ns+1
-          end
-          if (not unicode) and usedmap then
-            local foundindex=lpegmatch(oparser,name)
-            if foundindex then
-              unicode=cidcodes[foundindex] 
-              if unicode then
-                glyph.unicode=unicode
-                ns=ns+1
-              else
-                local reference=cidnames[foundindex] 
-                if reference then
-                  local foundindex=lpegmatch(oparser,reference)
-                  if foundindex then
-                    unicode=cidcodes[foundindex]
-                    if unicode then
-                      glyph.unicode=unicode
-                      ns=ns+1
-                    end
-                  end
-                  if not unicode or unicode=="" then
-                    local foundcodes,multiple=lpegmatch(uparser,reference)
-                    if foundcodes then
-                      glyph.unicode=foundcodes
-                      if multiple then
-                        nl=nl+1
-                        unicode=true
-                      else
-                        ns=ns+1
-                        unicode=foundcodes
-                      end
-                    end
-                  end
-                end
-              end
-            end
-          end
-          if not unicode or unicode=="" then
-            local split=lpegmatch(namesplitter,name)
-            local nsplit=split and #split or 0 
-            if nsplit==0 then
-            elseif nsplit==1 then
-              local base=split[1]
-              local u=unicodes[base] or unicodevector[base] or contextvector[name]
-              if not u then
-              elseif type(u)=="table" then
-                if u[1]<private then
-                  unicode=u
-                  glyph.unicode=unicode
-                end
-              elseif u<private then
-                unicode=u
-                glyph.unicode=unicode
-              end
-            else
-              local t,n={},0
-              for l=1,nsplit do
-                local base=split[l]
-                local u=unicodes[base] or unicodevector[base] or contextvector[name]
-                if not u then
-                  break
-                elseif type(u)=="table" then
-                  if u[1]>=private then
-                    break
-                  end
-                  n=n+1
-                  t[n]=u[1]
-                else
-                  if u>=private then
-                    break
-                  end
-                  n=n+1
-                  t[n]=u
-                end
-              end
-              if n>0 then
-                if n==1 then
-                  unicode=t[1]
-                else
-                  unicode=t
-                end
-                glyph.unicode=unicode
-              end
-            end
-            nl=nl+1
-          end
-          if not unicode or unicode=="" then
-            local foundcodes,multiple=lpegmatch(uparser,name)
-            if foundcodes then
-              glyph.unicode=foundcodes
-              if multiple then
-                nl=nl+1
-                unicode=true
-              else
-                ns=ns+1
-                unicode=foundcodes
-              end
-            end
-          end
-          local r=overloads[unicode]
-          if r then
-            unicode=r.unicode
-            glyph.unicode=unicode
-          end
-          if not unicode then
-            missing[du]=true
-            nofmissing=nofmissing+1
-          end
-        else
-        end
-      end
-    else
-      local overload=overloads[du]
-      if overload then
-        glyph.unicode=overload.unicode
-      elseif not glyph.unicode then
-        missing[du]=true
-        nofmissing=nofmissing+1
-      end
-    end
-  end
-  if type(checklookups)=="function" then
-    checklookups(data,missing,nofmissing)
-  end
-  local unicoded=0
-  local collected=fonts.handlers.otf.readers.getcomponents(data) 
-  local function resolve(glyph,u)
-    local n=#u
-    for i=1,n do
-      if u[i]>private then
-        n=0
-        break
-      end
-    end
-    if n>0 then
-      if n>1 then
-        glyph.unicode=u
-      else
-        glyph.unicode=u[1]
-      end
-      unicoded=unicoded+1
-    end
-  end
-  if not collected then
-  elseif forceligatures or force_ligatures then
-    for i=1,#dlist do
-      local du=dlist[i]
-      if du>=private or (du>=0xE000 and du<=0xF8FF) then
-        local u=collected[du] 
-        if u then
-          resolve(descriptions[du],u)
-        end
-      end
-    end
-  else
-    for i=1,#dlist do
-      local du=dlist[i]
-      if du>=private or (du>=0xE000 and du<=0xF8FF) then
-        local glyph=descriptions[du]
-        if glyph.class=="ligature" and not glyph.unicode then
-          local u=collected[du] 
-          if u then
-             resolve(glyph,u)
-          end
-        end
-      end
-    end
-  end
-  if trace_mapping and unicoded>0 then
-    report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
-  end
-  if trace_mapping then
-    for i=1,#dlist do
-      local du=dlist[i]
-      local glyph=descriptions[du]
-      local name=glyph.name or "-"
-      local index=glyph.index or 0
-      local unicode=glyph.unicode
-      if unicode then
-        if type(unicode)=="table" then
-          local unicodes={}
-          for i=1,#unicode do
-            unicodes[i]=formatters("%U",unicode[i])
-          end
-          report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
-        else
-          report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
-        end
-      else
-        report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
-      end
-    end
-  end
-  if trace_loading and (ns>0 or nl>0) then
-    report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
-  end
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-map”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] ---
-
-if not modules then modules={} end modules ['font-vfc']={
-  version=1.001,
-  comment="companion to font-ini.mkiv and hand-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local select,type=select,type
-local insert=table.insert
-local fonts=fonts
-local helpers=fonts.helpers
-local setmetatableindex=table.setmetatableindex
-local makeweak=table.makeweak
-local push={ "push" }
-local pop={ "pop" }
-local dummy={ "comment" }
-function helpers.prependcommands(commands,...)
-  insert(commands,1,push)
-  for i=select("#",...),1,-1 do
-    local s=(select(i,...))
-    if s then
-      insert(commands,1,s)
-    end
-  end
-  insert(commands,pop)
-  return commands
-end
-function helpers.appendcommands(commands,...)
-  insert(commands,1,push)
-  insert(commands,pop)
-  for i=1,select("#",...) do
-    local s=(select(i,...))
-    if s then
-      insert(commands,s)
-    end
-  end
-  return commands
-end
-function helpers.prependcommandtable(commands,t)
-  insert(commands,1,push)
-  for i=#t,1,-1 do
-    local s=t[i]
-    if s then
-      insert(commands,1,s)
-    end
-  end
-  insert(commands,pop)
-  return commands
-end
-function helpers.appendcommandtable(commands,t)
-  insert(commands,1,push)
-  insert(commands,pop)
-  for i=1,#t do
-    local s=t[i]
-    if s then
-      insert(commands,s)
-    end
-  end
-  return commands
-end
-local char=setmetatableindex(function(t,k)
-  local v={ "slot",0,k }
-  t[k]=v
-  return v
-end)
-local right=setmetatableindex(function(t,k)
-  local v={ "right",k }
-  t[k]=v
-  return v
-end)
-local left=setmetatableindex(function(t,k)
-  local v={ "right",-k }
-  t[k]=v
-  return v
-end)
-local down=setmetatableindex(function(t,k)
-  local v={ "down",k }
-  t[k]=v
-  return v
-end)
-local up=setmetatableindex(function(t,k)
-  local v={ "down",-k }
-  t[k]=v
-  return v
-end)
-helpers.commands=utilities.storage.allocate {
-  char=char,
-  right=right,
-  left=left,
-  down=down,
-  up=up,
-  push=push,
-  pop=pop,
-  dummy=dummy,
-}
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-vfc”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-otr” 2c35abf43f9a64bdd99240593d432d8a] ---
-
-if not modules then modules={} end modules ['font-otr']={
-  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"
-}
-local next,type,tonumber=next,type,tonumber
-local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
-local fullstrip=string.fullstrip
-local floor,round=math.floor,math.round
-local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
-local lpegmatch=lpeg.match
-local rshift=bit32.rshift
-local setmetatableindex=table.setmetatableindex
-local formatters=string.formatters
-local sortedkeys=table.sortedkeys
-local sortedhash=table.sortedhash
-local stripstring=string.nospaces
-local utf16_to_utf8_be=utf.utf16_to_utf8_be
-local report=logs.reporter("otf reader")
-local trace_cmap=false 
-local trace_cmap_detail=false
-fonts=fonts or {}
-local handlers=fonts.handlers or {}
-fonts.handlers=handlers
-local otf=handlers.otf or {}
-handlers.otf=otf
-local readers=otf.readers or {}
-otf.readers=readers
-local streamreader=utilities.files  
-local streamwriter=utilities.files
-readers.streamreader=streamreader
-readers.streamwriter=streamwriter
-local openfile=streamreader.open
-local closefile=streamreader.close
-local setposition=streamreader.setposition
-local skipshort=streamreader.skipshort
-local readbytes=streamreader.readbytes
-local readstring=streamreader.readstring
-local readbyte=streamreader.readcardinal1 
-local readushort=streamreader.readcardinal2 
-local readuint=streamreader.readcardinal3 
-local readulong=streamreader.readcardinal4
-local readshort=streamreader.readinteger2  
-local readlong=streamreader.readinteger4  
-local readfixed=streamreader.readfixed4
-local read2dot14=streamreader.read2dot14   
-local readfword=readshort          
-local readufword=readushort         
-local readoffset=readushort
-local readcardinaltable=streamreader.readcardinaltable
-local readintegertable=streamreader.readintegertable
-function streamreader.readtag(f)
-  return lower(stripstring(readstring(f,4)))
-end
-local short=2
-local ushort=2
-local ulong=4
-directives.register("fonts.streamreader",function()
-  streamreader=utilities.streams
-  openfile=streamreader.open
-  closefile=streamreader.close
-  setposition=streamreader.setposition
-  skipshort=streamreader.skipshort
-  readbytes=streamreader.readbytes
-  readstring=streamreader.readstring
-  readbyte=streamreader.readcardinal1
-  readushort=streamreader.readcardinal2
-  readuint=streamreader.readcardinal3
-  readulong=streamreader.readcardinal4
-  readshort=streamreader.readinteger2
-  readlong=streamreader.readinteger4
-  readfixed=streamreader.readfixed4
-  read2dot14=streamreader.read2dot14
-  readfword=readshort
-  readufword=readushort
-  readoffset=readushort
-  readcardinaltable=streamreader.readcardinaltable
-  readintegertable=streamreader.readintegertable
-  function streamreader.readtag(f)
-    return lower(stripstring(readstring(f,4)))
-  end
-end)
-local function readlongdatetime(f)
-  local a,b,c,d,e,f,g,h=readbytes(f,8)
-  return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
-end
-local tableversion=0.004
-readers.tableversion=tableversion
-local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
-local reservednames={ [0]="copyright",
-  "family",
-  "subfamily",
-  "uniqueid",
-  "fullname",
-  "version",
-  "postscriptname",
-  "trademark",
-  "manufacturer",
-  "designer",
-  "description",
-  "vendorurl",
-  "designerurl",
-  "license",
-  "licenseurl",
-  "reserved",
-  "typographicfamily",
-  "typographicsubfamily",
-  "compatiblefullname",
-  "sampletext",
-  "cidfindfontname",
-  "wwsfamily",
-  "wwssubfamily",
-  "lightbackgroundpalette",
-  "darkbackgroundpalette",
-  "variationspostscriptnameprefix",
-}
-local platforms={ [0]="unicode",
-  "macintosh",
-  "iso",
-  "windows",
-  "custom",
-}
-local encodings={
-  unicode={ [0]="unicode 1.0 semantics",
-    "unicode 1.1 semantics",
-    "iso/iec 10646",
-    "unicode 2.0 bmp",
-    "unicode 2.0 full",
-    "unicode variation sequences",
-    "unicode full repertoire",
-  },
-  macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
-    "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
-    "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
-    "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
-    "uninterpreted",
-  },
-  iso={ [0]="7-bit ascii",
-    "iso 10646",
-    "iso 8859-1",
-  },
-  windows={ [0]="symbol",
-    "unicode bmp",
-    "shiftjis",
-    "prc",
-    "big5",
-    "wansung",
-    "johab",
-    "reserved 7",
-    "reserved 8",
-    "reserved 9",
-    "unicode ucs-4",
-  },
-  custom={
-  }
-}
-local decoders={
-  unicode={},
-  macintosh={},
-  iso={},
-  windows={
-    ["unicode semantics"]=utf16_to_utf8_be,
-    ["unicode bmp"]=utf16_to_utf8_be,
-    ["unicode full"]=utf16_to_utf8_be,
-    ["unicode 1.0 semantics"]=utf16_to_utf8_be,
-    ["unicode 1.1 semantics"]=utf16_to_utf8_be,
-    ["unicode 2.0 bmp"]=utf16_to_utf8_be,
-    ["unicode 2.0 full"]=utf16_to_utf8_be,
-    ["unicode variation sequences"]=utf16_to_utf8_be,
-    ["unicode full repertoire"]=utf16_to_utf8_be,
-  },
-  custom={},
-}
-local languages={
-  unicode={
-    [ 0]="english",
-  },
-  macintosh={
-    [ 0]="english",
-  },
-  iso={},
-  windows={
-    [0x0409]="english - united states",
-  },
-  custom={},
-}
-local standardromanencoding={ [0]=
-  "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
-  "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
-  "parenright","asterisk","plus","comma","hyphen","period","slash",
-  "zero","one","two","three","four","five","six","seven","eight",
-  "nine","colon","semicolon","less","equal","greater","question","at",
-  "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","bracketleft",
-  "backslash","bracketright","asciicircum","underscore","grave","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","braceleft","bar",
-  "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
-  "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
-  "adieresis","atilde","aring","ccedilla","eacute","egrave",
-  "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
-  "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
-  "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
-  "section","bullet","paragraph","germandbls","registered","copyright",
-  "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
-  "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
-  "summation","product","pi","integral","ordfeminine","ordmasculine",
-  "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
-  "radical","florin","approxequal","Delta","guillemotleft",
-  "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
-  "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
-  "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
-  "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
-  "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
-  "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
-  "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
-  "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
-  "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
-  "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
-  "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
-  "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
-  "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
-  "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
-  "dcroat",
-}
-local weights={
-  [100]="thin",
-  [200]="extralight",
-  [300]="light",
-  [400]="normal",
-  [500]="medium",
-  [600]="semibold",
-  [700]="bold",
-  [800]="extrabold",
-  [900]="black",
-}
-local widths={
-  [1]="ultracondensed",
-  [2]="extracondensed",
-  [3]="condensed",
-  [4]="semicondensed",
-  [5]="normal",
-  [6]="semiexpanded",
-  [7]="expanded",
-  [8]="extraexpanded",
-  [9]="ultraexpanded",
-}
-setmetatableindex(weights,function(t,k)
-  local r=floor((k+50)/100)*100
-  local v=(r>900 and "black") or rawget(t,r) or "normal"
-  return v
-end)
-setmetatableindex(widths,function(t,k)
-  return "normal"
-end)
-local panoseweights={
-  [ 0]="normal",
-  [ 1]="normal",
-  [ 2]="verylight",
-  [ 3]="light",
-  [ 4]="thin",
-  [ 5]="book",
-  [ 6]="medium",
-  [ 7]="demi",
-  [ 8]="bold",
-  [ 9]="heavy",
-  [10]="black",
-}
-local panosewidths={
-  [ 0]="normal",
-  [ 1]="normal",
-  [ 2]="normal",
-  [ 3]="normal",
-  [ 4]="normal",
-  [ 5]="expanded",
-  [ 6]="condensed",
-  [ 7]="veryexpanded",
-  [ 8]="verycondensed",
-  [ 9]="monospaced",
-}
-local helpers={}
-readers.helpers=helpers
-local function gotodatatable(f,fontdata,tag,criterium)
-  if criterium and f then
-    local tables=fontdata.tables
-    if tables then
-      local datatable=tables[tag]
-      if datatable then
-        local tableoffset=datatable.offset
-        setposition(f,tableoffset)
-        return tableoffset
-      end
-    else
-      report("no tables")
-    end
-  end
-end
-local function reportskippedtable(f,fontdata,tag,criterium)
-  if criterium and f then
-    local tables=fontdata.tables
-    if tables then
-      local datatable=tables[tag]
-      if datatable then
-        report("loading of table %a skipped",tag)
-      end
-    else
-      report("no tables")
-    end
-  end
-end
-local function setvariabledata(fontdata,tag,data)
-  local variabledata=fontdata.variabledata
-  if variabledata then
-    variabledata[tag]=data
-  else
-    fontdata.variabledata={ [tag]=data }
-  end
-end
-helpers.gotodatatable=gotodatatable
-helpers.setvariabledata=setvariabledata
-helpers.reportskippedtable=reportskippedtable
-local platformnames={
-  postscriptname=true,
-  fullname=true,
-  family=true,
-  subfamily=true,
-  typographicfamily=true,
-  typographicsubfamily=true,
-  compatiblefullname=true,
-}
-local platformextras={
-  uniqueid=true,
-  version=true,
-  copyright=true,
-  license=true,
-  licenseurl=true,
-  manufacturer=true,
-  vendorurl=true,
-}
-function readers.name(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"name",true)
-  if tableoffset then
-    local format=readushort(f)
-    local nofnames=readushort(f)
-    local offset=readushort(f)
-    local start=tableoffset+offset
-    local namelists={
-      unicode={},
-      windows={},
-      macintosh={},
-    }
-    for i=1,nofnames do
-      local platform=platforms[readushort(f)]
-      if platform then
-        local namelist=namelists[platform]
-        if namelist then
-          local encoding=readushort(f)
-          local language=readushort(f)
-          local encodings=encodings[platform]
-          local languages=languages[platform]
-          if encodings and languages then
-            local encoding=encodings[encoding]
-            local language=languages[language]
-            if encoding and language then
-              local index=readushort(f)
-              local name=reservednames[index]
-              namelist[#namelist+1]={
-                platform=platform,
-                encoding=encoding,
-                language=language,
-                name=name,
-                index=index,
-                length=readushort(f),
-                offset=start+readushort(f),
-              }
-            else
-              skipshort(f,3)
-            end
-          else
-            skipshort(f,3)
-          end
-        else
-          skipshort(f,5)
-        end
-      else
-        skipshort(f,5)
-      end
-    end
-    local names={}
-    local done={}
-    local extras={}
-    local function decoded(platform,encoding,content)
-      local decoder=decoders[platform]
-      if decoder then
-        decoder=decoder[encoding]
-      end
-      if decoder then
-        return decoder(content)
-      else
-        return content
-      end
-    end
-    local function filter(platform,e,l)
-      local namelist=namelists[platform]
-      for i=1,#namelist do
-        local name=namelist[i]
-        local nametag=name.name
-        local index=name.index
-        if not done[nametag or i] then
-          local encoding=name.encoding
-          local language=name.language
-          if (not e or encoding==e) and (not l or language==l) then
-            setposition(f,name.offset)
-            local content=decoded(platform,encoding,readstring(f,name.length))
-            if nametag then
-              names[nametag]={
-                content=content,
-                platform=platform,
-                encoding=encoding,
-                language=language,
-              }
-            end
-            extras[index]=content
-            done[nametag or i]=true
-          end
-        end
-      end
-    end
-    filter("windows","unicode bmp","english - united states")
-    filter("macintosh","roman","english")
-    filter("windows")
-    filter("macintosh")
-    filter("unicode")
-    fontdata.names=names
-    fontdata.extras=extras
-    if specification.platformnames then
-      local collected={}
-      local platformextras=specification.platformextras and platformextras
-      for platform,namelist in next,namelists do
-        local filtered=false
-        for i=1,#namelist do
-          local entry=namelist[i]
-          local name=entry.name
-          if platformnames[name] or (platformextras and platformextras[name]) then
-            setposition(f,entry.offset)
-            local content=decoded(platform,entry.encoding,readstring(f,entry.length))
-            if filtered then
-              filtered[name]=content
-            else
-              filtered={ [name]=content }
-            end
-          end
-        end
-        if filtered then
-          collected[platform]=filtered
-        end
-      end
-      fontdata.platformnames=collected
-    end
-  else
-    fontdata.names={}
-  end
-end
-local validutf=lpeg.patterns.validutf8
-local function getname(fontdata,key)
-  local names=fontdata.names
-  if names then
-    local value=names[key]
-    if value then
-      local content=value.content
-      return lpegmatch(validutf,content) and content or nil
-    end
-  end
-end
-readers["os/2"]=function(f,fontdata)
-  local tableoffset=gotodatatable(f,fontdata,"os/2",true)
-  if tableoffset then
-    local version=readushort(f)
-    local windowsmetrics={
-      version=version,
-      averagewidth=readshort(f),
-      weightclass=readushort(f),
-      widthclass=readushort(f),
-      fstype=readushort(f),
-      subscriptxsize=readshort(f),
-      subscriptysize=readshort(f),
-      subscriptxoffset=readshort(f),
-      subscriptyoffset=readshort(f),
-      superscriptxsize=readshort(f),
-      superscriptysize=readshort(f),
-      superscriptxoffset=readshort(f),
-      superscriptyoffset=readshort(f),
-      strikeoutsize=readshort(f),
-      strikeoutpos=readshort(f),
-      familyclass=readshort(f),
-      panose={ readbytes(f,10) },
-      unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
-      vendor=readstring(f,4),
-      fsselection=readushort(f),
-      firstcharindex=readushort(f),
-      lastcharindex=readushort(f),
-      typoascender=readshort(f),
-      typodescender=readshort(f),
-      typolinegap=readshort(f),
-      winascent=readushort(f),
-      windescent=readushort(f),
-    }
-    if version>=1 then
-      windowsmetrics.codepageranges={ readulong(f),readulong(f) }
-    end
-    if version>=2 then
-      windowsmetrics.xheight=readshort(f)
-      windowsmetrics.capheight=readshort(f)
-      windowsmetrics.defaultchar=readushort(f)
-      windowsmetrics.breakchar=readushort(f)
-    end
-    windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
-    windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
-    windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
-    windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
-    fontdata.windowsmetrics=windowsmetrics
-  else
-    fontdata.windowsmetrics={}
-  end
-end
-readers.head=function(f,fontdata)
-  local tableoffset=gotodatatable(f,fontdata,"head",true)
-  if tableoffset then
-    local version=readulong(f)
-    local fontversion=readulong(f)
-    local fontheader={
-      version=version,
-      fontversion=number.to16dot16(fontversion),
-      fontversionnumber=fontversion,
-      checksum=readushort(f)*0x10000+readushort(f),
-      magic=readulong(f),
-      flags=readushort(f),
-      units=readushort(f),
-      created=readlongdatetime(f),
-      modified=readlongdatetime(f),
-      xmin=readshort(f),
-      ymin=readshort(f),
-      xmax=readshort(f),
-      ymax=readshort(f),
-      macstyle=readushort(f),
-      smallpixels=readushort(f),
-      directionhint=readshort(f),
-      indextolocformat=readshort(f),
-      glyphformat=readshort(f),
-    }
-    fontdata.fontheader=fontheader
-  else
-    fontdata.fontheader={}
-  end
-  fontdata.nofglyphs=0
-end
-readers.hhea=function(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
-  if tableoffset then
-    fontdata.horizontalheader={
-      version=readulong(f),
-      ascender=readfword(f),
-      descender=readfword(f),
-      linegap=readfword(f),
-      maxadvancewidth=readufword(f),
-      minleftsidebearing=readfword(f),
-      minrightsidebearing=readfword(f),
-      maxextent=readfword(f),
-      caretsloperise=readshort(f),
-      caretsloperun=readshort(f),
-      caretoffset=readshort(f),
-      reserved_1=readshort(f),
-      reserved_2=readshort(f),
-      reserved_3=readshort(f),
-      reserved_4=readshort(f),
-      metricdataformat=readshort(f),
-      nofmetrics=readushort(f),
-    }
-  else
-    fontdata.horizontalheader={
-      nofmetrics=0,
-    }
-  end
-end
-readers.vhea=function(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
-  if tableoffset then
-    fontdata.verticalheader={
-      version=readulong(f),
-      ascender=readfword(f),
-      descender=readfword(f),
-      linegap=readfword(f),
-      maxadvanceheight=readufword(f),
-      mintopsidebearing=readfword(f),
-      minbottomsidebearing=readfword(f),
-      maxextent=readfword(f),
-      caretsloperise=readshort(f),
-      caretsloperun=readshort(f),
-      caretoffset=readshort(f),
-      reserved_1=readshort(f),
-      reserved_2=readshort(f),
-      reserved_3=readshort(f),
-      reserved_4=readshort(f),
-      metricdataformat=readshort(f),
-      nofmetrics=readushort(f),
-    }
-  else
-    fontdata.verticalheader={
-      nofmetrics=0,
-    }
-  end
-end
-readers.maxp=function(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
-  if tableoffset then
-    local version=readulong(f)
-    local nofglyphs=readushort(f)
-    fontdata.nofglyphs=nofglyphs
-    if version==0x00005000 then
-      fontdata.maximumprofile={
-        version=version,
-        nofglyphs=nofglyphs,
-      }
-    elseif version==0x00010000 then
-      fontdata.maximumprofile={
-        version=version,
-        nofglyphs=nofglyphs,
-        points=readushort(f),
-        contours=readushort(f),
-        compositepoints=readushort(f),
-        compositecontours=readushort(f),
-        zones=readushort(f),
-        twilightpoints=readushort(f),
-        storage=readushort(f),
-        functiondefs=readushort(f),
-        instructiondefs=readushort(f),
-        stackelements=readushort(f),
-        sizeofinstructions=readushort(f),
-        componentelements=readushort(f),
-        componentdepth=readushort(f),
-      }
-    else
-      fontdata.maximumprofile={
-        version=version,
-        nofglyphs=0,
-      }
-    end
-  end
-end
-readers.hmtx=function(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs)
-  if tableoffset then
-    local horizontalheader=fontdata.horizontalheader
-    local nofmetrics=horizontalheader.nofmetrics
-    local glyphs=fontdata.glyphs
-    local nofglyphs=fontdata.nofglyphs
-    local width=0 
-    local leftsidebearing=0
-    for i=0,nofmetrics-1 do
-      local glyph=glyphs[i]
-      width=readshort(f) 
-      leftsidebearing=readshort(f)
-      if width~=0 then
-        glyph.width=width
-      end
-    end
-    for i=nofmetrics,nofglyphs-1 do
-      local glyph=glyphs[i]
-      if width~=0 then
-        glyph.width=width
-      end
-    end
-  end
-end
-readers.vmtx=function(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs)
-  if tableoffset then
-    local verticalheader=fontdata.verticalheader
-    local nofmetrics=verticalheader.nofmetrics
-    local glyphs=fontdata.glyphs
-    local nofglyphs=fontdata.nofglyphs
-    local vheight=0
-    local vdefault=verticalheader.ascender+verticalheader.descender
-    local topsidebearing=0
-    for i=0,nofmetrics-1 do
-      local glyph=glyphs[i]
-      vheight=readshort(f)
-      topsidebearing=readshort(f)
-      if vheight~=0 and vheight~=vdefault then
-        glyph.vheight=vheight
-      end
-    end
-    for i=nofmetrics,nofglyphs-1 do
-      local glyph=glyphs[i]
-      if vheight~=0 and vheight~=vdefault then
-        glyph.vheight=vheight
-      end
-    end
-  end
-end
-readers.vorg=function(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"vorg",specification.glyphs)
-end
-readers.post=function(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"post",true)
-  if tableoffset then
-    local version=readulong(f)
-    fontdata.postscript={
-      version=version,
-      italicangle=round(1000*readfixed(f))/1000,
-      underlineposition=readfword(f),
-      underlinethickness=readfword(f),
-      monospaced=readulong(f),
-      minmemtype42=readulong(f),
-      maxmemtype42=readulong(f),
-      minmemtype1=readulong(f),
-      maxmemtype1=readulong(f),
-    }
-    if not specification.glyphs then
-    elseif version==0x00010000 then
-      for index=0,#standardromanencoding do
-        glyphs[index].name=standardromanencoding[index]
-      end
-    elseif version==0x00020000 then
-      local glyphs=fontdata.glyphs
-      local nofglyphs=readushort(f)
-      local indices={}
-      local names={}
-      local maxnames=0
-      for i=0,nofglyphs-1 do
-        local nameindex=readushort(f)
-        if nameindex>=258 then
-          maxnames=maxnames+1
-          nameindex=nameindex-257
-          indices[nameindex]=i
-        else
-          glyphs[i].name=standardromanencoding[nameindex]
-        end
-      end
-      for i=1,maxnames do
-        local mapping=indices[i]
-        if not mapping then
-          report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
-          break
-        else
-          local length=readbyte(f)
-          if length>0 then
-            glyphs[mapping].name=readstring(f,length)
-          else
-            report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
-            break
-          end
-        end
-      end
-    end
-  else
-    fontdata.postscript={}
-  end
-end
-readers.cff=function(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"cff",specification.glyphs)
-end
-local formatreaders={}
-local duplicatestoo=true
-local sequence={
-  { 3,1,4 },
-  { 3,10,12 },
-  { 0,3,4 },
-  { 0,1,4 },
-  { 0,0,6 },
-  { 3,0,6 },
-  { 0,5,14 },
-{ 0,4,12 },
-  { 3,10,13 },
-}
-local supported={}
-for i=1,#sequence do
-  local si=sequence[i]
-  local sp,se,sf=si[1],si[2],si[3]
-  local p=supported[sp]
-  if not p then
-    p={}
-    supported[sp]=p
-  end
-  local e=p[se]
-  if not e then
-    e={}
-    p[se]=e
-  end
-  e[sf]=true
-end
-formatreaders[4]=function(f,fontdata,offset)
-  setposition(f,offset+2)
-  local length=readushort(f) 
-  local language=readushort(f)
-  local nofsegments=readushort(f)/2
-  skipshort(f,3)
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local nofdone=0
-  local endchars=readcardinaltable(f,nofsegments,ushort)
-  local reserved=readushort(f) 
-  local startchars=readcardinaltable(f,nofsegments,ushort)
-  local deltas=readcardinaltable(f,nofsegments,ushort)
-  local offsets=readcardinaltable(f,nofsegments,ushort)
-  local size=(length-2*2-5*2-4*2*nofsegments)/2
-  local indices=readcardinaltable(f,size-1,ushort)
-  for segment=1,nofsegments do
-    local startchar=startchars[segment]
-    local endchar=endchars[segment]
-    local offset=offsets[segment]
-    local delta=deltas[segment]
-    if startchar==0xFFFF and endchar==0xFFFF then
-    elseif startchar==0xFFFF and offset==0 then
-    elseif offset==0xFFFF then
-    elseif offset==0 then
-      if trace_cmap_detail then
-        report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
-      end
-      for unicode=startchar,endchar do
-        local index=(unicode+delta)%65536
-        if index and index>0 then
-          local glyph=glyphs[index]
-          if glyph then
-            local gu=glyph.unicode
-            if not gu then
-              glyph.unicode=unicode
-              nofdone=nofdone+1
-            elseif gu~=unicode then
-              if duplicatestoo then
-                local d=duplicates[gu]
-                if d then
-                  d[unicode]=true
-                else
-                  duplicates[gu]={ [unicode]=true }
-                end
-              else
-                report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
-              end
-            end
-            if not mapping[index] then
-              mapping[index]=unicode
-            end
-          end
-        end
-      end
-    else
-      local shift=(segment-nofsegments+offset/2)-startchar
-      if trace_cmap_detail then
-        report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
-      end
-      for unicode=startchar,endchar do
-        local slot=shift+unicode
-        local index=indices[slot]
-        if index and index>0 then
-          index=(index+delta)%65536
-          local glyph=glyphs[index]
-          if glyph then
-            local gu=glyph.unicode
-            if not gu then
-              glyph.unicode=unicode
-              nofdone=nofdone+1
-            elseif gu~=unicode then
-              if duplicatestoo then
-                local d=duplicates[gu]
-                if d then
-                  d[unicode]=true
-                else
-                  duplicates[gu]={ [unicode]=true }
-                end
-              else
-                report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
-              end
-            end
-            if not mapping[index] then
-              mapping[index]=unicode
-            end
-          end
-        end
-      end
-    end
-  end
-  return nofdone
-end
-formatreaders[6]=function(f,fontdata,offset)
-  setposition(f,offset) 
-  local format=readushort(f)
-  local length=readushort(f)
-  local language=readushort(f)
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local start=readushort(f)
-  local count=readushort(f)
-  local stop=start+count-1
-  local nofdone=0
-  if trace_cmap_detail then
-    report("format 6 from %C to %C",2,start,stop)
-  end
-  for unicode=start,stop do
-    local index=readushort(f)
-    if index>0 then
-      local glyph=glyphs[index]
-      if glyph then
-        local gu=glyph.unicode
-        if not gu then
-          glyph.unicode=unicode
-          nofdone=nofdone+1
-        elseif gu~=unicode then
-        end
-        if not mapping[index] then
-          mapping[index]=unicode
-        end
-      end
-    end
-  end
-  return nofdone
-end
-formatreaders[12]=function(f,fontdata,offset)
-  setposition(f,offset+2+2+4+4) 
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local nofgroups=readulong(f)
-  local nofdone=0
-  for i=1,nofgroups do
-    local first=readulong(f)
-    local last=readulong(f)
-    local index=readulong(f)
-    if trace_cmap_detail then
-      report("format 12 from %C to %C starts at index %i",first,last,index)
-    end
-    for unicode=first,last do
-      local glyph=glyphs[index]
-      if glyph then
-        local gu=glyph.unicode
-        if not gu then
-          glyph.unicode=unicode
-          nofdone=nofdone+1
-        elseif gu~=unicode then
-          local d=duplicates[gu]
-          if d then
-            d[unicode]=true
-          else
-            duplicates[gu]={ [unicode]=true }
-          end
-        end
-        if not mapping[index] then
-          mapping[index]=unicode
-        end
-      end
-      index=index+1
-    end
-  end
-  return nofdone
-end
-formatreaders[13]=function(f,fontdata,offset)
-  setposition(f,offset+2+2+4+4) 
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local nofgroups=readulong(f)
-  local nofdone=0
-  for i=1,nofgroups do
-    local first=readulong(f)
-    local last=readulong(f)
-    local index=readulong(f)
-    if first<privateoffset then
-      if trace_cmap_detail then
-        report("format 13 from %C to %C get index %i",first,last,index)
-      end
-      local glyph=glyphs[index]
-      local unicode=glyph.unicode
-      if not unicode then
-        unicode=first
-        glyph.unicode=unicode
-        first=first+1
-      end
-      local list=duplicates[unicode]
-      mapping[index]=unicode
-      if not list then
-        list={}
-        duplicates[unicode]=list
-      end
-      if last>=privateoffset then
-        local limit=privateoffset-1
-        report("format 13 from %C to %C pruned to %C",first,last,limit)
-        last=limit
-      end
-      for unicode=first,last do
-        list[unicode]=true
-      end
-      nofdone=nofdone+last-first+1
-    else
-      report("format 13 from %C to %C ignored",first,last)
-    end
-  end
-  return nofdone
-end
-formatreaders[14]=function(f,fontdata,offset)
-  if offset and offset~=0 then
-    setposition(f,offset)
-    local format=readushort(f)
-    local length=readulong(f)
-    local nofrecords=readulong(f)
-    local records={}
-    local variants={}
-    local nofdone=0
-    fontdata.variants=variants
-    for i=1,nofrecords do
-      records[i]={
-        selector=readuint(f),
-        default=readulong(f),
-        other=readulong(f),
-      }
-    end
-    for i=1,nofrecords do
-      local record=records[i]
-      local selector=record.selector
-      local default=record.default
-      local other=record.other
-      local other=record.other
-      if other~=0 then
-        setposition(f,offset+other)
-        local mapping={}
-        local count=readulong(f)
-        for i=1,count do
-          mapping[readuint(f)]=readushort(f)
-        end
-        nofdone=nofdone+count
-        variants[selector]=mapping
-      end
-    end
-    return nofdone
-  else
-    return 0
-  end
-end
-local function checkcmap(f,fontdata,records,platform,encoding,format)
-  local data=records[platform]
-  if not data then
-    return 0
-  end
-  data=data[encoding]
-  if not data then
-    return 0
-  end
-  data=data[format]
-  if not data then
-    return 0
-  end
-  local reader=formatreaders[format]
-  if not reader then
-    return 0
-  end
-  local p=platforms[platform]
-  local e=encodings[p]
-  local n=reader(f,fontdata,data) or 0
-  if trace_cmap then
-    report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n)
-  end
-  return n
-end
-function readers.cmap(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
-  if tableoffset then
-    local version=readushort(f)
-    local noftables=readushort(f)
-    local records={}
-    local unicodecid=false
-    local variantcid=false
-    local variants={}
-    local duplicates=fontdata.duplicates or {}
-    fontdata.duplicates=duplicates
-    for i=1,noftables do
-      local platform=readushort(f)
-      local encoding=readushort(f)
-      local offset=readulong(f)
-      local record=records[platform]
-      if not record then
-        records[platform]={
-          [encoding]={
-            offsets={ offset },
-            formats={},
-          }
-        }
-      else
-        local subtables=record[encoding]
-        if not subtables then
-          record[encoding]={
-            offsets={ offset },
-            formats={},
-          }
-        else
-          local offsets=subtables.offsets
-          offsets[#offsets+1]=offset
-        end
-      end
-    end
-    if trace_cmap then
-      report("found cmaps:")
-    end
-    for platform,record in sortedhash(records) do
-      local p=platforms[platform]
-      local e=encodings[p]
-      local sp=supported[platform]
-      local ps=p or "?"
-      if trace_cmap then
-        if sp then
-          report("  platform %i: %s",platform,ps)
-        else
-          report("  platform %i: %s (unsupported)",platform,ps)
-        end
-      end
-      for encoding,subtables in sortedhash(record) do
-        local se=sp and sp[encoding]
-        local es=e and e[encoding] or "?"
-        if trace_cmap then
-          if se then
-            report("    encoding %i: %s",encoding,es)
-          else
-            report("    encoding %i: %s (unsupported)",encoding,es)
-          end
-        end
-        local offsets=subtables.offsets
-        local formats=subtables.formats
-        for i=1,#offsets do
-          local offset=tableoffset+offsets[i]
-          setposition(f,offset)
-          formats[readushort(f)]=offset
-        end
-        record[encoding]=formats
-        if trace_cmap then
-          local list=sortedkeys(formats)
-          for i=1,#list do
-            if not (se and se[list[i]]) then
-              list[i]=list[i].." (unsupported)"
-            end
-          end
-          report("      formats: % t",list)
-        end
-      end
-    end
-    local ok=false
-    for i=1,#sequence do
-      local si=sequence[i]
-      local sp,se,sf=si[1],si[2],si[3]
-      if checkcmap(f,fontdata,records,sp,se,sf)>0 then
-        ok=true
-      end
-    end
-    if not ok then
-      report("no useable unicode cmap found")
-    end
-    fontdata.cidmaps={
-      version=version,
-      noftables=noftables,
-      records=records,
-    }
-  else
-    fontdata.cidmaps={}
-  end
-end
-function readers.loca(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"loca",specification.glyphs)
-end
-function readers.glyf(f,fontdata,specification) 
-  reportskippedtable(f,fontdata,"glyf",specification.glyphs)
-end
-function readers.colr(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"colr",specification.glyphs)
-end
-function readers.cpal(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"cpal",specification.glyphs)
-end
-function readers.svg(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"svg",specification.glyphs)
-end
-function readers.sbix(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"sbix",specification.glyphs)
-end
-function readers.cbdt(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
-end
-function readers.cblc(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"cblc",specification.glyphs)
-end
-function readers.ebdt(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
-end
-function readers.ebsc(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
-end
-function readers.eblc(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"eblc",specification.glyphs)
-end
-function readers.kern(f,fontdata,specification)
-  local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
-  if tableoffset then
-    local version=readushort(f)
-    local noftables=readushort(f)
-    for i=1,noftables do
-      local version=readushort(f)
-      local length=readushort(f)
-      local coverage=readushort(f)
-      local format=rshift(coverage,8) 
-      if format==0 then
-        local nofpairs=readushort(f)
-        local searchrange=readushort(f)
-        local entryselector=readushort(f)
-        local rangeshift=readushort(f)
-        local kerns={}
-        local glyphs=fontdata.glyphs
-        for i=1,nofpairs do
-          local left=readushort(f)
-          local right=readushort(f)
-          local kern=readfword(f)
-          local glyph=glyphs[left]
-          local kerns=glyph.kerns
-          if kerns then
-            kerns[right]=kern
-          else
-            glyph.kerns={ [right]=kern }
-          end
-        end
-      elseif format==2 then
-        report("todo: kern classes")
-      else
-        report("todo: kerns")
-      end
-    end
-  end
-end
-function readers.gdef(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"gdef",specification.details)
-end
-function readers.gsub(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"gsub",specification.details)
-end
-function readers.gpos(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"gpos",specification.details)
-end
-function readers.math(f,fontdata,specification)
-  reportskippedtable(f,fontdata,"math",specification.details)
-end
-local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
-  local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
-  local names=fontdata.names
-  local info=nil
-  if names then
-    local metrics=fontdata.windowsmetrics or {}
-    local postscript=fontdata.postscript   or {}
-    local fontheader=fontdata.fontheader   or {}
-    local cffinfo=fontdata.cffinfo    or {}
-    local filename=fontdata.filename
-    local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
-    local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
-    local fontname=getname(fontdata,"postscriptname")
-    local fullname=getname(fontdata,"fullname")
-    local family=getname(fontdata,"family")
-    local subfamily=getname(fontdata,"subfamily")
-    local familyname=getname(fontdata,"typographicfamily")
-    local subfamilyname=getname(fontdata,"typographicsubfamily")
-    local compatiblename=getname(fontdata,"compatiblefullname") 
-    if rawfamilynames then
-    else
-      if not  familyname then  familyname=family end
-      if not subfamilyname then subfamilyname=subfamily end
-    end
-    if platformnames then
-      platformnames=fontdata.platformnames
-    end
-    if instancenames then
-      local variabledata=fontdata.variabledata
-      if variabledata then
-        local instances=variabledata and variabledata.instances
-        if instances then
-          instancenames={}
-          for i=1,#instances do
-            instancenames[i]=lower(stripstring(instances[i].subfamily))
-          end
-        else
-          instancenames=nil
-        end
-      else
-        instancenames=nil
-      end
-    end
-    info={ 
-      subfontindex=fontdata.subfontindex or sub or 0,
-      version=getname(fontdata,"version"),
-      fontname=fontname,
-      fullname=fullname,
-      family=family,
-      subfamily=subfamily,
-      familyname=familyname,
-      subfamilyname=subfamilyname,
-      compatiblename=compatiblename,
-      weight=weight and lower(weight),
-      width=width and lower(width),
-      pfmweight=metrics.weightclass or 400,
-      pfmwidth=metrics.widthclass or 5,
-      panosewidth=metrics.panosewidth,
-      panoseweight=metrics.panoseweight,
-      italicangle=postscript.italicangle or 0,
-      units=fontheader.units or 0,
-      designsize=fontdata.designsize,
-      minsize=fontdata.minsize,
-      maxsize=fontdata.maxsize,
-      boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil,
-      monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
-      averagewidth=metrics.averagewidth,
-      xheight=metrics.xheight,
-      capheight=metrics.capheight or fontdata.maxy,
-      ascender=metrics.typoascender,
-      descender=metrics.typodescender,
-      platformnames=platformnames or nil,
-      instancenames=instancenames or nil,
-      tableoffsets=fontdata.tableoffsets,
-    }
-    if metricstoo then
-      local keys={
-        "version",
-        "ascender","descender","linegap",
-        "maxadvancewidth","maxadvanceheight","maxextent",
-        "minbottomsidebearing","mintopsidebearing",
-      }
-      local h=fontdata.horizontalheader or {}
-      local v=fontdata.verticalheader  or {}
-      if h then
-        local th={}
-        local tv={}
-        for i=1,#keys do
-          local key=keys[i]
-          th[key]=h[key] or 0
-          tv[key]=v[key] or 0
-        end
-        info.horizontalmetrics=th
-        info.verticalmetrics=tv
-      end
-    end
-  elseif n then
-    info={
-      filename=fontdata.filename,
-      comment="there is no info for subfont "..n,
-    }
-  else
-    info={
-      filename=fontdata.filename,
-      comment="there is no info",
-    }
-  end
-  return info
-end
-local function loadtables(f,specification,offset)
-  if offset then
-    setposition(f,offset)
-  end
-  local tables={}
-  local basename=file.basename(specification.filename)
-  local filesize=specification.filesize
-  local filetime=specification.filetime
-  local fontdata={ 
-    filename=basename,
-    filesize=filesize,
-    filetime=filetime,
-    version=readstring(f,4),
-    noftables=readushort(f),
-    searchrange=readushort(f),
-    entryselector=readushort(f),
-    rangeshift=readushort(f),
-    tables=tables,
-    foundtables=false,
-  }
-  for i=1,fontdata.noftables do
-    local tag=lower(stripstring(readstring(f,4)))
-    local checksum=readushort(f)*0x10000+readushort(f)
-    local offset=readulong(f)
-    local length=readulong(f)
-    if offset+length>filesize then
-      report("bad %a table in file %a",tag,basename)
-    end
-    tables[tag]={
-      checksum=checksum,
-      offset=offset,
-      length=length,
-    }
-  end
-  fontdata.foundtables=sortedkeys(tables)
-  if tables.cff or tables.cff2 then
-    fontdata.format="opentype"
-  else
-    fontdata.format="truetype"
-  end
-  return fontdata,tables
-end
-local function prepareglyps(fontdata)
-  local glyphs=setmetatableindex(function(t,k)
-    local v={
-      index=k,
-    }
-    t[k]=v
-    return v
-  end)
-  fontdata.glyphs=glyphs
-  fontdata.mapping={}
-end
-local function readtable(tag,f,fontdata,specification,...)
-  local reader=readers[tag]
-  if reader then
-    reader(f,fontdata,specification,...)
-  end
-end
-local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
-local function readdata(f,offset,specification)
-  local fontdata,tables=loadtables(f,specification,offset)
-  if specification.glyphs then
-    prepareglyps(fontdata)
-  end
-  if not variablefonts_supported then
-    specification.instance=nil
-    specification.variable=nil
-    specification.factors=nil
-  end
-  fontdata.temporary={}
-  readtable("name",f,fontdata,specification)
-  local askedname=specification.askedname
-  if askedname then
-    local fullname=getname(fontdata,"fullname") or ""
-    local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
-    local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
-    if lower(cleanname)~=lower(foundname) then
-      return 
-    end
-  end
-  readtable("stat",f,fontdata,specification)
-  readtable("avar",f,fontdata,specification)
-  readtable("fvar",f,fontdata,specification)
-  if variablefonts_supported then
-    local variabledata=fontdata.variabledata
-    if variabledata then
-      local instances=variabledata.instances
-      local axis=variabledata.axis
-      if axis and (not instances or #instances==0) then
-        instances={}
-        variabledata.instances=instances
-        local function add(n,subfamily,value)
-          local values={}
-          for i=1,#axis do
-            local a=axis[i]
-            values[i]={
-              axis=a.tag,
-              value=i==n and value or a.default,
-            }
-          end
-          instances[#instances+1]={
-            subfamily=subfamily,
-            values=values,
-          }
-        end
-        for i=1,#axis do
-          local a=axis[i]
-          local tag=a.tag
-          add(i,"default"..tag,a.default)
-          add(i,"minimum"..tag,a.minimum)
-          add(i,"maximum"..tag,a.maximum)
-        end
-      end
-    end
-    if not specification.factors then
-      local instance=specification.instance
-      if type(instance)=="string" then
-        local factors=helpers.getfactors(fontdata,instance)
-        if factors then
-          specification.factors=factors
-          fontdata.factors=factors
-          fontdata.instance=instance
-          report("user instance: %s, factors: % t",instance,factors)
-        else
-          report("user instance: %s, bad factors",instance)
-        end
-      end
-    end
-    if not fontdata.factors then
-      if fontdata.variabledata then
-        local factors=helpers.getfactors(fontdata,true)
-        if factors then
-          specification.factors=factors
-          fontdata.factors=factors
-        end
-      else
-      end
-    end
-  end
-  readtable("os/2",f,fontdata,specification)
-  readtable("head",f,fontdata,specification)
-  readtable("maxp",f,fontdata,specification)
-  readtable("hhea",f,fontdata,specification)
-  readtable("vhea",f,fontdata,specification)
-  readtable("hmtx",f,fontdata,specification)
-  readtable("vmtx",f,fontdata,specification)
-  readtable("vorg",f,fontdata,specification)
-  readtable("post",f,fontdata,specification)
-  readtable("mvar",f,fontdata,specification)
-  readtable("hvar",f,fontdata,specification)
-  readtable("vvar",f,fontdata,specification)
-  readtable("gdef",f,fontdata,specification)
-  readtable("cff",f,fontdata,specification)
-  readtable("cff2",f,fontdata,specification)
-  readtable("cmap",f,fontdata,specification)
-  readtable("loca",f,fontdata,specification) 
-  readtable("glyf",f,fontdata,specification) 
-  readtable("colr",f,fontdata,specification)
-  readtable("cpal",f,fontdata,specification)
-  readtable("svg",f,fontdata,specification)
-  readtable("sbix",f,fontdata,specification)
-  readtable("cbdt",f,fontdata,specification)
-  readtable("cblc",f,fontdata,specification)
-  readtable("ebdt",f,fontdata,specification)
-  readtable("eblc",f,fontdata,specification)
-  readtable("kern",f,fontdata,specification)
-  readtable("gsub",f,fontdata,specification)
-  readtable("gpos",f,fontdata,specification)
-  readtable("math",f,fontdata,specification)
-  fontdata.locations=nil
-  fontdata.cidmaps=nil
-  fontdata.dictionaries=nil
-  if specification.tableoffsets then
-    fontdata.tableoffsets=tables
-    setmetatableindex(tables,{
-      version=fontdata.version,
-      noftables=fontdata.noftables,
-      searchrange=fontdata.searchrange,
-      entryselector=fontdata.entryselector,
-      rangeshift=fontdata.rangeshift,
-    })
-  end
-  return fontdata
-end
-local function loadfontdata(specification)
-  local filename=specification.filename
-  local fileattr=lfs.attributes(filename)
-  local filesize=fileattr and fileattr.size or 0
-  local filetime=fileattr and fileattr.modification or 0
-  local f=openfile(filename,true) 
-  if not f then
-    report("unable to open %a",filename)
-  elseif filesize==0 then
-    report("empty file %a",filename)
-    closefile(f)
-  else
-    specification.filesize=filesize
-    specification.filetime=filetime
-    local version=readstring(f,4)
-    local fontdata=nil
-    if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
-      fontdata=readdata(f,0,specification)
-    elseif version=="ttcf" then
-      local subfont=tonumber(specification.subfont)
-      local ttcversion=readulong(f)
-      local nofsubfonts=readulong(f)
-      local offsets=readcardinaltable(f,nofsubfonts,ulong)
-      if subfont then 
-        if subfont>=1 and subfont<=nofsubfonts then
-          fontdata=readdata(f,offsets[subfont],specification)
-        else
-          report("no subfont %a in file %a",subfont,filename)
-        end
-      else
-        subfont=specification.subfont
-        if type(subfont)=="string" and subfont~="" then
-          specification.askedname=subfont
-          for i=1,nofsubfonts do
-            fontdata=readdata(f,offsets[i],specification)
-            if fontdata then
-              fontdata.subfontindex=i
-              report("subfont named %a has index %a",subfont,i)
-              break
-            end
-          end
-          if not fontdata then
-            report("no subfont named %a",subfont)
-          end
-        else
-          local subfonts={}
-          fontdata={
-            filename=filename,
-            filesize=filesize,
-            filetime=filetime,
-            version=version,
-            subfonts=subfonts,
-            ttcversion=ttcversion,
-            nofsubfonts=nofsubfonts,
-          }
-          for i=1,nofsubfonts do
-            subfonts[i]=readdata(f,offsets[i],specification)
-          end
-        end
-      end
-    else
-      report("unknown version %a in file %a",version,filename)
-    end
-    closefile(f)
-    return fontdata or {}
-  end
-end
-local function loadfont(specification,n,instance)
-  if type(specification)=="string" then
-    specification={
-      filename=specification,
-      info=true,
-      details=true,
-      glyphs=true,
-      shapes=true,
-      kerns=true,
-      variable=true,
-      globalkerns=true,
-      lookups=true,
-      subfont=n or true,
-      tounicode=false,
-      instance=instance
-    }
-  end
-  if specification.shapes or specification.lookups or specification.kerns then
-    specification.glyphs=true
-  end
-  if specification.glyphs then
-    specification.details=true
-  end
-  if specification.details then
-    specification.info=true 
-  end
-  if specification.platformnames then
-    specification.platformnames=true 
-  end
-  if specification.instance or instance then
-    specification.variable=true
-    specification.instance=specification.instance or instance
-  end
-  local function message(str)
-    report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
-  end
-  local ok,result=xpcall(loadfontdata,message,specification)
-  if ok then
-    return result
-  end
-end
-function readers.loadshapes(filename,n,instance,streams)
-  local fontdata=loadfont {
-    filename=filename,
-    shapes=true,
-    streams=streams,
-    variable=true,
-    subfont=n,
-    instance=instance,
-  }
-  if fontdata then
-    for k,v in next,fontdata.glyphs do
-      v.class=nil
-      v.index=nil
-      v.math=nil
-    end
-    local names=fontdata.names
-    if names then
-      for k,v in next,names do
-        names[k]=fullstrip(v.content)
-      end
-    end
-  end
-  return fontdata and {
-    filename=filename,
-    format=fontdata.format,
-    glyphs=fontdata.glyphs,
-    units=fontdata.fontheader.units,
-    cffinfo=fontdata.cffinfo,
-    fontheader=fontdata.fontheader,
-    horizontalheader=fontdata.horizontalheader,
-    verticalheader=fontdata.verticalheader,
-    maximumprofile=fontdata.maximumprofile,
-    names=fontdata.names,
-    postscript=fontdata.postscript,
-  } or {
-    filename=filename,
-    format="unknown",
-    glyphs={},
-    units=0,
-  }
-end
-function readers.loadfont(filename,n,instance)
-  local fontdata=loadfont {
-    filename=filename,
-    glyphs=true,
-    shapes=false,
-    lookups=true,
-    variable=true,
-    subfont=n,
-    instance=instance,
-  }
-  if fontdata then
-    return {
-      tableversion=tableversion,
-      creator="context mkiv",
-      size=fontdata.filesize,
-      time=fontdata.filetime,
-      glyphs=fontdata.glyphs,
-      descriptions=fontdata.descriptions,
-      format=fontdata.format,
-      goodies={},
-      metadata=getinfo(fontdata,n,false,false,true,true),
-      properties={
-        hasitalics=fontdata.hasitalics or false,
-        maxcolorclass=fontdata.maxcolorclass,
-        hascolor=fontdata.hascolor or false,
-        instance=fontdata.instance,
-        factors=fontdata.factors,
-      },
-      resources={
-        filename=filename,
-        private=privateoffset,
-        duplicates=fontdata.duplicates or {},
-        features=fontdata.features  or {},
-        sublookups=fontdata.sublookups or {},
-        marks=fontdata.marks    or {},
-        markclasses=fontdata.markclasses or {},
-        marksets=fontdata.marksets  or {},
-        sequences=fontdata.sequences  or {},
-        variants=fontdata.variants,
-        version=getname(fontdata,"version"),
-        cidinfo=fontdata.cidinfo,
-        mathconstants=fontdata.mathconstants,
-        colorpalettes=fontdata.colorpalettes,
-        svgshapes=fontdata.svgshapes,
-        pngshapes=fontdata.pngshapes,
-        variabledata=fontdata.variabledata,
-        foundtables=fontdata.foundtables,
-      },
-    }
-  end
-end
-function readers.getinfo(filename,specification)
-  local subfont=nil
-  local platformnames=false
-  local rawfamilynames=false
-  local instancenames=true
-  local tableoffsets=false
-  if type(specification)=="table" then
-    subfont=tonumber(specification.subfont)
-    platformnames=specification.platformnames
-    rawfamilynames=specification.rawfamilynames
-    tableoffsets=specification.tableoffsets
-  else
-    subfont=tonumber(specification)
-  end
-  local fontdata=loadfont {
-    filename=filename,
-    details=true,
-    platformnames=platformnames,
-    instancenames=true,
-    tableoffsets=tableoffsets,
-  }
-  if fontdata then
-    local subfonts=fontdata.subfonts
-    if not subfonts then
-      return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
-    elseif not subfont then
-      local info={}
-      for i=1,#subfonts do
-        info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
-      end
-      return info
-    elseif subfont>=1 and subfont<=#subfonts then
-      return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
-    else
-      return {
-        filename=filename,
-        comment="there is no subfont "..subfont.." in this file"
-      }
-    end
-  else
-    return {
-      filename=filename,
-      comment="the file cannot be opened for reading",
-    }
-  end
-end
-function readers.rehash(fontdata,hashmethod)
-  report("the %a helper is not yet implemented","rehash")
-end
-function readers.checkhash(fontdata)
-  report("the %a helper is not yet implemented","checkhash")
-end
-function readers.pack(fontdata,hashmethod)
-  report("the %a helper is not yet implemented","pack")
-end
-function readers.unpack(fontdata)
-  report("the %a helper is not yet implemented","unpack")
-end
-function readers.expand(fontdata)
-  report("the %a helper is not yet implemented","unpack")
-end
-function readers.compact(fontdata)
-  report("the %a helper is not yet implemented","compact")
-end
-local extenders={}
-function readers.registerextender(extender)
-  extenders[#extenders+1]=extender
-end
-function readers.extend(fontdata)
-  for i=1,#extenders do
-    local extender=extenders[i]
-    local name=extender.name or "unknown"
-    local action=extender.action
-    if action then
-      action(fontdata)
-    end
-  end
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-otr”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] ---
-
-if not modules then modules={} end modules ['font-oti']={
-  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"
-}
-local lower=string.lower
-local fonts=fonts
-local constructors=fonts.constructors
-local otf=constructors.handlers.otf
-local otffeatures=constructors.features.otf
-local registerotffeature=otffeatures.register
-local otftables=otf.tables or {}
-otf.tables=otftables
-local allocate=utilities.storage.allocate
-registerotffeature {
-  name="features",
-  description="initialization of feature handler",
-  default=true,
-}
-local function setmode(tfmdata,value)
-  if value then
-    tfmdata.properties.mode=lower(value)
-  end
-end
-otf.modeinitializer=setmode
-local function setlanguage(tfmdata,value)
-  if value then
-    local cleanvalue=lower(value)
-    local languages=otftables and otftables.languages
-    local properties=tfmdata.properties
-    if not languages then
-      properties.language=cleanvalue
-    elseif languages[value] then
-      properties.language=cleanvalue
-    else
-      properties.language="dflt"
-    end
-  end
-end
-local function setscript(tfmdata,value)
-  if value then
-    local cleanvalue=lower(value)
-    local scripts=otftables and otftables.scripts
-    local properties=tfmdata.properties
-    if not scripts then
-      properties.script=cleanvalue
-    elseif scripts[value] then
-      properties.script=cleanvalue
-    else
-      properties.script="dflt"
-    end
-  end
-end
-registerotffeature {
-  name="mode",
-  description="mode",
-  initializers={
-    base=setmode,
-    node=setmode,
-    plug=setmode,
-  }
-}
-registerotffeature {
-  name="language",
-  description="language",
-  initializers={
-    base=setlanguage,
-    node=setlanguage,
-    plug=setlanguage,
-  }
-}
-registerotffeature {
-  name="script",
-  description="script",
-  initializers={
-    base=setscript,
-    node=setscript,
-    plug=setscript,
-  }
-}
-otftables.featuretypes=allocate {
-  gpos_single="position",
-  gpos_pair="position",
-  gpos_cursive="position",
-  gpos_mark2base="position",
-  gpos_mark2ligature="position",
-  gpos_mark2mark="position",
-  gpos_context="position",
-  gpos_contextchain="position",
-  gsub_single="substitution",
-  gsub_multiple="substitution",
-  gsub_alternate="substitution",
-  gsub_ligature="substitution",
-  gsub_context="substitution",
-  gsub_contextchain="substitution",
-  gsub_reversecontextchain="substitution",
-  gsub_reversesub="substitution",
-}
-function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
-  if featuretype=="position" then
-    local default=scripts.dflt
-    if default then
-      if autoscript=="position" or autoscript==true then
-        return default
-      else
-        report_otf("script feature %s not applied, enable default positioning")
-      end
-    else
-    end
-  elseif featuretype=="substitution" then
-    local default=scripts.dflt
-    if default then
-      if autoscript=="substitution" or autoscript==true then
-        return default
-      end
-    end
-  end
-end
-function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
-  if featuretype=="position" then
-    local default=languages.dflt
-    if default then
-      if autolanguage=="position" or autolanguage==true then
-        return default
-      else
-        report_otf("language feature %s not applied, enable default positioning")
-      end
-    else
-    end
-  elseif featuretype=="substitution" then
-    local default=languages.dflt
-    if default then
-      if autolanguage=="substitution" or autolanguage==true then
-        return default
-      end
-    end
-  end
-end
-
-end --- [luaotfload, fontloader-2019-01-30.lua scope for “font-oti”] ---
-
-
-do  --- [luaotfload, fontloader-2019-01-30.lua scope for “font-ott” a8b78a27cbb22d4f697a8dd801a73eea] ---
-
-if not modules then modules={} end modules ["font-ott"]={
-  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",
-}
-local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
-local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
-local sequenced=table.sequenced
-local is_boolean=string.is_boolean
-local setmetatableindex=table.setmetatableindex
-local setmetatablenewindex=table.setmetatablenewindex
-local allocate=utilities.storage.allocate
-local fonts=fonts
-local otf=fonts.handlers.otf
-local otffeatures=otf.features
-local tables=otf.tables or {}
-otf.tables=tables
-local statistics=otf.statistics or {}
-otf.statistics=statistics
-local scripts=allocate {
-  ["arab"]="arabic",
-  ["armi"]="imperial aramaic",
-  ["armn"]="armenian",
-  ["avst"]="avestan",
-  ["bali"]="balinese",
-  ["bamu"]="bamum",
-  ["batk"]="batak",
-  ["beng"]="bengali",
-  ["bng2"]="bengali variant 2",
-  ["bopo"]="bopomofo",
-  ["brah"]="brahmi",
-  ["brai"]="braille",
-  ["bugi"]="buginese",
-  ["buhd"]="buhid",
-  ["byzm"]="byzantine music",
-  ["cakm"]="chakma",
-  ["cans"]="canadian syllabics",
-  ["cari"]="carian",
-  ["cham"]="cham",
-  ["cher"]="cherokee",
-  ["copt"]="coptic",
-  ["cprt"]="cypriot syllabary",
-  ["cyrl"]="cyrillic",
-  ["deva"]="devanagari",
-  ["dev2"]="devanagari variant 2",
-  ["dsrt"]="deseret",
-  ["egyp"]="egyptian heiroglyphs",
-  ["ethi"]="ethiopic",
-  ["geor"]="georgian",
-  ["glag"]="glagolitic",
-  ["goth"]="gothic",
-  ["grek"]="greek",
-  ["gujr"]="gujarati",
-  ["gjr2"]="gujarati variant 2",
-  ["guru"]="gurmukhi",
-  ["gur2"]="gurmukhi variant 2",
-  ["hang"]="hangul",
-  ["hani"]="cjk ideographic",
-  ["hano"]="hanunoo",
-  ["hebr"]="hebrew",
-  ["ital"]="old italic",
-  ["jamo"]="hangul jamo",
-  ["java"]="javanese",
-  ["kali"]="kayah li",
-  ["kana"]="hiragana and katakana",
-  ["khar"]="kharosthi",
-  ["khmr"]="khmer",
-  ["knda"]="kannada",
-  ["knd2"]="kannada variant 2",
-  ["kthi"]="kaithi",
-  ["lana"]="tai tham",
-  ["lao" ]="lao",
-  ["latn"]="latin",
-  ["lepc"]="lepcha",
-  ["limb"]="limbu",
-  ["linb"]="linear b",
-  ["lisu"]="lisu",
-  ["lyci"]="lycian",
-  ["lydi"]="lydian",
-  ["mand"]="mandaic and mandaean",
-  ["math"]="mathematical alphanumeric symbols",
-  ["merc"]="meroitic cursive",
-  ["mero"]="meroitic hieroglyphs",
-  ["mlym"]="malayalam",
-  ["mlm2"]="malayalam variant 2",
-  ["mong"]="mongolian",
-  ["mtei"]="meitei Mayek",
-  ["musc"]="musical symbols",
-  ["mym2"]="myanmar variant 2",
-  ["mymr"]="myanmar",
-  ["nko" ]='n"ko',
-  ["ogam"]="ogham",
-  ["olck"]="ol chiki",
-  ["orkh"]="old turkic and orkhon runic",
-  ["orya"]="oriya",
-  ["ory2"]="odia variant 2",
-  ["osma"]="osmanya",
-  ["phag"]="phags-pa",
-  ["phli"]="inscriptional pahlavi",
-  ["phnx"]="phoenician",
-  ["prti"]="inscriptional parthian",
-  ["rjng"]="rejang",
-  ["runr"]="runic",
-  ["samr"]="samaritan",
-  ["sarb"]="old south arabian",
-  ["saur"]="saurashtra",
-  ["shaw"]="shavian",
-  ["shrd"]="sharada",
-  ["sinh"]="sinhala",
-  ["sora"]="sora sompeng",
-  ["sund"]="sundanese",
-  ["sylo"]="syloti nagri",
-  ["syrc"]="syriac",
-  ["tagb"]="tagbanwa",
-  ["takr"]="takri",
-  ["tale"]="tai le",
-  ["talu"]="tai lu",
-  ["taml"]="tamil",
-  ["tavt"]="tai viet",
-  ["telu"]="telugu",
-  ["tel2"]="telugu variant 2",
-  ["tfng"]="tifinagh",
-  ["tglg"]="tagalog",
-  ["thaa"]="thaana",
-  ["thai"]="thai",
-  ["tibt"]="tibetan",
-  ["tml2"]="tamil variant 2",
-  ["ugar"]="ugaritic cuneiform",
-  ["vai" ]="vai",
-  ["xpeo"]="old persian cuneiform",
-  ["xsux"]="sumero-akkadian cuneiform",
-  ["yi" ]="yi",
-}
-local languages=allocate {
-  ["aba" ]="abaza",
-  ["abk" ]="abkhazian",
-  ["ach" ]="acholi",
-  ["acr" ]="achi",
-  ["ady" ]="adyghe",
-  ["afk" ]="afrikaans",
-  ["afr" ]="afar",
-  ["agw" ]="agaw",
-  ["aio" ]="aiton",
-  ["aka" ]="akan",
-  ["als" ]="alsatian",
-  ["alt" ]="altai",
-  ["amh" ]="amharic",
-  ["ang" ]="anglo-saxon",
-  ["apph"]="phonetic transcription—americanist conventions",
-  ["ara" ]="arabic",
-  ["arg" ]="aragonese",
-  ["ari" ]="aari",
-  ["ark" ]="rakhine",
-  ["asm" ]="assamese",
-  ["ast" ]="asturian",
-  ["ath" ]="athapaskan",
-  ["avr" ]="avar",
-  ["awa" ]="awadhi",
-  ["aym" ]="aymara",
-  ["azb" ]="torki",
-  ["aze" ]="azerbaijani",
-  ["bad" ]="badaga",
-  ["bad0"]="banda",
-  ["bag" ]="baghelkhandi",
-  ["bal" ]="balkar",
-  ["ban" ]="balinese",
-  ["bar" ]="bavarian",
-  ["bau" ]="baulé",
-  ["bbc" ]="batak toba",
-  ["bbr" ]="berber",
-  ["bch" ]="bench",
-  ["bcr" ]="bible cree",
-  ["bdy" ]="bandjalang",
-  ["bel" ]="belarussian",
-  ["bem" ]="bemba",
-  ["ben" ]="bengali",
-  ["bgc" ]="haryanvi",
-  ["bgq" ]="bagri",
-  ["bgr" ]="bulgarian",
-  ["bhi" ]="bhili",
-  ["bho" ]="bhojpuri",
-  ["bik" ]="bikol",
-  ["bil" ]="bilen",
-  ["bis" ]="bislama",
-  ["bjj" ]="kanauji",
-  ["bkf" ]="blackfoot",
-  ["bli" ]="baluchi",
-  ["blk" ]="pa'o karen",
-  ["bln" ]="balante",
-  ["blt" ]="balti",
-  ["bmb" ]="bambara (bamanankan)",
-  ["bml" ]="bamileke",
-  ["bos" ]="bosnian",
-  ["bpy" ]="bishnupriya manipuri",
-  ["bre" ]="breton",
-  ["brh" ]="brahui",
-  ["bri" ]="braj bhasha",
-  ["brm" ]="burmese",
-  ["brx" ]="bodo",
-  ["bsh" ]="bashkir",
-  ["bti" ]="beti",
-  ["bts" ]="batak simalungun",
-  ["bug" ]="bugis",
-  ["cak" ]="kaqchikel",
-  ["cat" ]="catalan",
-  ["cbk" ]="zamboanga chavacano",
-  ["ceb" ]="cebuano",
-  ["cgg" ]="chiga",
-  ["cha" ]="chamorro",
-  ["che" ]="chechen",
-  ["chg" ]="chaha gurage",
-  ["chh" ]="chattisgarhi",
-  ["chi" ]="chichewa (chewa, nyanja)",
-  ["chk" ]="chukchi",
-  ["chk0"]="chuukese",
-  ["cho" ]="choctaw",
-  ["chp" ]="chipewyan",
-  ["chr" ]="cherokee",
-  ["chu" ]="chuvash",
-  ["chy" ]="cheyenne",
-  ["cmr" ]="comorian",
-  ["cop" ]="coptic",
-  ["cor" ]="cornish",
-  ["cos" ]="corsican",
-  ["cpp" ]="creoles",
-  ["cre" ]="cree",
-  ["crr" ]="carrier",
-  ["crt" ]="crimean tatar",
-  ["csb" ]="kashubian",
-  ["csl" ]="church slavonic",
-  ["csy" ]="czech",
-  ["ctg" ]="chittagonian",
-  ["cuk" ]="san blas kuna",
-  ["dan" ]="danish",
-  ["dar" ]="dargwa",
-  ["dax" ]="dayi",
-  ["dcr" ]="woods cree",
-  ["deu" ]="german",
-  ["dgo" ]="dogri",
-  ["dgr" ]="dogri",
-  ["dhg" ]="dhangu",
-  ["dhv" ]="divehi (dhivehi, maldivian)",
-  ["diq" ]="dimli",
-  ["div" ]="divehi (dhivehi, maldivian)",
-  ["djr" ]="zarma",
-  ["djr0"]="djambarrpuyngu",
-  ["dng" ]="dangme",
-  ["dnj" ]="dan",
-  ["dnk" ]="dinka",
-  ["dri" ]="dari",
-  ["duj" ]="dhuwal",
-  ["dun" ]="dungan",
-  ["dzn" ]="dzongkha",
-  ["ebi" ]="ebira",
-  ["ecr" ]="eastern cree",
-  ["edo" ]="edo",
-  ["efi" ]="efik",
-  ["ell" ]="greek",
-  ["emk" ]="eastern maninkakan",
-  ["eng" ]="english",
-  ["erz" ]="erzya",
-  ["esp" ]="spanish",
-  ["esu" ]="central yupik",
-  ["eti" ]="estonian",
-  ["euq" ]="basque",
-  ["evk" ]="evenki",
-  ["evn" ]="even",
-  ["ewe" ]="ewe",
-  ["fan" ]="french antillean",
-  ["fan0"]=" fang",
-  ["far" ]="persian",
-  ["fat" ]="fanti",
-  ["fin" ]="finnish",
-  ["fji" ]="fijian",
-  ["fle" ]="dutch (flemish)",
-  ["fne" ]="forest nenets",
-  ["fon" ]="fon",
-  ["fos" ]="faroese",
-  ["fra" ]="french",
-  ["frc" ]="cajun french",
-  ["fri" ]="frisian",
-  ["frl" ]="friulian",
-  ["frp" ]="arpitan",
-  ["fta" ]="futa",
-  ["ful" ]="fulah",
-  ["fuv" ]="nigerian fulfulde",
-  ["gad" ]="ga",
-  ["gae" ]="scottish gaelic (gaelic)",
-  ["gag" ]="gagauz",
-  ["gal" ]="galician",
-  ["gar" ]="garshuni",
-  ["gaw" ]="garhwali",
-  ["gez" ]="ge'ez",
-  ["gih" ]="githabul",
-  ["gil" ]="gilyak",
-  ["gil0"]="kiribati (gilbertese)",
-  ["gkp" ]="kpelle (guinea)",
-  ["glk" ]="gilaki",
-  ["gmz" ]="gumuz",
-  ["gnn" ]="gumatj",
-  ["gog" ]="gogo",
-  ["gon" ]="gondi",
-  ["grn" ]="greenlandic",
-  ["gro" ]="garo",
-  ["gua" ]="guarani",
-  ["guc" ]="wayuu",
-  ["guf" ]="gupapuyngu",
-  ["guj" ]="gujarati",
-  ["guz" ]="gusii",
-  ["hai" ]="haitian (haitian creole)",
-  ["hal" ]="halam",
-  ["har" ]="harauti",
-  ["hau" ]="hausa",
-  ["haw" ]="hawaiian",
-  ["hay" ]="haya",
-  ["haz" ]="hazaragi",
-  ["hbn" ]="hammer-banna",
-  ["her" ]="herero",
-  ["hil" ]="hiligaynon",
-  ["hin" ]="hindi",
-  ["hma" ]="high mari",
-  ["hmn" ]="hmong",
-  ["hmo" ]="hiri motu",
-  ["hnd" ]="hindko",
-  ["ho" ]="ho",
-  ["hri" ]="harari",
-  ["hrv" ]="croatian",
-  ["hun" ]="hungarian",
-  ["hye" ]="armenian",
-  ["hye0"]="armenian east",
-  ["iba" ]="iban",
-  ["ibb" ]="ibibio",
-  ["ibo" ]="igbo",
-  ["ido" ]="ido",
-  ["ijo" ]="ijo languages",
-  ["ile" ]="interlingue",
-  ["ilo" ]="ilokano",
-  ["ina" ]="interlingua",
-  ["ind" ]="indonesian",
-  ["ing" ]="ingush",
-  ["inu" ]="inuktitut",
-  ["ipk" ]="inupiat",
-  ["ipph"]="phonetic transcription—ipa conventions",
-  ["iri" ]="irish",
-  ["irt" ]="irish traditional",
-  ["isl" ]="icelandic",
-  ["ism" ]="inari sami",
-  ["ita" ]="italian",
-  ["iwr" ]="hebrew",
-  ["jam" ]="jamaican creole",
-  ["jan" ]="japanese",
-  ["jav" ]="javanese",
-  ["jbo" ]="lojban",
-  ["jii" ]="yiddish",
-  ["jud" ]="ladino",
-  ["jul" ]="jula",
-  ["kab" ]="kabardian",
-  ["kab0"]="kabyle",
-  ["kac" ]="kachchi",
-  ["kal" ]="kalenjin",
-  ["kan" ]="kannada",
-  ["kar" ]="karachay",
-  ["kat" ]="georgian",
-  ["kaz" ]="kazakh",
-  ["kde" ]="makonde",
-  ["kea" ]="kabuverdianu (crioulo)",
-  ["keb" ]="kebena",
-  ["kek" ]="kekchi",
-  ["kge" ]="khutsuri georgian",
-  ["kha" ]="khakass",
-  ["khk" ]="khanty-kazim",
-  ["khm" ]="khmer",
-  ["khs" ]="khanty-shurishkar",
-  ["kht" ]="khamti shan",
-  ["khv" ]="khanty-vakhi",
-  ["khw" ]="khowar",
-  ["kik" ]="kikuyu (gikuyu)",
-  ["kir" ]="kirghiz (kyrgyz)",
-  ["kis" ]="kisii",
-  ["kiu" ]="kirmanjki",
-  ["kjd" ]="southern kiwai",
-  ["kjp" ]="eastern pwo karen",
-  ["kjz" ]="bumthangkha",
-  ["kkn" ]="kokni",
-  ["klm" ]="kalmyk",
-  ["kmb" ]="kamba",
-  ["kmn" ]="kumaoni",
-  ["kmo" ]="komo",
-  ["kms" ]="komso",
-  ["knr" ]="kanuri",
-  ["kod" ]="kodagu",
-  ["koh" ]="korean old hangul",
-  ["kok" ]="konkani",
-  ["kom" ]="komi",
-  ["kon" ]="kikongo",
-  ["kon0"]="kongo",
-  ["kop" ]="komi-permyak",
-  ["kor" ]="korean",
-  ["kos" ]="kosraean",
-  ["koz" ]="komi-zyrian",
-  ["kpl" ]="kpelle",
-  ["kri" ]="krio",
-  ["krk" ]="karakalpak",
-  ["krl" ]="karelian",
-  ["krm" ]="karaim",
-  ["krn" ]="karen",
-  ["krt" ]="koorete",
-  ["ksh" ]="kashmiri",
-  ["ksh0"]="ripuarian",
-  ["ksi" ]="khasi",
-  ["ksm" ]="kildin sami",
-  ["ksw" ]="s’gaw karen",
-  ["kua" ]="kuanyama",
-  ["kui" ]="kui",
-  ["kul" ]="kulvi",
-  ["kum" ]="kumyk",
-  ["kur" ]="kurdish",
-  ["kuu" ]="kurukh",
-  ["kuy" ]="kuy",
-  ["kyk" ]="koryak",
-  ["kyu" ]="western kayah",
-  ["lad" ]="ladin",
-  ["lah" ]="lahuli",
-  ["lak" ]="lak",
-  ["lam" ]="lambani",
-  ["lao" ]="lao",
-  ["lat" ]="latin",
-  ["laz" ]="laz",
-  ["lcr" ]="l-cree",
-  ["ldk" ]="ladakhi",
-  ["lez" ]="lezgi",
-  ["lij" ]="ligurian",
-  ["lim" ]="limburgish",
-  ["lin" ]="lingala",
-  ["lis" ]="lisu",
-  ["ljp" ]="lampung",
-  ["lki" ]="laki",
-  ["lma" ]="low mari",
-  ["lmb" ]="limbu",
-  ["lmo" ]="lombard",
-  ["lmw" ]="lomwe",
-  ["lom" ]="loma",
-  ["lrc" ]="luri",
-  ["lsb" ]="lower sorbian",
-  ["lsm" ]="lule sami",
-  ["lth" ]="lithuanian",
-  ["ltz" ]="luxembourgish",
-  ["lua" ]="luba-lulua",
-  ["lub" ]="luba-katanga",
-  ["lug" ]="ganda",
-  ["luh" ]="luyia",
-  ["luo" ]="luo",
-  ["lvi" ]="latvian",
-  ["mad" ]="madura",
-  ["mag" ]="magahi",
-  ["mah" ]="marshallese",
-  ["maj" ]="majang",
-  ["mak" ]="makhuwa",
-  ["mal" ]="malayalam reformed",
-  ["mam" ]="mam",
-  ["man" ]="mansi",
-  ["map" ]="mapudungun",
-  ["mar" ]="marathi",
-  ["maw" ]="marwari",
-  ["mbn" ]="mbundu",
-  ["mch" ]="manchu",
-  ["mcr" ]="moose cree",
-  ["mde" ]="mende",
-  ["mdr" ]="mandar",
-  ["men" ]="me'en",
-  ["mer" ]="meru",
-  ["mfa" ]="pattani malay",
-  ["mfe" ]="morisyen",
-  ["min" ]="minangkabau",
-  ["miz" ]="mizo",
-  ["mkd" ]="macedonian",
-  ["mkr" ]="makasar",
-  ["mkw" ]="kituba",
-  ["mle" ]="male",
-  ["mlg" ]="malagasy",
-  ["mln" ]="malinke",
-  ["mly" ]="malay",
-  ["mnd" ]="mandinka",
-  ["mng" ]="mongolian",
-  ["mni" ]="manipuri",
-  ["mnk" ]="maninka",
-  ["mnx" ]="manx",
-  ["moh" ]="mohawk",
-  ["mok" ]="moksha",
-  ["mol" ]="moldavian",
-  ["mon" ]="mon",
-  ["mor" ]="moroccan",
-  ["mos" ]="mossi",
-  ["mri" ]="maori",
-  ["mth" ]="maithili",
-  ["mts" ]="maltese",
-  ["mun" ]="mundari",
-  ["mus" ]="muscogee",
-  ["mwl" ]="mirandese",
-  ["mww" ]="hmong daw",
-  ["myn" ]="mayan",
-  ["mzn" ]="mazanderani",
-  ["nag" ]="naga-assamese",
-  ["nah" ]="nahuatl",
-  ["nan" ]="nanai",
-  ["nap" ]="neapolitan",
-  ["nas" ]="naskapi",
-  ["nau" ]="nauruan",
-  ["nav" ]="navajo",
-  ["ncr" ]="n-cree",
-  ["ndb" ]="ndebele",
-  ["ndc" ]="ndau",
-  ["ndg" ]="ndonga",
-  ["nds" ]="low saxon",
-  ["nep" ]="nepali",
-  ["new" ]="newari",
-  ["nga" ]="ngbaka",
-  ["ngr" ]="nagari",
-  ["nhc" ]="norway house cree",
-  ["nis" ]="nisi",
-  ["niu" ]="niuean",
-  ["nkl" ]="nyankole",
-  ["nko" ]="n'ko",
-  ["nld" ]="dutch",
-  ["noe" ]="nimadi",
-  ["nog" ]="nogai",
-  ["nor" ]="norwegian",
-  ["nov" ]="novial",
-  ["nsm" ]="northern sami",
-  ["nso" ]="sotho, northern",
-  ["nta" ]="northern tai",
-  ["nto" ]="esperanto",
-  ["nym" ]="nyamwezi",
-  ["nyn" ]="norwegian nynorsk",
-  ["oci" ]="occitan",
-  ["ocr" ]="oji-cree",
-  ["ojb" ]="ojibway",
-  ["ori" ]="odia",
-  ["oro" ]="oromo",
-  ["oss" ]="ossetian",
-  ["paa" ]="palestinian aramaic",
-  ["pag" ]="pangasinan",
-  ["pal" ]="pali",
-  ["pam" ]="pampangan",
-  ["pan" ]="punjabi",
-  ["pap" ]="palpa",
-  ["pap0"]="papiamentu",
-  ["pas" ]="pashto",
-  ["pau" ]="palauan",
-  ["pcc" ]="bouyei",
-  ["pcd" ]="picard",
-  ["pdc" ]="pennsylvania german",
-  ["pgr" ]="polytonic greek",
-  ["phk" ]="phake",
-  ["pih" ]="norfolk",
-  ["pil" ]="filipino",
-  ["plg" ]="palaung",
-  ["plk" ]="polish",
-  ["pms" ]="piemontese",
-  ["pnb" ]="western panjabi",
-  ["poh" ]="pocomchi",
-  ["pon" ]="pohnpeian",
-  ["pro" ]="provencal",
-  ["ptg" ]="portuguese",
-  ["pwo" ]="western pwo karen",
-  ["qin" ]="chin",
-  ["quc" ]="k’iche’",
-  ["quh" ]="quechua (bolivia)",
-  ["quz" ]="quechua",
-  ["qvi" ]="quechua (ecuador)",
-  ["qwh" ]="quechua (peru)",
-  ["raj" ]="rajasthani",
-  ["rar" ]="rarotongan",
-  ["rbu" ]="russian buriat",
-  ["rcr" ]="r-cree",
-  ["rej" ]="rejang",
-  ["ria" ]="riang",
-  ["rif" ]="tarifit",
-  ["rit" ]="ritarungo",
-  ["rkw" ]="arakwal",
-  ["rms" ]="romansh",
-  ["rmy" ]="vlax romani",
-  ["rom" ]="romanian",
-  ["roy" ]="romany",
-  ["rsy" ]="rusyn",
-  ["rtm" ]="rotuman",
-  ["rua" ]="kinyarwanda",
-  ["run" ]="rundi",
-  ["rup" ]="aromanian",
-  ["rus" ]="russian",
-  ["sad" ]="sadri",
-  ["san" ]="sanskrit",
-  ["sas" ]="sasak",
-  ["sat" ]="santali",
-  ["say" ]="sayisi",
-  ["scn" ]="sicilian",
-  ["sco" ]="scots",
-  ["sek" ]="sekota",
-  ["sel" ]="selkup",
-  ["sga" ]="old irish",
-  ["sgo" ]="sango",
-  ["sgs" ]="samogitian",
-  ["shi" ]="tachelhit",
-  ["shn" ]="shan",
-  ["sib" ]="sibe",
-  ["sid" ]="sidamo",
-  ["sig" ]="silte gurage",
-  ["sks" ]="skolt sami",
-  ["sky" ]="slovak",
-  ["sla" ]="slavey",
-  ["slv" ]="slovenian",
-  ["sml" ]="somali",
-  ["smo" ]="samoan",
-  ["sna" ]="sena",
-  ["sna0"]="shona",
-  ["snd" ]="sindhi",
-  ["snh" ]="sinhala (sinhalese)",
-  ["snk" ]="soninke",
-  ["sog" ]="sodo gurage",
-  ["sop" ]="songe",
-  ["sot" ]="sotho, southern",
-  ["sqi" ]="albanian",
-  ["srb" ]="serbian",
-  ["srd" ]="sardinian",
-  ["srk" ]="saraiki",
-  ["srr" ]="serer",
-  ["ssl" ]="south slavey",
-  ["ssm" ]="southern sami",
-  ["stq" ]="saterland frisian",
-  ["suk" ]="sukuma",
-  ["sun" ]="sundanese",
-  ["sur" ]="suri",
-  ["sva" ]="svan",
-  ["sve" ]="swedish",
-  ["swa" ]="swadaya aramaic",
-  ["swk" ]="swahili",
-  ["swz" ]="swati",
-  ["sxt" ]="sutu",
-  ["sxu" ]="upper saxon",
-  ["syl" ]="sylheti",
-  ["syr" ]="syriac",
-  ["szl" ]="silesian",
-  ["tab" ]="tabasaran",
-  ["taj" ]="tajiki",
-  ["tam" ]="tamil",
-  ["tat" ]="tatar",
-  ["tcr" ]="th-cree",
-  ["tdd" ]="dehong dai",
-  ["tel" ]="telugu",
-  ["tet" ]="tetum",
-  ["tgl" ]="tagalog",
-  ["tgn" ]="tongan",
-  ["tgr" ]="tigre",
-  ["tgy" ]="tigrinya",
-  ["tha" ]="thai",
-  ["tht" ]="tahitian",
-  ["tib" ]="tibetan",
-  ["tiv" ]="tiv",
-  ["tkm" ]="turkmen",
-  ["tmh" ]="tamashek",
-  ["tmn" ]="temne",
-  ["tna" ]="tswana",
-  ["tne" ]="tundra nenets",
-  ["tng" ]="tonga",
-  ["tod" ]="todo",
-  ["tod0"]="toma",
-  ["tpi" ]="tok pisin",
-  ["trk" ]="turkish",
-  ["tsg" ]="tsonga",
-  ["tsj" ]="tshangla",
-  ["tua" ]="turoyo aramaic",
-  ["tul" ]="tulu",
-  ["tuv" ]="tuvin",
-  ["tvl" ]="tuvalu",
-  ["twi" ]="twi",
-  ["tyz" ]="tày",
-  ["tzm" ]="tamazight",
-  ["tzo" ]="tzotzil",
-  ["udm" ]="udmurt",
-  ["ukr" ]="ukrainian",
-  ["umb" ]="umbundu",
-  ["urd" ]="urdu",
-  ["usb" ]="upper sorbian",
-  ["uyg" ]="uyghur",
-  ["uzb" ]="uzbek",
-  ["vec" ]="venetian",
-  ["ven" ]="venda",
-  ["vit" ]="vietnamese",
-  ["vol" ]="volapük",
-  ["vro" ]="võro",
-  ["wa" ]="wa",
-  ["wag" ]="wagdi",
-  ["war" ]="waray-waray",
-  ["wcr" ]="west-cree",
-  ["wel" ]="welsh",
-  ["wlf" ]="wolof",
-  ["wln" ]="walloon",
-  ["xbd" ]="lü",
-  ["xhs" ]="xhosa",
-  ["xjb" ]="minjangbal",
-  ["xkf" ]="khengkha",
-  ["xog" ]="soga",
-  ["xpe" ]="kpelle (liberia)",
-  ["yak" ]="sakha",
-  ["yao" ]="yao",
-  ["yap" ]="yapese",
-  ["yba" ]="yoruba",
-  ["ycr" ]="y-cree",
-  ["yic" ]="yi classic",
-  ["yim" ]="yi modern",
-  ["zea" ]="zealandic",
-  ["zgh" ]="standard morrocan tamazigh",
-  ["zha" ]="zhuang",
-  ["zhh" ]="chinese, hong kong sar",
-  ["zhp" ]="chinese phonetic",
-  ["zhs" ]="chinese simplified",
-  ["zht" ]="chinese traditional",
-  ["znd" ]="zande",
-  ["zul" ]="zulu",
-  ["zza" ]="zazaki",
-}
-local features=allocate {
-  ["aalt"]="access all alternates",
-  ["abvf"]="above-base forms",
-  ["abvm"]="above-base mark positioning",
-  ["abvs"]="above-base substitutions",
-  ["afrc"]="alternative fractions",
-  ["akhn"]="akhands",
-  ["blwf"]="below-base forms",
-  ["blwm"]="below-base mark positioning",
-  ["blws"]="below-base substitutions",
-  ["c2pc"]="petite capitals from capitals",
-  ["c2sc"]="small capitals from capitals",
-  ["calt"]="contextual alternates",
-  ["case"]="case-sensitive forms",
-  ["ccmp"]="glyph composition/decomposition",
-  ["cfar"]="conjunct form after ro",
-  ["cjct"]="conjunct forms",
-  ["clig"]="contextual ligatures",
-  ["cpct"]="centered cjk punctuation",
-  ["cpsp"]="capital spacing",
-  ["cswh"]="contextual swash",
-  ["curs"]="cursive positioning",
-  ["dflt"]="default processing",
-  ["dist"]="distances",
-  ["dlig"]="discretionary ligatures",
-  ["dnom"]="denominators",
-  ["dtls"]="dotless forms",
-  ["expt"]="expert forms",
-  ["falt"]="final glyph alternates",
-  ["fin2"]="terminal forms #2",
-  ["fin3"]="terminal forms #3",
-  ["fina"]="terminal forms",
-  ["flac"]="flattened accents over capitals",
-  ["frac"]="fractions",
-  ["fwid"]="full width",
-  ["half"]="half forms",
-  ["haln"]="halant forms",
-  ["halt"]="alternate half width",
-  ["hist"]="historical forms",
-  ["hkna"]="horizontal kana alternates",
-  ["hlig"]="historical ligatures",
-  ["hngl"]="hangul",
-  ["hojo"]="hojo kanji forms",
-  ["hwid"]="half width",
-  ["init"]="initial forms",
-  ["isol"]="isolated forms",
-  ["ital"]="italics",
-  ["jalt"]="justification alternatives",
-  ["jp04"]="jis2004 forms",
-  ["jp78"]="jis78 forms",
-  ["jp83"]="jis83 forms",
-  ["jp90"]="jis90 forms",
-  ["kern"]="kerning",
-  ["lfbd"]="left bounds",
-  ["liga"]="standard ligatures",
-  ["ljmo"]="leading jamo forms",
-  ["lnum"]="lining figures",
-  ["locl"]="localized forms",
-  ["ltra"]="left-to-right alternates",
-  ["ltrm"]="left-to-right mirrored forms",
-  ["mark"]="mark positioning",
-  ["med2"]="medial forms #2",
-  ["medi"]="medial forms",
-  ["mgrk"]="mathematical greek",
-  ["mkmk"]="mark to mark positioning",
-  ["mset"]="mark positioning via substitution",
-  ["nalt"]="alternate annotation forms",
-  ["nlck"]="nlc kanji forms",
-  ["nukt"]="nukta forms",
-  ["numr"]="numerators",
-  ["onum"]="old style figures",
-  ["opbd"]="optical bounds",
-  ["ordn"]="ordinals",
-  ["ornm"]="ornaments",
-  ["palt"]="proportional alternate width",
-  ["pcap"]="petite capitals",
-  ["pkna"]="proportional kana",
-  ["pnum"]="proportional figures",
-  ["pref"]="pre-base forms",
-  ["pres"]="pre-base substitutions",
-  ["pstf"]="post-base forms",
-  ["psts"]="post-base substitutions",
-  ["pwid"]="proportional widths",
-  ["qwid"]="quarter widths",
-  ["rand"]="randomize",
-  ["rclt"]="required contextual alternates",
-  ["rkrf"]="rakar forms",
-  ["rlig"]="required ligatures",
-  ["rphf"]="reph form",
-  ["rtbd"]="right bounds",
-  ["rtla"]="right-to-left alternates",
-  ["rtlm"]="right to left mirrored forms",
-  ["rvrn"]="required variation alternates",
-  ["ruby"]="ruby notation forms",
-  ["salt"]="stylistic alternates",
-  ["sinf"]="scientific inferiors",
-  ["size"]="optical size",
-  ["smcp"]="small capitals",
-  ["smpl"]="simplified forms",
-  ["ssty"]="script style",
-  ["stch"]="stretching glyph decomposition",
-  ["subs"]="subscript",
-  ["sups"]="superscript",
-  ["swsh"]="swash",
-  ["titl"]="titling",
-  ["tjmo"]="trailing jamo forms",
-  ["tnam"]="traditional name forms",
-  ["tnum"]="tabular figures",
-  ["trad"]="traditional forms",
-  ["twid"]="third widths",
-  ["unic"]="unicase",
-  ["valt"]="alternate vertical metrics",
-  ["vatu"]="vattu variants",
-  ["vert"]="vertical writing",
-  ["vhal"]="alternate vertical half metrics",
-  ["vjmo"]="vowel jamo forms",
-  ["vkna"]="vertical kana alternates",
-  ["vkrn"]="vertical kerning",
-  ["vpal"]="proportional alternate vertical metrics",
-  ["vrt2"]="vertical rotation",
-  ["zero"]="slashed zero",
-  ["trep"]="traditional tex replacements",
-  ["tlig"]="traditional tex ligatures",
-  ["ss.."]="stylistic set ..",
-  ["cv.."]="character variant ..",
-  ["js.."]="justification ..",
-  ["dv.."]="devanagari ..",
-  ["ml.."]="malayalam ..",
-}
-local baselines=allocate {
-  ["hang"]="hanging baseline",
-  ["icfb"]="ideographic character face bottom edge baseline",
-  ["icft"]="ideographic character face tope edige baseline",
-  ["ideo"]="ideographic em-box bottom edge baseline",
-  ["idtp"]="ideographic em-box top edge baseline",
-  ["math"]="mathematical centered baseline",
-  ["romn"]="roman baseline"
-}
-tables.scripts=scripts
-tables.languages=languages
-tables.features=features
-tables.baselines=baselines
-local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
-local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
-local report_checks=logs.reporter("fonts","checks")
-if otffeatures.features then
-  for k,v in next,otffeatures.features do
-    features[k]=v
-  end
-  otffeatures.features=features
-end
-local function swapped(h)
-  local r={}
-  for k,v in next,h do
-    r[gsub(v,"[^a-z0-9]","")]=k 
-  end
-  return r
-end
-local verbosescripts=allocate(swapped(scripts ))
-local verboselanguages=allocate(swapped(languages))
-local verbosefeatures=allocate(swapped(features ))
-local verbosebaselines=allocate(swapped(baselines))
-local function resolve(t,k)
-  if k then
-    k=gsub(lower(k),"[^a-z0-9]","")
-    local v=rawget(t,k)
-    if v then
-      return v
-    end
-  end
-end
-setmetatableindex(verbosescripts,resolve)
-setmetatableindex(verboselanguages,resolve)
-setmetatableindex(verbosefeatures,resolve)
-setmetatableindex(verbosebaselines,resolve)
-setmetatableindex(scripts,function(t,k)
-  if k then
-    k=lower(k)
-    if k=="dflt" then
-      return k
-    end
-    local v=rawget(t,k)
-    if v then
-      return v
-    end
-    k=gsub(k," ","")
-    v=rawget(t,v)
-    if v then
-      return v
-    elseif acceptscripts then
-      report_checks("registering extra script %a",k)
-      rawset(t,k,k)
-      return k
-    end
-  end
-  return "dflt"
-end)
-setmetatableindex(languages,function(t,k)
-  if k then
-    k=lower(k)
-    if k=="dflt" then
-      return k
-    end
-    local v=rawget(t,k)
-    if v then
-      return v
-    end
-    k=gsub(k," ","")
-    v=rawget(t,v)
-    if v then
-      return v
-    elseif acceptlanguages then
-      report_checks("registering extra language %a",k)
-      rawset(t,k,k)
-      return k
-    end
-  end
-  return "dflt"
-end)
-if setmetatablenewindex then
-  setmetatablenewindex(languages,"ignore")
-  setmetatablenewindex(scripts,"ignore")
-  setmetatablenewindex(baselines,"ignore")
-end
-local function resolve(t,k)
-  if k then
-    k=lower(k)
-    local v=rawget(t,k)
-    if v then
-      return v
-    end
-    k=gsub(k," ","")
-    local v=rawget(t,k)
-    if v then
-      return v
-    end
-    local tag,dd=match(k,"(..)(%d+)")
-    if tag and dd then
-      local v=rawget(t,tag)
-      if v then
-        return v 
-      else
-        local v=rawget(t,tag.."..") 
-        if v then

@@ Diff output truncated at 1234567 characters. @@


More information about the tex-live-commits mailing list