texlive[76107] Build/source/libs: harfbuzz 11.4.2

commits+kakuto at tug.org commits+kakuto at tug.org
Thu Aug 21 09:53:07 CEST 2025


Revision: 76107
          https://tug.org/svn/texlive?view=revision&revision=76107
Author:   kakuto
Date:     2025-08-21 09:53:07 +0200 (Thu, 21 Aug 2025)
Log Message:
-----------
harfbuzz 11.4.2

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-harfrust.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/Cargo.toml
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/shape.rs
    trunk/Build/source/libs/harfbuzz/version.ac

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/README	2025-08-21 07:53:07 UTC (rev 76107)
@@ -28,7 +28,7 @@
   https://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 11.4.1 - checked 14aug25
+harfbuzz 11.4.2 - checked 21aug25
   https://github.com/harfbuzz/harfbuzz/releases/latest
 
 icu 76.1 - checked 27oct24 (requires C++17, e.g., g++13)

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,3 +1,8 @@
+2025-08-21  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-11.4.2.
+	* version.ac: Adjusted.
+
 2025-08-14  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-11.4.1.

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,3 +1,8 @@
+2025-08-21  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-11.4.2 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/11.4.2/
+
 2025-08-14  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-11.4.1 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-11.4.1/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/11.4.1/
+Changes applied to the harfbuzz-11.4.2/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/11.4.2/
 
 Removed:
 	.clang-format

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/configure	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 11.4.1.
+# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 11.4.2.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -604,8 +604,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='11.4.1'
-PACKAGE_STRING='harfbuzz (TeX Live) 11.4.1'
+PACKAGE_VERSION='11.4.2'
+PACKAGE_STRING='harfbuzz (TeX Live) 11.4.2'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1341,7 +1341,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures harfbuzz (TeX Live) 11.4.1 to adapt to many kinds of systems.
+'configure' configures harfbuzz (TeX Live) 11.4.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1413,7 +1413,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 11.4.1:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 11.4.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1518,7 +1518,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 11.4.1
+harfbuzz (TeX Live) configure 11.4.2
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -2075,7 +2075,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 11.4.1, which was
+It was created by harfbuzz (TeX Live) $as_me 11.4.2, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -5259,7 +5259,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='11.4.1'
+ VERSION='11.4.2'
 
 
 # Some tools Automake needs.
@@ -5573,8 +5573,8 @@
 
 HB_VERSION_MAJOR=11
 HB_VERSION_MINOR=4
-HB_VERSION_MICRO=1
-HB_VERSION=11.4.1
+HB_VERSION_MICRO=2
+HB_VERSION=11.4.2
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -9426,7 +9426,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 11.4.1, which was
+This file was extended by harfbuzz (TeX Live) $as_me 11.4.2, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9494,7 +9494,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 11.4.1
+harfbuzz (TeX Live) config.status 11.4.2
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,3 +1,19 @@
+# Building HarfBuzz
+
+HarfBuzz primarily uses the _meson_ build system. A community-maintained
+_CMake_ build system is also available. Finally, you can build HarfBuzz
+without a build system by compiling the amalgamated source file.
+
+## Installing dependencies
+
+First, we need to install desired dependencies.  None of these are strictly
+required to build the library, but when they are present, you can build the
+library with additional _integration_ features, such as _FreeType_ integration.
+
+The command-line tools (`hb-view`, `hb-shape`, `hb-info`, `hb-subset`) require
+_GLib_, while `hb-view` also requires _Cairo_.  Most of the test suite requires
+_GLib_ to run.
+
 On Linux, install the development packages for FreeType, Cairo, and GLib. For
 example, on Ubuntu / Debian, you would do:
 
@@ -15,6 +31,8 @@
 
     brew install pkg-config ragel gtk-doc freetype glib cairo meson
 
+## Building HarfBuzz with meson
+
 Then use meson to build the project and run the tests, like:
 
     meson build && ninja -Cbuild && meson test -Cbuild
@@ -27,6 +45,16 @@
 
 Our CI configurations are also a good source of learning how to build HarfBuzz.
 
+## Building without a build system
+
 There is also amalgamated source provided with HarfBuzz which reduces whole process
-of building HarfBuzz to `g++ src/harfbuzz.cc -fno-exceptions` but there is
-no guarantee provided with buildability and reliability of features you get.
+of building HarfBuzz to `c++ -c src/harfbuzz.cc` but there is no guarantee provided
+with buildability and reliability of features you get.  This can be useful when
+embedding HarfBuzz in your project.
+
+For example, the `hb-shape` tool can be built simply as:
+
+    $ c++ -O2 src/harfbuzz.cc util/hb-shape.cc  -o hb-shape -I src -DHB_NO_FEATURES_H `pkg-config --cflags --libs glib-2.0`
+
+See `CONFIG.md` for ideas on how to shrink the feature set of your custom built
+HarfBuzz library.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2025-08-21 07:53:07 UTC (rev 76107)
@@ -801,9 +801,6 @@
 
 ## Additional harfbuzz build artifacts
 if (HB_BUILD_UTILS)
-  add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"")
-  add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"")
-
   if (HB_HAVE_CAIRO)
     add_executable(hb-view
         ${PROJECT_SOURCE_DIR}/util/ansi-print.hh

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,3 +1,15 @@
+Overview of changes leading to 11.4.2
+Thursday, August 21, 2025
+====================================
+- Various performance and memory usage improvements.
+- The `hb-shape` command line tool can now be built with the amalgamated
+  `harfbuzz.cc` source.
+- Fix regression in handling version 2 of `avar` table.
+- Increase various buffer length limits for better handling of fonts that
+  generate huge number of glyphs per codepoint (e.g. Noto Sans Duployan)
+- Improvements to the harfrust shaper for more accurate testing.
+
+
 Overview of changes leading to 11.4.1
 Wednesday, August 13, 2025
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md	2025-08-21 07:53:07 UTC (rev 76107)
@@ -13,7 +13,7 @@
 [Apple Advanced Typography][2]. HarfBuzz is used in Android, Chrome,
 ChromeOS, Firefox, GNOME, GTK+, KDE, Qt, LibreOffice, OpenJDK, XeTeX,
 PlayStation, Microsoft Edge, Adobe Photoshop, Illustrator, InDesign,
-Godot Engine, Unreal Engine, QuarkXPress, Figma, Canva, and other places.
+Godot Engine, Unreal Engine, QuarkXPress, Figma, and other places.
 
 [![xkcd-derived image](xkcd.png)](https://xkcd.com/2347/)
 
@@ -78,6 +78,8 @@
 More presentations and papers are available on [behdad][11]'s website.
 In particular, the following _studies_ are relevant to HarfBuzz development:
 
+- 2025 – [AAT layout caches][24]
+- 2025 – [OpenType Layout lookup caches][23]
 - 2025 – [Introducing HarfRust][22]
 - 2025 – [Subsetting][21]
 - 2025 – [Caching][12]
@@ -136,3 +138,5 @@
 [20]: https://behdad.org/doc/harfbuzz10years-slides.pdf
 [21]: https://docs.google.com/document/d/1_vZrt97OorJ0jA1YzJ29LRcGr3YGrNJANdOABjVZGEs/preview
 [22]: https://docs.google.com/document/d/1aH_waagdEM5UhslQxCeFEb82ECBhPlZjy5_MwLNLBYo/preview
+[23]: https://docs.google.com/document/d/1hRd5oYQJLrt0JuwWhEJWi7wh_9rbaIJkX6IR9DW7rZQ/preview
+[24]: https://docs.google.com/document/d/1a3K6fHjsiWW36vSzwJwCwEBOgznunKs80PSpBbpfHiA/preview

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1,6 +1,6 @@
 project('harfbuzz', ['c', 'cpp'],
   meson_version: '>= 0.60.0',
-  version: '11.4.1',
+  version: '11.4.2',
   default_options: [
     'cpp_eh=none',          # Just to support msvc, we are passing -fno-exceptions also anyway
     # 'cpp_rtti=false',     # Do NOT enable, wraps inherit it and ICU needs RTTI
@@ -375,9 +375,6 @@
   endif
 endif
 
-conf.set_quoted('PACKAGE_NAME', 'HarfBuzz')
-conf.set_quoted('PACKAGE_VERSION', meson.project_version())
-
 foreach check : check_headers
   name = check[0]
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -103,29 +103,18 @@
 
   const Coverage &get_coverage () const { return this+coverage; }
 
-  static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
+  struct external_cache_t
   {
-    switch (op)
+    hb_ot_layout_mapping_cache_t coverage;
+  };
+  void *external_cache_create () const
+  {
+    external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t));
+    if (likely (cache))
     {
-      case hb_ot_subtable_cache_op_t::CREATE:
-      {
-	hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) hb_malloc (sizeof (hb_ot_layout_mapping_cache_t));
-	if (likely (cache))
-	  cache->clear ();
-	return cache;
-      }
-      case hb_ot_subtable_cache_op_t::ENTER:
-	return nullptr;
-      case hb_ot_subtable_cache_op_t::LEAVE:
-	return nullptr;
-      case hb_ot_subtable_cache_op_t::DESTROY:
-      {
-	hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) p;
-	hb_free (cache);
-	return nullptr;
-      }
+      cache->coverage.clear ();
     }
-    return nullptr;
+    return cache;
   }
 
   bool apply (hb_ot_apply_context_t *c, void *external_cache) const
@@ -135,8 +124,8 @@
     hb_buffer_t *buffer = c->buffer;
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-    hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) external_cache;
-    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint, cache);
+    external_cache_t *cache = (external_cache_t *) external_cache;
+    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint, cache ? &cache->coverage : nullptr);
 #else
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -123,40 +123,22 @@
 
   const Coverage &get_coverage () const { return this+coverage; }
 
-  struct pair_pos_cache_t
+  struct external_cache_t
   {
     hb_ot_layout_mapping_cache_t coverage;
     hb_ot_layout_mapping_cache_t first;
     hb_ot_layout_mapping_cache_t second;
   };
-
-  static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
+  void *external_cache_create () const
   {
-    switch (op)
+    external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t));
+    if (likely (cache))
     {
-      case hb_ot_subtable_cache_op_t::CREATE:
-      {
-	pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t));
-	if (likely (cache))
-	{
-	  cache->coverage.clear ();
-	  cache->first.clear ();
-	  cache->second.clear ();
-	}
-	return cache;
-      }
-      case hb_ot_subtable_cache_op_t::ENTER:
-	return nullptr;
-      case hb_ot_subtable_cache_op_t::LEAVE:
-	return nullptr;
-      case hb_ot_subtable_cache_op_t::DESTROY:
-	{
-	  pair_pos_cache_t *cache = (pair_pos_cache_t *) p;
-	  hb_free (cache);
-	  return nullptr;
-	}
+      cache->coverage.clear ();
+      cache->first.clear ();
+      cache->second.clear ();
     }
-    return nullptr;
+    return cache;
   }
 
   bool apply (hb_ot_apply_context_t *c, void *external_cache) const
@@ -166,7 +148,7 @@
     hb_buffer_t *buffer = c->buffer;
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-    pair_pos_cache_t *cache = (pair_pos_cache_t *) external_cache;
+    external_cache_t *cache = (external_cache_t *) external_cache;
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint, cache ? &cache->coverage : nullptr);
 #else
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -44,6 +44,12 @@
     c->output->add (ligGlyph);
   }
 
+  template <typename set_t>
+  void collect_second (set_t &s) const
+  {
+    s.add (component[1]); // This adds codepoint 0 if component array is empty.
+  }
+
   bool would_apply (hb_would_apply_context_t *c) const
   {
     if (c->len != component.lenP1)
@@ -91,15 +97,6 @@
     unsigned int total_component_count = 0;
 
     if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return false;
-    unsigned match_positions_stack[4];
-    unsigned *match_positions = match_positions_stack;
-    if (unlikely (count > ARRAY_LENGTH (match_positions_stack)))
-    {
-      match_positions = (unsigned *) hb_malloc (hb_max (count, 1u) * sizeof (unsigned));
-      if (unlikely (!match_positions))
-	return_trace (false);
-    }
-
     unsigned int match_end = 0;
 
     if (likely (!match_input (c, count,
@@ -107,12 +104,9 @@
                               match_glyph,
                               nullptr,
                               &match_end,
-                              match_positions,
                               &total_component_count)))
     {
       c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
-      if (match_positions != match_positions_stack)
-        hb_free (match_positions);
       return_trace (false);
     }
 
@@ -129,10 +123,10 @@
       match_end += delta;
       for (unsigned i = 0; i < count; i++)
       {
-	match_positions[i] += delta;
+	c->match_positions[i] += delta;
 	if (i)
 	  *p++ = ',';
-	snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]);
+	snprintf (p, sizeof(buf) - (p - buf), "%u", c->match_positions[i]);
 	p += strlen(p);
       }
 
@@ -143,7 +137,6 @@
 
     ligate_input (c,
                   count,
-                  match_positions,
                   match_end,
                   ligGlyph,
                   total_component_count);
@@ -156,8 +149,6 @@
 			  pos);
     }
 
-    if (match_positions != match_positions_stack)
-      hb_free (match_positions);
     return_trace (true);
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -62,6 +62,15 @@
     ;
   }
 
+  template <typename set_t>
+  void collect_seconds (set_t &s) const
+  {
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([&s] (const Ligature<Types> &_) { _.collect_second (s); })
+    ;
+  }
+
   bool would_apply (hb_would_apply_context_t *c) const
   {
     return
@@ -72,7 +81,7 @@
     ;
   }
 
-  bool apply (hb_ot_apply_context_t *c) const
+  bool apply (hb_ot_apply_context_t *c, const hb_set_digest_t *seconds = nullptr) const
   {
     TRACE_APPLY (this);
 
@@ -79,7 +88,7 @@
     unsigned int num_ligs = ligature.len;
 
 #ifndef HB_NO_OT_RULESETS_FAST_PATH
-    if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4)
+    if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 1)
 #endif
     {
     slow:
@@ -91,7 +100,7 @@
       return_trace (false);
     }
 
-    /* This version is optimized for speed by matching the first component
+    /* This version is optimized for speed by matching the second component
      * of the ligature here, instead of calling into the ligation code.
      *
      * This is replicated in ChainRuleSet and RuleSet. */
@@ -101,11 +110,11 @@
     skippy_iter.set_match_func (match_always, nullptr);
     skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
     unsigned unsafe_to;
-    hb_codepoint_t first = (unsigned) -1;
+    hb_codepoint_t second = (unsigned) -1;
     bool matched = skippy_iter.next (&unsafe_to);
     if (likely (matched))
     {
-      first = c->buffer->info[skippy_iter.idx].codepoint;
+      second = c->buffer->info[skippy_iter.idx].codepoint;
       unsafe_to = skippy_iter.idx + 1;
 
       if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
@@ -118,13 +127,14 @@
     else
       goto slow;
 
+    if (seconds && !seconds->may_have (second))
+      return_trace (false);
     bool unsafe_to_concat = false;
-
     for (unsigned int i = 0; i < num_ligs; i++)
     {
       const auto &lig = this+ligature.arrayZ[i];
       if (unlikely (lig.component.lenP1 <= 1) ||
-	  lig.component.arrayZ[0] == first)
+	  lig.component.arrayZ[0] == second)
       {
 	if (lig.apply (c))
 	{

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -78,29 +78,25 @@
     return lig_set.would_apply (c);
   }
 
-  static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
+  struct external_cache_t
   {
-    switch (op)
+    hb_ot_layout_mapping_cache_t coverage;
+    hb_set_digest_t seconds;
+  };
+  void *external_cache_create () const
+  {
+    external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t));
+    if (likely (cache))
     {
-      case hb_ot_subtable_cache_op_t::CREATE:
-      {
-	hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) hb_malloc (sizeof (hb_ot_layout_mapping_cache_t));
-	if (likely (cache))
-	  cache->clear ();
-	return cache;
-      }
-      case hb_ot_subtable_cache_op_t::ENTER:
-	return nullptr;
-      case hb_ot_subtable_cache_op_t::LEAVE:
-	return nullptr;
-      case hb_ot_subtable_cache_op_t::DESTROY:
-      {
-	hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) p;
-	hb_free (cache);
-	return nullptr;
-      }
+      cache->coverage.clear ();
+
+      cache->seconds.init ();
+      + hb_iter (ligatureSet)
+      | hb_map (hb_add (this))
+      | hb_apply ([cache] (const LigatureSet<Types> &_) { _.collect_seconds (cache->seconds); })
+      ;
     }
-    return nullptr;
+    return cache;
   }
 
   bool apply (hb_ot_apply_context_t *c, void *external_cache) const
@@ -109,15 +105,17 @@
     hb_buffer_t *buffer = c->buffer;
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-    hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) external_cache;
-    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint, cache);
+    external_cache_t *cache = (external_cache_t *) external_cache;
+    const hb_set_digest_t *seconds = cache ? &cache->seconds : nullptr;
+    unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint, cache ? &cache->coverage : nullptr);
 #else
+    const hb_set_digest_t *seconds = nullptr;
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
 #endif
     if (index == NOT_COVERED) return_trace (false);
 
     const auto &lig_set = this+ligatureSet[index];
-    return_trace (lig_set.apply (c));
+    return_trace (lig_set.apply (c, seconds));
   }
 
   bool serialize (hb_serialize_context_t *c,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2025-08-21 07:53:07 UTC (rev 76107)
@@ -165,7 +165,7 @@
 SLOPPY = "SLOPPY"
 
 compression_level = {
-    DEFAULT: 5,
+    DEFAULT: 3,
     COMPACT: 9,
     SLOPPY: 9,
 }
@@ -193,7 +193,7 @@
     print("pub(crate) mod ucd {")
     print()
     print("#![allow(unused_parens)]")
-    print("#![allow(clippy::unnecessary_cast)]")
+    print("#![allow(clippy::unnecessary_cast, clippy::unreadable_literal, clippy::double_parens)]")
     print()
     print("use crate::hb::algs::{HB_CODEPOINT_ENCODE3, HB_CODEPOINT_ENCODE3_11_7_14};")
     print("use crate::hb::common::script;")

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2025-08-21 07:53:07 UTC (rev 76107)
@@ -15,9 +15,21 @@
 * ms-use/IndicPositionalCategory-Additional.txt
 """
 
+import packTab
+
+import sys
 import logging
+
 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
 
+if len(sys.argv) > 1 and sys.argv[1] == "--rust":
+    del sys.argv[1]
+    logging.info("Generating Rust code...")
+    language = "rust"
+else:
+    logging.info("Generating C code...")
+    language = "c"
+language = packTab.languages[language]
 
 import sys
 
@@ -425,105 +437,100 @@
 		print (" * %s" % (l.strip()))
 print (" */")
 print ()
-print ("#ifndef HB_OT_SHAPER_USE_TABLE_HH")
-print ("#define HB_OT_SHAPER_USE_TABLE_HH")
-print ()
-print ('#include "hb.hh"')
-print ()
-print ('#include "hb-ot-shaper-use-machine.hh"')
-print ()
+if language.name == "c":
+    print ("#ifndef HB_OT_SHAPER_USE_TABLE_HH")
+    print ("#define HB_OT_SHAPER_USE_TABLE_HH")
+    print ()
+    print ('#include "hb.hh"')
+    print ()
+    print ('#include "hb-ot-shaper-use-machine.hh"')
+    print ()
 
-total = 0
-used = 0
-last_block = None
-def print_block (block, start, end, use_data):
-	global total, used, last_block
-	if block and block != last_block:
-		print ()
-		print ()
-		print ("  /* %s */" % block)
-		if start % 16:
-			print (' ' * (20 + (start % 16 * 6)), end='')
-	num = 0
-	assert start % 8 == 0
-	assert (end+1) % 8 == 0
-	for u in range (start, end+1):
-		if u % 16 == 0:
-			print ()
-			print ("  /* %04X */" % u, end='')
-		if u in use_data:
-			num += 1
-		d = use_data.get (u)
-		if d is not None:
-			d = d[0]
-		elif u in unicode_data[4]:
-			d = 'O'
-		else:
-			d = 'WJ'
-		print ("%6s," % d, end='')
+    print ('#pragma GCC diagnostic push')
+    print ('#pragma GCC diagnostic ignored "-Wunused-macros"')
+    for k,v in sorted(use_mapping.items()):
+        if k in use_positions and use_positions[k]: continue
+        print ("#define %s	USE(%s)	/* %s */" % (k, k, v.__name__[3:]))
+    for k,v in sorted(use_positions.items()):
+        if not v: continue
+        for suf in v.keys():
+            tag = k + suf
+            print ("#define %s	USE(%s)" % (tag, tag))
+    print ('#pragma GCC diagnostic pop')
+    print ("")
 
-	total += end - start + 1
-	used += num
-	if block:
-		last_block = block
+elif language.name == "rust":
+    print()
+    print("#![allow(unused_parens)]")
+    print("#![allow(clippy::unnecessary_cast, clippy::unreadable_literal, clippy::double_parens)]")
+    print()
+    print("use super::ot_shaper_use::category::*;")
+    print()
+else:
+    assert False, "Unknown language: %s" % language.name
 
 uu = sorted (use_data.keys ())
 
-last = -100000
-num = 0
-offset = 0
-starts = []
-ends = []
-print ('#pragma GCC diagnostic push')
-print ('#pragma GCC diagnostic ignored "-Wunused-macros"')
-for k,v in sorted(use_mapping.items()):
-	if k in use_positions and use_positions[k]: continue
-	print ("#define %s	USE(%s)	/* %s */" % (k, k, v.__name__[3:]))
-for k,v in sorted(use_positions.items()):
-	if not v: continue
-	for suf in v.keys():
-		tag = k + suf
-		print ("#define %s	USE(%s)" % (tag, tag))
-print ('#pragma GCC diagnostic pop')
-print ("")
+data = {u:v[0] for u,v in use_data.items()}
 
+if language.name == "c":
+    private = True
+elif language.name == "rust":
+    private = False
+    language.public_function_linkage = "pub(crate)"
+else:
+    assert False, "Unknown language: %s" % language.name
 
-import packTab
-data = {u:v[0] for u,v in use_data.items()}
 
-DEFAULT = 5
-COMPACT = 9
-for compression in (DEFAULT, COMPACT):
+DEFAULT = "DEFAULT"
+COMPACT = "COMPACT"
 
-    logging.info('  Compression=%d:' % compression)
+compression_level = {
+    DEFAULT: 5,
+    COMPACT: 9,
+}
+
+modes = {}
+if language.name == "c":
+    modes[DEFAULT] = "#ifndef HB_OPTIMIZE_SIZE"
+    modes[COMPACT] = "#else"
+    modes[None] = "#endif"
+else:
+    modes[DEFAULT] = ""
+
+for step, text in modes.items():
     print()
-    if compression == DEFAULT:
-        print('#ifndef HB_OPTIMIZE_SIZE')
-    elif compression == COMPACT:
-        print('#else')
-    else:
-        assert False
-    print()
+    if text:
+        print(text)
+        print()
+    if step is None:
+        continue
 
+    compression = compression_level[step]
+    logging.info("  Compression=%d:" % compression)
+
     code = packTab.Code('hb_use')
     sol = packTab.pack_table(data, compression=compression, default='O')
     logging.info('      FullCost=%d' % (sol.fullCost))
-    sol.genCode(code, f'get_category')
-    code.print_c()
+    sol.genCode(code, f'get_category', language=language, private=private)
+    code.print_code(language=language, private=private)
     print ()
 
-print('#endif')
-
-print ()
-for k in sorted(use_mapping.keys()):
-	if k in use_positions and use_positions[k]: continue
-	print ("#undef %s" % k)
-for k,v in sorted(use_positions.items()):
-	if not v: continue
-	for suf in v.keys():
-		tag = k + suf
-		print ("#undef %s" % tag)
-print ()
-print ()
-print ("#endif /* HB_OT_SHAPER_USE_TABLE_HH */")
+if language.name == "c":
+    print ()
+    for k in sorted(use_mapping.keys()):
+        if k in use_positions and use_positions[k]: continue
+        print ("#undef %s" % k)
+    for k,v in sorted(use_positions.items()):
+        if not v: continue
+        for suf in v.keys():
+            tag = k + suf
+            print ("#undef %s" % tag)
+    print ()
+    print ()
+    print ("#endif /* HB_OT_SHAPER_USE_TABLE_HH */")
+elif language.name == "rust":
+    pass
+else:
+    assert False, "Unknown language: %s" % language.name
 print ("/* == End of generated table == */")

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -47,8 +47,7 @@
 
 struct ankr;
 
-using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>;
-static_assert (sizeof (hb_aat_class_cache_t) == 256, "");
+using hb_aat_class_cache_t = hb_ot_layout_mapping_cache_t;
 
 struct hb_aat_scratch_t
 {
@@ -1082,6 +1081,8 @@
     for (unsigned i = 0; i < subtable_count; i++)
     {
       uint32_t offset = (uint32_t) subtableOffsets[i];
+      // A font file called SFNSDisplay.ttf has value 0xFFFFFFFF in the offsets.
+      // Just ignore it.
       if (offset == 0 || offset == 0xFFFFFFFF)
         continue;
       if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes)))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2025-08-21 07:53:07 UTC (rev 76107)
@@ -163,7 +163,7 @@
 
     hb_buffer_append (fragment, text_buffer, text_start, text_end);
     if (!hb_shape_full (font, fragment, features, num_features, shapers) ||
-	fragment->successful || fragment->shaping_failed)
+	fragment->successful)
     {
       hb_buffer_destroy (reconstruction);
       hb_buffer_destroy (fragment);
@@ -313,11 +313,11 @@
    * Shape the two fragment streams.
    */
   if (!hb_shape_full (font, fragments[0], features, num_features, shapers) ||
-      !fragments[0]->successful || fragments[0]->shaping_failed)
+      !fragments[0]->successful)
     goto out;
 
   if (!hb_shape_full (font, fragments[1], features, num_features, shapers) ||
-      !fragments[1]->successful || fragments[1]->shaping_failed)
+      !fragments[1]->successful)
     goto out;
 
   if (!forward)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2025-08-21 07:53:07 UTC (rev 76107)
@@ -158,8 +158,6 @@
 bool
 hb_buffer_t::enlarge (unsigned int size)
 {
-  if (unlikely (!successful))
-    return false;
   if (unlikely (size > max_len))
   {
     successful = false;
@@ -166,6 +164,9 @@
     return false;
   }
 
+  if (unlikely (!successful))
+    return false;
+
   unsigned int new_allocated = allocated;
   hb_glyph_position_t *new_pos = nullptr;
   hb_glyph_info_t *new_info = nullptr;
@@ -297,7 +298,6 @@
   props = default_props;
 
   successful = true;
-  shaping_failed = false;
   have_output = false;
   have_positions = false;
 
@@ -320,7 +320,6 @@
 {
   deallocate_var_all ();
   serial = 0;
-  shaping_failed = false;
   scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
   unsigned mul;
   if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul)))
@@ -339,7 +338,6 @@
   max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
   deallocate_var_all ();
   serial = 0;
-  // Intentionally not reseting shaping_failed, such that it can be inspected.
 }
 
 
@@ -726,7 +724,6 @@
   HB_SEGMENT_PROPERTIES_DEFAULT,
 
   false, /* successful */
-  true, /* shaping_failed */
   false, /* have_output */
   true  /* have_positions */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -90,7 +90,6 @@
   hb_segment_properties_t props; /* Script, language, direction */
 
   bool successful; /* Allocations successful */
-  bool shaping_failed; /* Shaping failure */
   bool have_output; /* Whether we have an output buffer going on */
   bool have_positions; /* Whether we have positions */
 
@@ -346,7 +345,7 @@
     {
       if (out_info != info || out_len != idx)
       {
-	if (unlikely (!make_room_for (1, 1))) return false;
+	if (unlikely (!ensure (out_len + 1))) return false;
 	out_info[out_len] = info[idx];
       }
       out_len++;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-harfrust.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-harfrust.cc	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-harfrust.cc	2025-08-21 07:53:07 UTC (rev 76107)
@@ -92,7 +92,6 @@
 
 extern "C" void *
 _hb_harfrust_shape_plan_create_rs (const void *font_data,
-				   const void *face_data,
 				   hb_script_t script,
 				   hb_language_t language,
 				   hb_direction_t direction);
@@ -154,7 +153,7 @@
     hr_shape_plan = hb_shape_plan_get_user_data (shape_plan, &hb_object_key);
     if (unlikely (!hr_shape_plan))
     {
-      hr_shape_plan = _hb_harfrust_shape_plan_create_rs (font_data, face_data,
+      hr_shape_plan = _hb_harfrust_shape_plan_create_rs (font_data,
 							 shape_plan->key.props.script,
 							 shape_plan->key.props.language,
 							 shape_plan->key.props.direction);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -29,10 +29,10 @@
 
 
 #ifndef HB_BUFFER_MAX_LEN_FACTOR
-#define HB_BUFFER_MAX_LEN_FACTOR 64
+#define HB_BUFFER_MAX_LEN_FACTOR 256
 #endif
 #ifndef HB_BUFFER_MAX_LEN_MIN
-#define HB_BUFFER_MAX_LEN_MIN 16384
+#define HB_BUFFER_MAX_LEN_MIN 65536
 #endif
 #ifndef HB_BUFFER_MAX_LEN_DEFAULT
 #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
@@ -39,10 +39,10 @@
 #endif
 
 #ifndef HB_BUFFER_MAX_OPS_FACTOR
-#define HB_BUFFER_MAX_OPS_FACTOR 1024
+#define HB_BUFFER_MAX_OPS_FACTOR 4096
 #endif
 #ifndef HB_BUFFER_MAX_OPS_MIN
-#define HB_BUFFER_MAX_OPS_MIN 16384
+#define HB_BUFFER_MAX_OPS_MIN 65536
 #endif
 #ifndef HB_BUFFER_MAX_OPS_DEFAULT
 #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -63,12 +63,20 @@
   c->set_lookup_index (lookup_index);
   c->set_lookup_props (l.get_props ());
 
+  uint32_t stack_match_positions[8];
+  hb_vector_t<uint32_t> saved_match_positions;
+  saved_match_positions.set_storage (stack_match_positions);
+  hb_swap (c->match_positions, saved_match_positions);
+
   bool ret = false;
   auto *accel = gpos->get_accel (lookup_index);
-  ret = accel && accel->apply (c, l.get_subtable_count (), false);
+  ret = accel && accel->apply (c, false);
 
   c->set_lookup_index (saved_lookup_index);
   c->set_lookup_props (saved_lookup_props);
+
+  hb_swap (c->match_positions, saved_match_positions);
+
   return ret;
 }
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -76,12 +76,20 @@
   c->set_lookup_index (lookup_index);
   c->set_lookup_props (l.get_props ());
 
+  uint32_t stack_match_positions[8];
+  hb_vector_t<uint32_t> saved_match_positions;
+  saved_match_positions.set_storage (stack_match_positions);
+  hb_swap (c->match_positions, saved_match_positions);
+
   bool ret = false;
   auto *accel = gsub->get_accel (lookup_index);
-  ret = accel && accel->apply (c, l.get_subtable_count (), false);
+  ret = accel && accel->apply (c, false);
 
   c->set_lookup_index (saved_lookup_index);
   c->set_lookup_props (saved_lookup_props);
+
+  hb_swap (c->match_positions, saved_match_positions);
+
   return ret;
 }
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -682,12 +682,20 @@
   bool stop_sublookup_iteration (return_t r) const { return r; }
   return_t recurse (unsigned int sub_lookup_index)
   {
-    if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0))
+    assert (recurse_func);
+    if (unlikely (nesting_level_left == 0))
     {
-      buffer->shaping_failed = true;
+      buffer->successful = false;
       return default_return_value ();
     }
 
+    buffer->max_ops--;
+    if (unlikely (buffer->max_ops < 0))
+    {
+      buffer->successful = false;
+      return default_return_value ();
+    }
+
     nesting_level_left--;
     bool ret = recurse_func (this, sub_lookup_index);
     nesting_level_left++;
@@ -726,6 +734,9 @@
   signed last_base = -1; // GPOS uses
   unsigned last_base_until = 0; // GPOS uses
 
+  hb_vector_t<uint32_t> match_positions;
+  uint32_t stack_match_positions[8];
+
   hb_ot_apply_context_t (unsigned int table_index_,
 			 hb_font_t *font_,
 			 hb_buffer_t *buffer_,
@@ -755,6 +766,7 @@
   {
     init_iters ();
     buffer->collect_codepoints (digest);
+    match_positions.set_storage (stack_match_positions);
   }
 
   void init_iters ()
@@ -866,8 +878,8 @@
       _hb_glyph_info_set_glyph_props (&buffer->cur(), props);
 
     if (cached_props != (unsigned) -1)
-      _hb_glyph_info_set_match (&buffer->cur(),
-				check_glyph_property (&buffer->cur(), cached_props, false));
+      _hb_glyph_info_set_matches (&buffer->cur(),
+				  check_glyph_property (&buffer->cur(), cached_props, false));
   }
 
   void replace_glyph (hb_codepoint_t glyph_index)
@@ -896,10 +908,8 @@
 
 enum class hb_ot_subtable_cache_op_t
 {
-  CREATE,
   ENTER,
   LEAVE,
-  DESTROY,
 };
 
 struct hb_accelerate_subtables_context_t :
@@ -931,23 +941,23 @@
   }
 
   template <typename T>
-  static inline auto cache_func_ (void *p,
+  static inline auto cache_func_ (hb_ot_apply_context_t *c,
 				  hb_ot_subtable_cache_op_t op,
-				  hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) )
+				  hb_priority<1>) HB_RETURN (bool, T::cache_func (c, op) )
   template <typename T=void>
-  static inline void * cache_func_ (void *p,
-				    hb_ot_subtable_cache_op_t op HB_UNUSED,
-				    hb_priority<0>) { return nullptr; }
+  static inline bool cache_func_ (hb_ot_apply_context_t *c,
+				  hb_ot_subtable_cache_op_t op HB_UNUSED,
+				  hb_priority<0>) { return false; }
   template <typename Type>
-  static inline void * cache_func_to (void *p,
-				      hb_ot_subtable_cache_op_t op)
+  static inline bool cache_func_to (hb_ot_apply_context_t *c,
+				    hb_ot_subtable_cache_op_t op)
   {
-    return cache_func_<Type> (p, op, hb_prioritize);
+    return cache_func_<Type> (c, op, hb_prioritize);
   }
 #endif
 
   typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, void *external_cache);
-  typedef void * (*hb_cache_func_t) (void *p, hb_ot_subtable_cache_op_t op);
+  typedef bool (*hb_cache_func_t) (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op);
 
   struct hb_applicable_t
   {
@@ -960,6 +970,7 @@
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
 	       , hb_apply_func_t apply_cached_func_
 	       , hb_cache_func_t cache_func_
+	       , void *external_cache_
 #endif
 		)
     {
@@ -968,7 +979,7 @@
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
       apply_cached_func = apply_cached_func_;
       cache_func = cache_func_;
-      external_cache = cache_create ();
+      external_cache = external_cache_;
 #endif
       digest.init ();
       obj_.get_coverage ().collect_coverage (&digest);
@@ -988,13 +999,10 @@
     {
       return digest.may_have (c->buffer->cur().codepoint) &&  apply_cached_func (obj, c, external_cache);
     }
-    void *cache_create () const
-    {
-	return cache_func (nullptr, hb_ot_subtable_cache_op_t::CREATE);
-    }
+
     bool cache_enter (hb_ot_apply_context_t *c) const
     {
-      return (bool) cache_func (c, hb_ot_subtable_cache_op_t::ENTER);
+      return cache_func (c, hb_ot_subtable_cache_op_t::ENTER);
     }
     void cache_leave (hb_ot_apply_context_t *c) const
     {
@@ -1018,6 +1026,11 @@
   auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () )
   template <typename T>
   auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u )
+
+  template <typename T>
+  auto external_cache_create (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.external_cache_create () )
+  template <typename T>
+  auto external_cache_create (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( nullptr )
 #endif
 
   /* Dispatch interface. */
@@ -1024,6 +1037,12 @@
   template <typename T>
   return_t dispatch (const T &obj)
   {
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
+    void *external_cache = nullptr;
+    if (i < 8)
+      external_cache = external_cache_create (obj, hb_prioritize);
+#endif
+
     hb_applicable_t *entry = &array[i++];
 
     entry->init (obj,
@@ -1031,6 +1050,7 @@
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
 		 , apply_cached_to<T>
 		 , cache_func_to<T>
+		 , external_cache
 #endif
 		 );
 
@@ -1294,7 +1314,6 @@
 			 match_func_t match_func,
 			 const void *match_data,
 			 unsigned int *end_position,
-			 unsigned int *match_positions,
 			 unsigned int *p_total_component_count = nullptr)
 {
   TRACE_APPLY (nullptr);
@@ -1352,7 +1371,10 @@
       return_trace (false);
     }
 
-    match_positions[i] = skippy_iter.idx;
+    if (unlikely (i + 1 > c->match_positions.length &&
+		  !c->match_positions.resize (i + 1, false)))
+      return_trace (false);
+    c->match_positions.arrayZ[i] = skippy_iter.idx;
 
     unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
     unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
@@ -1412,13 +1434,12 @@
     *p_total_component_count = total_component_count;
   }
 
-  match_positions[0] = buffer->idx;
+  c->match_positions.arrayZ[0] = buffer->idx;
 
   return_trace (true);
 }
 static inline bool ligate_input (hb_ot_apply_context_t *c,
 				 unsigned int count, /* Including the first glyph */
-				 const unsigned int *match_positions, /* Including the first glyph */
 				 unsigned int match_end,
 				 hb_codepoint_t lig_glyph,
 				 unsigned int total_component_count)
@@ -1461,10 +1482,10 @@
    *   https://bugzilla.gnome.org/show_bug.cgi?id=437633
    */
 
-  bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]);
-  bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]);
+  bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[c->match_positions.arrayZ[0]]);
+  bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[0]]);
   for (unsigned int i = 1; i < count; i++)
-    if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]]))
+    if (!_hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[i]]))
     {
       is_base_ligature = false;
       is_mark_ligature = false;
@@ -1490,7 +1511,7 @@
 
   for (unsigned int i = 1; i < count; i++)
   {
-    while (buffer->idx < match_positions[i] && buffer->successful)
+    while (buffer->idx < c->match_positions.arrayZ[i] && buffer->successful)
     {
       if (is_ligature)
       {
@@ -1729,7 +1750,6 @@
 
 static inline void apply_lookup (hb_ot_apply_context_t *c,
 				 unsigned int count, /* Including the first glyph */
-				 unsigned int *match_positions, /* Including the first glyph */
 				 unsigned int lookupCount,
 				 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
 				 unsigned int match_end)
@@ -1737,9 +1757,6 @@
   hb_buffer_t *buffer = c->buffer;
   int end;
 
-  unsigned int *match_positions_input = match_positions;
-  unsigned int match_positions_count = count;
-
   /* All positions are distance from beginning of *output* buffer.
    * Adjust. */
   {
@@ -1749,7 +1766,7 @@
     int delta = bl - buffer->idx;
     /* Convert positions to new indexing. */
     for (unsigned int j = 0; j < count; j++)
-      match_positions[j] += delta;
+      c->match_positions.arrayZ[j] += delta;
   }
 
   for (unsigned int i = 0; i < lookupCount && buffer->successful; i++)
@@ -1761,10 +1778,10 @@
     unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
 
     /* This can happen if earlier recursed lookups deleted many entries. */
-    if (unlikely (match_positions[idx] >= orig_len))
+    if (unlikely (c->match_positions.arrayZ[idx] >= orig_len))
       continue;
 
-    if (unlikely (!buffer->move_to (match_positions[idx])))
+    if (unlikely (!buffer->move_to (c->match_positions.arrayZ[idx])))
       break;
 
     if (unlikely (buffer->max_ops <= 0))
@@ -1823,9 +1840,9 @@
      */
 
     end += delta;
-    if (end < int (match_positions[idx]))
+    if (end < int (c->match_positions.arrayZ[idx]))
     {
-      /* End might end up being smaller than match_positions[idx] if the recursed
+      /* End might end up being smaller than match_positions.arrayZ[idx] if the recursed
        * lookup ended up removing many items.
        * Just never rewind end beyond start of current position, since that is
        * not possible in the recursed lookup.  Also adjust delta as such.
@@ -1833,8 +1850,8 @@
        * https://bugs.chromium.org/p/chromium/issues/detail?id=659496
        * https://github.com/harfbuzz/harfbuzz/issues/1611
        */
-      delta += match_positions[idx] - end;
-      end = match_positions[idx];
+      delta += c->match_positions.arrayZ[idx] - end;
+      end = c->match_positions.arrayZ[idx];
     }
 
     unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
@@ -1843,27 +1860,9 @@
     {
       if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH))
 	break;
-      if (unlikely (delta + count > match_positions_count))
-      {
-        unsigned new_match_positions_count = hb_max (delta + count, hb_max(match_positions_count, 4u) * 1.5);
-        if (match_positions == match_positions_input)
-	{
-	  match_positions = (unsigned int *) hb_malloc (new_match_positions_count * sizeof (match_positions[0]));
-	  if (unlikely (!match_positions))
-	    break;
-	  memcpy (match_positions, match_positions_input, count * sizeof (match_positions[0]));
-	  match_positions_count = new_match_positions_count;
-	}
-	else
-	{
-	  unsigned int *new_match_positions = (unsigned int *) hb_realloc (match_positions, new_match_positions_count * sizeof (match_positions[0]));
-	  if (unlikely (!new_match_positions))
-	    break;
-	  match_positions = new_match_positions;
-	  match_positions_count = new_match_positions_count;
-	}
-      }
-
+      if (unlikely (count + delta > c->match_positions.length &&
+		    !c->match_positions.resize (count + delta, false)))
+        return;
     }
     else
     {
@@ -1873,23 +1872,20 @@
     }
 
     /* Shift! */
-    memmove (match_positions + next + delta, match_positions + next,
-	     (count - next) * sizeof (match_positions[0]));
+    memmove (c->match_positions + next + delta, c->match_positions + next,
+	     (count - next) * sizeof (c->match_positions.arrayZ[0]));
     next += delta;
     count += delta;
 
     /* Fill in new entries. */
     for (unsigned int j = idx + 1; j < next; j++)
-      match_positions[j] = match_positions[j - 1] + 1;
+      c->match_positions.arrayZ[j] = c->match_positions.arrayZ[j - 1] + 1;
 
     /* And fixup the rest. */
     for (; next < count; next++)
-      match_positions[next] += delta;
+      c->match_positions.arrayZ[next] += delta;
   }
 
-  if (match_positions != match_positions_input)
-    hb_free (match_positions);
-
   assert (end >= 0);
   (void) buffer->move_to (end);
 }
@@ -1992,14 +1988,6 @@
 				  const ContextApplyLookupContext &lookup_context)
 {
   if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false;
-  unsigned match_positions_stack[4];
-  unsigned *match_positions = match_positions_stack;
-  if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack)))
-  {
-    match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0]));
-    if (unlikely (!match_positions))
-      return false;
-  }
 
   unsigned match_end = 0;
   bool ret = false;
@@ -2006,11 +1994,11 @@
   if (match_input (c,
 		   inputCount, input,
 		   lookup_context.funcs.match, lookup_context.match_data,
-		   &match_end, match_positions))
+		   &match_end))
   {
     c->buffer->unsafe_to_break (c->buffer->idx, match_end);
     apply_lookup (c,
-		  inputCount, match_positions,
+		  inputCount,
 		  lookupCount, lookupRecord,
 		  match_end);
     ret = true;
@@ -2021,41 +2009,32 @@
     ret = false;
   }
 
-  if (unlikely (match_positions != match_positions_stack))
-    hb_free (match_positions);
-
   return ret;
 }
 
-static inline void * context_cache_func (void *p, hb_ot_subtable_cache_op_t op)
+static inline bool context_cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op)
 {
   switch (op)
   {
-    case hb_ot_subtable_cache_op_t::CREATE:
-      return nullptr;
     case hb_ot_subtable_cache_op_t::ENTER:
     {
-      hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
       if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
-	return (void *) false;
+	return false;
       auto &info = c->buffer->info;
       unsigned count = c->buffer->len;
       for (unsigned i = 0; i < count; i++)
 	info[i].syllable() = 255;
       c->new_syllables = 255;
-      return (void *) true;
+      return true;
     }
     case hb_ot_subtable_cache_op_t::LEAVE:
     {
-      hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
       c->new_syllables = (unsigned) -1;
       HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
-      return nullptr;
+      break;
     }
-    case hb_ot_subtable_cache_op_t::DESTROY:
-      return nullptr;
   }
-  return nullptr;
+  return false;
 }
 
 template <typename Types>
@@ -2688,9 +2667,9 @@
   {
     return (this+classDef).cost ();
   }
-  static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
+  static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op)
   {
-    return context_cache_func (p, op);
+    return context_cache_func (c, op);
   }
 
   bool apply_cached (hb_ot_apply_context_t *c, void *external_cache HB_UNUSED) const { return _apply (c, true); }
@@ -3116,14 +3095,6 @@
 					const ChainContextApplyLookupContext &lookup_context)
 {
   if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false;
-  unsigned match_positions_stack[4];
-  unsigned *match_positions = match_positions_stack;
-  if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack)))
-  {
-    match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0]));
-    if (unlikely (!match_positions))
-      return false;
-  }
 
   unsigned start_index = c->buffer->out_len;
   unsigned end_index = c->buffer->idx;
@@ -3132,7 +3103,7 @@
   if (!(match_input (c,
 		     inputCount, input,
 		     lookup_context.funcs.match[1], lookup_context.match_data[1],
-		     &match_end, match_positions) && (end_index = match_end)
+		     &match_end) && (end_index = match_end)
        && match_lookahead (c,
 			   lookaheadCount, lookahead,
 			   lookup_context.funcs.match[2], lookup_context.match_data[2],
@@ -3139,8 +3110,7 @@
 			   match_end, &end_index)))
   {
     c->buffer->unsafe_to_concat (c->buffer->idx, end_index);
-    ret = false;
-    goto done;
+    return false;
   }
 
   if (!match_backtrack (c,
@@ -3149,20 +3119,15 @@
 			&start_index))
   {
     c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
-    ret = false;
-    goto done;
+    return false;
   }
 
   c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
   apply_lookup (c,
-		inputCount, match_positions,
+		inputCount,
 		lookupCount, lookupRecord,
 		match_end);
-  done:
 
-  if (unlikely (match_positions != match_positions_stack))
-    hb_free (match_positions);
-
   return ret;
 }
 
@@ -3909,9 +3874,9 @@
   {
     return (this+inputClassDef).cost () + (this+lookaheadClassDef).cost ();
   }
-  static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
+  static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op)
   {
-    return context_cache_func (p, op);
+    return context_cache_func (c, op);
   }
 
   bool apply_cached (hb_ot_apply_context_t *c, void *external_cache HB_UNUSED) const { return _apply (c, true); }
@@ -4434,8 +4399,9 @@
     for (auto& subtable : hb_iter (thiz->subtables, count))
       thiz->digest.union_ (subtable.digest);
 
+    thiz->count = count;
+
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-    thiz->count = count;
     thiz->subtable_cache_user_idx = c_accelerate_subtables.subtable_cache_user_idx;
 
     for (unsigned i = 0; i < count; i++)
@@ -4450,8 +4416,7 @@
   {
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     for (unsigned i = 0; i < count; i++)
-      if (subtables[i].external_cache)
-	subtables[i].cache_func (subtables[i].external_cache, hb_ot_subtable_cache_op_t::DESTROY);
+      hb_free (subtables[i].external_cache);
 #endif
   }
 
@@ -4461,7 +4426,7 @@
 #ifndef HB_OPTIMIZE_SIZE
   HB_ALWAYS_INLINE
 #endif
-  bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
+  bool apply (hb_ot_apply_context_t *c, bool use_cache) const
   {
     c->lookup_accel = this;
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
@@ -4468,7 +4433,7 @@
     if (use_cache)
     {
       return
-      + hb_iter (hb_iter (subtables, subtables_count))
+      + hb_iter (hb_iter (subtables, count))
       | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); })
       | hb_any
       ;
@@ -4477,7 +4442,7 @@
 #endif
     {
       return
-      + hb_iter (hb_iter (subtables, subtables_count))
+      + hb_iter (hb_iter (subtables, count))
       | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); })
       | hb_any
       ;
@@ -4503,12 +4468,11 @@
 
 
   hb_set_digest_t digest;
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   private:
   unsigned count = 0; /* Number of subtables in the array. */
+#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   unsigned subtable_cache_user_idx = (unsigned) -1;
 #endif
-  private:
   hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY];
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1915,8 +1915,7 @@
 
 static inline bool
 apply_forward (OT::hb_ot_apply_context_t *c,
-	       const OT::hb_ot_layout_lookup_accelerator_t &accel,
-	       unsigned subtable_count)
+	       const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
   bool use_hot_subtable_cache = accel.cache_enter (c);
 
@@ -1924,16 +1923,11 @@
   hb_buffer_t *buffer = c->buffer;
   while (buffer->idx < buffer->len && buffer->successful)
   {
-    bool applied = false;
     auto &cur = buffer->cur();
     if (accel.digest.may_have (cur.codepoint) &&
 	(cur.mask & c->lookup_mask) &&
-	c->check_glyph_property (&cur, c->lookup_props))
-     {
-       applied = accel.apply (c, subtable_count, use_hot_subtable_cache);
-     }
-
-    if (applied)
+	c->check_glyph_property (&cur, c->lookup_props) &&
+        accel.apply (c, use_hot_subtable_cache))
       ret = true;
     else
       (void) buffer->next_glyph ();
@@ -1947,8 +1941,7 @@
 
 static inline bool
 apply_backward (OT::hb_ot_apply_context_t *c,
-	       const OT::hb_ot_layout_lookup_accelerator_t &accel,
-	       unsigned subtable_count)
+	       const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
   bool ret = false;
   hb_buffer_t *buffer = c->buffer;
@@ -1958,11 +1951,10 @@
     if (accel.digest.may_have (cur.codepoint) &&
 	(cur.mask & c->lookup_mask) &&
 	c->check_glyph_property (&cur, c->lookup_props))
-      ret |= accel.apply (c, subtable_count, false);
+      ret |= accel.apply (c, false);
 
     /* The reverse lookup doesn't "advance" cursor (for good reason). */
     buffer->idx--;
-
   }
   while ((int) buffer->idx >= 0);
   return ret;
@@ -1990,8 +1982,8 @@
     {
       auto &info = buffer->info;
       for (unsigned int i = 0; i < buffer->len; i++)
-	_hb_glyph_info_set_match (&info[i],
-				  c->check_glyph_property (&info[i], lookup_props, false));
+	_hb_glyph_info_set_matches (&info[i],
+				    c->check_glyph_property (&info[i], lookup_props, false));
       c->cached_props = lookup_props;
     }
     else
@@ -2006,7 +1998,7 @@
       buffer->clear_output ();
 
     buffer->idx = 0;
-    ret = apply_forward (c, accel, subtable_count);
+    ret = apply_forward (c, accel);
 
     if (!Proxy::always_inplace)
       buffer->sync ();
@@ -2016,7 +2008,7 @@
     /* in-place backward substitution/positioning */
     assert (!buffer->have_output);
     buffer->idx = buffer->len - 1;
-    ret = apply_backward (c, accel, subtable_count);
+    ret = apply_backward (c, accel);
   }
 
   return ret;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -617,9 +617,9 @@
   return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MATCHES;
 }
 static inline void
-_hb_glyph_info_set_match (hb_glyph_info_t *info, bool match)
+_hb_glyph_info_set_matches (hb_glyph_info_t *info, bool matches)
 {
-  if (match)
+  if (matches)
     info->glyph_props() |= HB_OT_LAYOUT_GLYPH_PROPS_MATCHES;
   else
     info->glyph_props() &= ~HB_OT_LAYOUT_GLYPH_PROPS_MATCHES;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2025-08-21 07:53:07 UTC (rev 76107)
@@ -1171,8 +1171,6 @@
   _hb_buffer_deallocate_unicode_vars (c->buffer);
 
   c->buffer->props.direction = c->target_direction;
-
-  c->buffer->leave ();
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -380,7 +380,7 @@
 }
 static inline uint8_t hb_use_get_category (unsigned u)
 {
-  return u<921600 ? hb_use_u8[2953u+(((hb_use_u8[625u+(((hb_use_u16[((hb_use_u8[113u+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31))])<<3)+((u>>1>>3)&7)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : O;
+  return u<921600 ? hb_use_u8[2953u+((hb_use_u8[625u+((hb_use_u16[((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((u)>>1))>>3))>>3))>>5)))<<5)+((((((((u)>>1))>>3))>>3))&31)])<<3)+((((((u)>>1))>>3))&7)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : O;
 }
 
 
@@ -661,11 +661,13 @@
 }
 static inline uint8_t hb_use_get_category (unsigned u)
 {
-  return u<921600 ? hb_use_u8[3265u+(((hb_use_u8[937u+(((hb_use_u16[((hb_use_u8[369u+(((hb_use_u8[113u+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15))])<<3)+((u>>1>>3>>1)&7))])<<1)+((u>>1>>3)&1)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : O;
+  return u<921600 ? hb_use_u8[3265u+((hb_use_u8[937u+((hb_use_u16[((hb_use_u8[369u+((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((((u)>>1))>>3))>>1))>>3))>>4)))<<4)+((((((((((u)>>1))>>3))>>1))>>3))&15)])<<3)+((((((((u)>>1))>>3))>>1))&7)])<<1)+((((((u)>>1))>>3))&1)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : O;
 }
 
+
 #endif
 
+
 #undef B
 #undef CGJ
 #undef CS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -388,6 +388,11 @@
     const auto &var_store = this+v2.varStore;
     auto *var_store_cache = var_store.create_cache ();
 
+    hb_vector_t<int> coords_2_14;
+    coords_2_14.resize (coords_length);
+    for (unsigned i = 0; i < coords_length; i++)
+      coords_2_14[i] = roundf (coords[i] / 4.f); // 16.16 -> 2.14
+
     hb_vector_t<int> out;
     out.alloc (coords_length);
     for (unsigned i = 0; i < coords_length; i++)
@@ -394,7 +399,7 @@
     {
       int v = coords[i];
       uint32_t varidx = varidx_map.map (i);
-      float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache);
+      float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache);
       v += roundf (delta * 4); // 2.14 -> 16.16
       v = hb_clamp (v, -(1<<16), +(1<<16));
       out.push (v);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2025-08-21 07:53:07 UTC (rev 76107)
@@ -149,14 +149,11 @@
 
   hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
 
-  if (buffer->max_ops <= 0)
-    buffer->shaping_failed = true;
-
   hb_shape_plan_destroy (shape_plan);
 
   if (text_buffer)
   {
-    if (res && buffer->successful && !buffer->shaping_failed
+    if (res && buffer->successful
 	    && text_buffer->successful
 	    && !buffer->verify (text_buffer,
 				font,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -861,8 +861,7 @@
 	{
 	  // Hack to point vector to static string.
 	  auto &b = buffArray.arrayZ[last];
-	  b.length = 1;
-	  b.arrayZ = const_cast<unsigned char *>(endchar_str);
+	  b.set_storage (const_cast<unsigned char *>(endchar_str), 1);
 	}
 
       last++; // Skip over gid
@@ -877,8 +876,7 @@
       {
 	// Hack to point vector to static string.
 	auto &b = buffArray.arrayZ[last];
-	b.length = 1;
-	b.arrayZ = const_cast<unsigned char *>(endchar_str);
+	b.set_storage (const_cast<unsigned char *>(endchar_str), 1);
       }
 
     return true;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -761,59 +761,144 @@
 
 #include <stdint.h>
 
-static const uint8_t _hb_ucd_u8[17612]=
+static const uint8_t _hb_ucd_u8[19376]=
 {
-    0,  1,  2,  3,  4,  5,  5,  5,  5,  5,  6,  5,  5,  7,  8,  9,
-   10, 11, 12, 13, 14, 15, 16,  5, 17, 15, 18, 19, 20, 21, 22, 23,
-    5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 24, 25, 26,  5, 27, 28,
-    5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, 32,
-    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, 33,
     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-   31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45,
-   46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59,
-   60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-   60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65,
-   66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80,
-   81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
-   17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101,
-   17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110,
-   17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114,
-   17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120,
-  121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130,
-  131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100,
-  142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100,
-   17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100,
-  100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100,
-   17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100,
-  160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-   60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162,
-   60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   28, 26, 29, 30, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 33, 34, 34, 34, 34,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39,
+   40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+   26, 56, 57, 58, 58, 58, 58, 59, 26, 26, 60, 26, 26, 26, 26, 26,
+   26, 61, 26, 62, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   63, 58, 58, 58, 26, 64, 65, 66, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 67, 26, 26, 68, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 69, 70, 71, 58, 58, 58, 58, 72, 58,
+   58, 58, 58, 58, 58, 58, 73, 74, 75, 76, 77, 78, 79, 80, 58, 81,
+   82, 83, 84, 85, 86, 58, 87, 88, 89, 90, 79, 91, 92, 93, 58, 58,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 94, 26, 26, 26, 26, 26, 26, 26, 95, 96, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 97, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 98, 26, 99, 58, 58, 58, 58, 26,100, 58, 58,
+   26, 26, 26, 26, 26, 26, 26, 26, 26,101, 26, 26, 26, 26, 26, 26,
+   26,102, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+  103, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,104,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,105,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
@@ -1207,174 +1292,200 @@
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0, 38,  0,  0,  0,  0,  0,  0,  0,  0,  0, 39, 40,
     0,  0,  0,  0,  0,  0, 41, 42, 43,  0, 44,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  3,  0,
-    0,  0,  4,  5,  6,  7,  0,  8,  9, 10,  0, 11, 12, 13, 14, 15,
-   16, 17, 16, 18, 16, 19, 16, 19, 16, 19,  0, 19, 16, 20, 16, 19,
-   21, 19,  0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,  0, 32,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0, 33,  0,  0,  0,  0,  0,  0,
-   34,  0,  0, 35,  0,  0, 36,  0, 37,  0,  0,  0, 38, 39, 40, 41,
-   42, 43, 44, 45, 46,  0,  0, 47,  0,  0,  0, 48,  0,  0,  0, 49,
-    0,  0,  0,  0,  0,  0,  0, 50,  0, 51,  0, 52, 53,  0, 54,  0,
-    0,  0,  0,  0,  0, 55, 56, 57,  0,  0,  0,  0, 58,  0,  0, 59,
-   60, 61, 62, 63,  0,  0, 64, 65,  0,  0,  0, 66,  0,  0,  0,  0,
-   67,  0,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0, 69,  0,  0,  0, 70,  0, 71,  0,  0, 72,  0,  0, 73,
-    0,  0,  0,  0,  0,  0,  0,  0, 74, 75,  0,  0,  0,  0, 76, 77,
-    0, 78, 79,  0,  0, 80, 81,  0, 82, 62,  0, 83, 84,  0,  0, 85,
-   86, 87,  0, 88,  0, 89,  0, 90,  0,  0, 51, 91, 51,  0, 92,  0,
-   93,  0,  0,  0, 81,  0,  0,  0, 94, 95,  0, 96, 97, 98, 99,  0,
-    0,  0,  0,  0, 51,  0,  0,  0,  0,100,101,  0,  0,  0,  0,  0,
-    0,102,  0,  0,  0,  0,  0,  0,103,  0,  0,  0,  0,  0,  0,104,
-  105,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,106,  0,  0,107,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,108,109,  0,  0,110,  0,  0,
-    0,  0,  0,  0,111,  0,112,  0,105,  0,  0,  0,  0,  0,113,114,
-    0,  0,  0,  0,  0,  0,  0,115,  0,  0,  0,116,  0,  0,  0,117,
-    0,118,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  0,
-    8,  0,  0,  0,  0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0,
-   14, 15,  0, 16,  0, 17, 18,  0,  0, 19,  0, 20, 21,  0,  0,  0,
-    0,  0, 22, 23,  0, 24, 25,  0,  0, 26,  0,  0,  0, 27,  0,  0,
-   28, 29, 30, 31,  0,  0,  0, 32, 33, 34,  0,  0, 33,  0,  0, 35,
-   33,  0,  0,  0, 33, 36,  0,  0,  0,  0,  0, 37, 38,  0,  0,  0,
-    0,  0,  0, 39, 40,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,
-    0, 43,  0, 44,  0,  0,  0, 45, 46,  0,  0,  0, 47,  0,  0,  0,
-    0,  0,  0, 48, 49,  0,  0,  0,  0, 50,  0,  0,  0, 51,  0, 52,
-    0, 53,  0,  0,  0,  0, 54,  0,  0,  0,  0, 55,  0, 56,  0,  0,
-    0,  0, 57, 58,  0,  0,  0, 59, 60,  0,  0,  0,  0,  0,  0, 61,
-   52,  0, 62, 63,  0,  0, 64,  0,  0,  0, 65, 66,  0,  0,  0, 67,
-    0, 68, 69, 70, 71, 72,  1, 73,  0, 74, 75, 76,  0,  0, 77, 78,
-    0,  0,  0, 79,  0,  0,  1,  1,  0,  0, 80,  0,  0, 81,  0,  0,
-    0,  0, 77, 82,  0, 83,  0,  0,  0,  0,  0, 78, 84,  0, 85,  0,
-   52,  0,  1, 78,  0,  0, 86,  0,  0, 87,  0,  0,  0,  0,  0, 88,
-   57,  0,  0,  0,  0,  0,  0, 89, 90,  0,  0, 84,  0,  0, 33,  0,
-    0, 91,  0,  0,  0,  0, 92,  0,  0,  0,  0, 49,  0,  0, 93,  0,
-    0,  0,  0, 94, 95,  0,  0, 96,  0,  0, 97,  0,  0,  0, 98,  0,
-    0,  0, 99,  0,  0,  0,100,  0,  0,  0,  0,101,102, 93,  0,  0,
-  103,  0,  0,  0, 84,  0,  0,104,  0,  0,  0,105,106,  0,  0,107,
-  108,  0,  0,  0,  0,  0,  0,109,  0,  0,110,  0,  0,  0,  0,111,
-   33,  0,112,113,114, 57,  0,  0,115, 35,  0,  0,116,  0,  0,  0,
-  117,  0,  0,  0,  0,  0,  0,118,  0,  0,119,  0,  0,  0,  0,120,
-   88,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0, 52,121,  0,  0,  0,
-    0,122,  0,  0,123,  0,  0,  0,  0,121,  0,  0,124,  0,  0,  0,
-    0,  0, 79,  0,  0,  0,  0,125,  0,  0,  0,126,  0,  0,  0,127,
-    0,128,  0,  0,  0,  0,129,130,131,  0,132,  0,133,  0,  0,  0,
-  134,135,136,  0, 77,  0,  0,  0,  0,  0, 35,  0,  0,  0,137,  0,
-    0,  0,138,  0,  0,  0,139,  0,  0,140,  0,  0,141,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  2,  3,  4,  0,  0,  0,  0,  0,  0,  0,  0,
+    5,  0,  0,  0,  0,  0,  0,  0,  6,  7,  8,  0,  9,  0, 10, 11,
+    0,  0, 12, 13, 14, 15, 16,  0,  0,  0,  0, 17, 18, 19, 20,  0,
+   21,  0, 22, 23,  0, 24, 25,  0,  0, 24, 26, 27,  0, 24, 26,  0,
+    0, 24, 26,  0,  0, 24, 26,  0,  0,  0, 26,  0,  0, 24, 28,  0,
+    0, 24, 26,  0,  0, 29, 26,  0,  0,  0, 30,  0,  0, 31, 32,  0,
+    0, 33, 34,  0, 35, 36,  0, 37, 38,  0, 39,  0,  0, 40,  0,  0,
+   41,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 42,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 43, 44,  0,  0,  0,  0, 45,  0,  0,  0,  0,  0,
+    0, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0, 48,  0,  0, 49,
+    0, 50, 51,  0,  0, 52, 53, 54,  0, 55,  0, 56,  0, 57,  0,  0,
+    0,  0, 58, 59,  0,  0,  0,  0,  0,  0, 60, 61,  0,  0,  0,  0,
+    0,  0, 62, 63,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 64,  0,  0,  0, 65,  0,  0,  0, 66,  0, 67,  0,  0,
+   68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 69,
+   70,  0,  0, 71,  0,  0,  0,  0,  0,  0,  0,  0, 72, 73,  0,  0,
+    0,  0, 53, 74,  0, 75, 76,  0,  0, 77, 78,  0,  0,  0,  0,  0,
+    0, 79, 80, 81,  0,  0,  0,  0,  0,  0,  0, 26,  0,  0,  0,  0,
+    0,  0,  0,  0, 82,  0,  0,  0,  0,  0,  0,  0,  0, 83,  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, 84,  0,  0,  0,  0,
+    0,  0,  0, 85,  0,  0,  0, 86,  0,  0,  0,  0, 87, 88,  0,  0,
+    0,  0,  0, 89,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 90,  0, 91,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 92,  0, 93,  0,  0, 94,  0, 95,  0,  0,  0,  0,  0, 72, 96,
+    0, 97,  0,  0, 98, 99,  0, 77,  0,  0,100,  0,  0,101,  0,  0,
+    0,  0,  0,102,  0,103, 26,104,  0,  0,105,  0,  0,  0,106,  0,
+    0,  0,107,  0,  0,  0,  0,  0,  0, 65,108,  0,  0, 65,  0,  0,
+    0,109,  0,  0,  0,110,  0,  0,  0,  0,  0,  0,  0, 97,  0,  0,
+    0,  0,  0,  0,  0,111,112,  0,  0,  0,  0, 78,  0, 44,113,  0,
+  114,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 65,  0,  0,
+    0,  0,  0,  0,  0,  0,115,  0,116,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,118,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,119,  0,120,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,121,  0,  0,  0,  0,
+  122,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,123,124,125,  0,  0,  0,  0,126,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,127,128,  0,  0,
+  129,  0,  0,  0,  0,120,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,130,  0,131,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,132,  0,  0,  0,  0,  0,  0,  0,133,  0,  0,  0,  0,
+    0,  0,134,  0,  0,  0,135,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,
     4,  8,  9, 10,  1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1,
-   19,  1,  0,  0, 20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28,
-   29, 30,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36,
-   37,  0,  0,  0,  0, 38,  1, 39, 14, 39, 40, 41, 42,  0,  0,  0,
-   43, 36, 44, 45, 21, 45, 46,  0,  0,  0, 19,  1, 21,  0,  0, 47,
-    0, 38, 48,  1,  1, 49, 49, 50,  0,  0, 51,  0,  0, 19, 52,  1,
-    0,  0, 38, 14,  4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,
-    0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 59,
-    0, 60,  0,  0,  0,  0, 61, 62,  0,  0, 63,  0,  0,  0, 64,  0,
-    0,  0, 65,  0,  0,  0, 66,  0,  0,  0, 67,  0,  0,  0, 68,  0,
-    0, 69, 70,  0, 71, 72, 73, 74, 75, 76,  0,  0,  0, 77,  0,  0,
-    0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0, 49,  0, 80,  0,  0,
-    0, 62,  0,  0, 63,  0,  0, 81,  0,  0, 82,  0,  0,  0, 83,  0,
-    0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,  1, 52, 15, 86,
-   36, 10, 21, 87,  0, 55,  0,  0,  0,  0, 19, 10,  1,  0,  0,  0,
-    0,  0, 88,  0,  0, 89,  0,  0, 88,  0,  0,  0,  0, 78,  0,  0,
+    0,  0,  0,  0, 19,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33,
+   34, 35,  1, 36,  0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,
+    0, 38,  1, 39, 14, 39, 40, 41,  0,  0,  0,  0,  0,  0,  0,  0,
+   42,  0,  0,  0,  0,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,
+    0,  0,  0,  0,  0,  0, 19,  1, 21,  0,  0, 47,  0,  0,  0,  0,
+    0, 38, 48,  1,  1, 49, 49, 50,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 51,  0,  0,  0,  0,  0,  0, 19, 52,  1,  0,  0, 38, 14,
+    4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,  0,  0,  0,  0,
+    0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 56,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 59,  0,  0,  0, 56,
+    0, 60,  0,  0,  0,  0,  0,  0,  0,  0, 61, 62,  0,  0, 63,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 64,  0,  0,  0, 65,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 66,  0,  0,  0, 67,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 68,  0,  0,  0,  0,  0,
+    0, 69, 70,  0,  0,  0,  0,  0, 71, 72, 73, 74, 75, 76,  0,  0,
+    0,  0,  0,  0,  0, 77,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 49,  0,  0,  0,  0,  0, 80,  0,  0,  0,  0,  0,  0,
+    0, 62,  0,  0,  0,  0,  0,  0, 63,  0,  0, 81,  0,  0, 82,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 83,  0,  0,  0,  0,  0,
+    0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,  0,  0,  0,  0,
+    1, 52, 15, 86, 36, 10, 21, 87,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 55,  0,  0,  0, 62,  0,  0,  0,  0,  0,  0,  0,  0, 19, 10,
+    1,  0,  0,  0,  0,  0, 88,  0,  0,  0,  0,  0,  0, 89,  0,  0,
+   88,  0,  0,  0,  0,  0,  0,  0,  0, 78,  0,  0,  0,  0,  0,  0,
    87,  9, 12,  4, 90,  8, 91, 47,  0, 58, 50,  0, 21,  1, 21, 92,
-   93,  1,  1,  1,  1, 94, 95, 96, 97,  1, 98, 58, 81, 99,100,  4,
-   58,  0,  0,  0,  0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0, 61,
-    0,  0,101,102,  0,  0,103,  0,  0,  1,  1, 50,  0,  0,  0, 38,
-    0, 63,  0,  0,  0,  0,  0, 62,  0,  0,104, 68, 61,  0,  0,  0,
-   78,  0,  0,  0,105,106, 58, 38, 81,  0,  0,  0,  0,  0,  0,107,
-    1, 14,  4, 12, 84,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,
-    0,  0,109, 61,  0,110,  0,  0,  0,  1,  0,  0,  0,  0, 49, 50,
-    0,  0, 19, 58,  0,  0,  0, 51,  0,111, 14, 52,112, 41,  0,  0,
-   62,  0,  0, 61,  0,  0,113,  0, 87,  0,  0,  0, 61, 62,  0,  0,
-   62,  0, 89,  0,  0,113,  0,  0,  0,  0,114,  0,  0,  0, 78, 55,
-    0, 38,  1, 58,  1, 58,  0,  0,  0,  0,  0, 88, 63, 89,  0,  0,
-  115,  0,  0,  0, 55,  0,  0,  0,  0,115,  0,  0,  0,  0, 61,  0,
-    0,  0,  0, 79,  0, 61,  0,  0,  0,  0, 56,  0, 89, 80,  0,  0,
-   79,  0,  0,  0,  8, 91,  0,  0,  1, 87,  0,  0,116,  0,  0,  0,
+   93,  1,  1,  1,  1,  1,  1,  1,  1, 94, 95, 96,  0,  0,  0,  0,
+   97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,  0,  0,  0, 19,
+   50,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 61,  1,  1,  1,  1,
+    1,  1,  1,  1,  0,  0,101,102,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,103,  0,  0,  0,  0, 19,  0,  1,  1, 50,  0,  0,  0,  0,
+    0,  0,  0, 38,  0,  0,  0,  0, 50,  0,  0,  0,  0, 63,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0,  0,  1,  1,  1,  1,
+   50,  0,  0,  0,  0,  0,104, 68,  0,  0,  0,  0,  0,  0,  0,  0,
+   61,  0,  0,  0,  0,  0,  0,  0, 78,  0,  0,  0, 62,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,105,106, 58, 38, 81,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0, 63,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,107,  1, 14,  4, 12,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 47, 84,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 38, 87,  0,  0,  0,  0,108,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,109, 61,  0,110,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,
+    0,  0,  0,  0,  0,  0, 49, 50,  0,  0,  0,  0,  0,  0, 19, 58,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 51,  0,111, 14, 52,
+   84,  0,  0,  0,112, 41,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   62,  0,  0, 61,  0,  0,  0,  0,  0,  0,113,  0, 87,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,113,  0,  0,  0,  0,114,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 78, 55,  0, 38,  1, 58,
+    1, 58,  0,  0,  0,  0,  0, 88, 62,  0,  0,  0, 63, 89,  0,  0,
+    0,  0,  0, 59,115,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,115,  0,  0,  0,  0, 61,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 79, 78,  0,  0,  0,
+    0,  0,  0,  0,  0, 61,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 56,  0, 89, 80,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 61,  0,  0, 79,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 61,
+    0,  0,  0,  0,  0,  0,  0,  0,  8, 91,  0,  0,  0,  0,  0,  0,
+    1, 87,  0,  0,  0,  0,  0,  0,116,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,117,  0,118,119,120,121,  0,104,  4,122, 49, 23,  0,
-    0,  0, 38, 50, 38, 58,  0,  0,  1, 87,  1,  1,  1,  1, 39,  1,
-   48,105, 87,  0,  0,  0,  0,  1,  0,  0,  0,123,  0,  0,  0,112,
-    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,230,230,230,230,
-  230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
-  220,220,220,202,202,220,220,220,  1,  1,  1,  1,  1,220,220,220,
-  220,230,230,230,230,240,230,220,220,220,230,230,230,220,220,  0,
-  230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
-  234,234,233,230,  0,  0,  0,230,  0,220,230,230,230,230,220,230,
-  230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,
-  230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27, 28, 29, 30, 31,
-   32, 33, 34,230,230,220,220,230,220,230,230,220, 35,  0,  0,  0,
-    0,  0,230,230,230,  0,  0,230,230,  0,220,230,230,220,  0,  0,
-    0, 36,  0,  0,230,220,230,230,220,220,230,220,220,230,220,230,
-  220,230,230,  0,  0,220,  0,  0,230,230,  0,230,  0,230,230,230,
-  230,230,  0,  0,  0,220,220,220,230,220,220,220,230,230,  0,220,
-   27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,
-  230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,
-    9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,107,107,107,107,
-  118,118,  9,  0,122,122,122,122,220,220,  0,  0,  0,220,  0,220,
-    0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,
-  130,130,  0,  0,130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,
-    0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,  0,230,  0,  0,
-    0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,230,  0,  0,220,
-  230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,  0,  0,  7,  0,
-  230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,230,230,
-  230,230,232,228,228,220,218,230,233,220,230,220,230,230,  1,  1,
-    1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,218,228,
-  232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,230,  0,230,230,
-  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
-    0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
-    0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
-    0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
-  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 17,
-   17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,
-  129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+    0,  0,  0,  0,  0,  0, 38, 50,  0,  0,  0,  0, 38, 58,  0,  0,
+    0,  0,  0,  0,  1, 87,  1,  1,  1,  1, 39,  1, 48,105, 87,  0,
+    0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0, 59,
+    0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,123,
+    0,  0,  0,  0,  0,  0,  0,112,  0,  0,  0,  0,  0,  0,  0,  0,
+    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220,
+  220,202,202,220,220,220,220,202,202,220,220,220,  1,  1,  1,  1,
+    1,220,220,220,220,230,230,230,230,240,230,220,220,220,230,230,
+  230,220,220,  0,230,230,230,220,220,220,220,230,232,220,220,230,
+  233,234,234,233,234,234,233,230,  0,  0,  0,230,  0,220,230,230,
+  230,230,220,230,230,230,222,220,230,230,220,220,230,222,228,230,
+   10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,
+    0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27,
+   28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220,
+   35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,230,  0,220,230,
+  230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,220,220,230,220,
+  220,230,220,230,220,230,230,  0,  0,220,  0,  0,230,230,  0,230,
+    0,230,230,230,230,230,  0,  0,  0,220,220,220,230,220,220,220,
+  230,230,  0,220, 27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,
+    0,230,220,230,230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,
+    0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,
+  107,107,107,107,118,118,  9,  0,122,122,122,122,220,220,  0,  0,
+    0,220,  0,220,  0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,
+    0,  0,130,130,130,130,  0,  0,130,  0,230,230,  9,  0,230,230,
+    0,  0,220,  0,  0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,
+    0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,
+  230,  0,  0,220,230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,
+    0,  0,  7,  0,230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,
+  202,230,230,230,230,230,232,228,228,220,218,230,233,220,230,220,
+  230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,
+    0,  0,218,228,232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,
+  230,  0,230,230,220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,
+  230,  1,220,  0,  0,230,220,  0,  0,  0,220,220,  0,  0,230,220,
+    0,  9,  7,  0,  0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,
+    0,  0,  1,  0,  0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,
+  216,216,216,  0,220,220,220,  0,232,232,220,230,230,230,  7,  0,
+   16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17,
+   20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237,  0,  1,  2,  2,
-    0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  6,  7,  8,
-    9,  0,  0,  0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 20,  0,  0, 21, 22,  0,  0,  0,  0,
-   23, 24, 25, 26,  0, 27,  0, 28, 29, 30, 31, 32,  0,  0,  0,  0,
-    0,  0,  0, 33, 34, 35, 36,  0,  0,  0,  0,  0, 37,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,  1,  2, 40, 41,
-    0,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,
-    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  5,  0,
-    0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  1,  0,  0,  0,  0,
-    0,  0,  8,  9,  0,  0,  0,  0,  0,  0, 10,  0,  0, 10,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,
-    0,  0,  0,  0,  0,  0, 11, 12,  0, 13,  0, 14, 15, 16,  0,  0,
-    0,  0,  0,  1, 17, 18,  0, 19,  7,  1,  0,  0,  0, 20, 20,  7,
-   20, 20, 20, 20, 20, 20, 20,  8, 21,  0, 22,  0,  7, 23, 24,  0,
-   20, 20, 25,  0,  0,  0, 26, 27,  1,  7, 20, 20, 20, 20, 20,  1,
-   28, 29, 30, 31,  0,  0, 20,  0,  0,  0,  0,  0,  0,  0, 10,  0,
-    0,  0,  0,  0,  0,  0, 20, 20, 20,  1,  0,  0,  8, 21, 32,  4,
-    0, 10,  0, 33,  7, 20, 20, 20,  0,  0,  0,  0,  8, 34, 34, 35,
-   36, 34, 37,  0, 38,  1, 20, 20,  0,  0, 39,  0,  1,  1,  0,  8,
-   21,  1, 20,  0,  0,  0,  1,  0,  0, 40,  1,  1,  0,  0,  8, 21,
-    0,  1,  0,  1,  0,  1,  0,  0,  0,  0, 26, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 21,  7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 21,  0, 42, 43, 44,  0, 45,  0,  8, 21,  0,  0,  0,  0,  0,
-    0,  0,  0, 46,  7,  1, 10,  1,  0,  0,  0,  1, 20, 20,  1,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0, 26, 34,  9,  0,  0, 20, 20,
-    1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,  0,  1,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47, 48,  0,  0,  0,
-    0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
-   12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18,
-   18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20, 20, 20, 20, 20,
-   20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, 33,
-   34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20, 38, 20, 39, 40,
-   41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20, 20, 20, 20, 45,
-   46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52, 53, 54, 55, 56,
-   57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237,
+    0,  1,  2,  2,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,
+    0,  6,  7,  8,  9,  0,  0,  0, 10, 11, 12, 13, 14, 15, 16, 17,
+   18, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0,  0, 21, 22,
+    0,  0,  0,  0, 23, 24, 25, 26,  0, 27,  0, 28, 29, 30, 31, 32,
+    0,  0,  0,  0,  0,  0,  0, 33, 34, 35, 36,  0,  0,  0,  0,  0,
+   37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,
+    1,  2, 40, 41,  0,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  3,  4,
+    0,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  1,
+    0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,  0,  0,  0, 10,  0,
+    0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,
+    0,  0,  0, 10,  0,  0,  0,  0,  0,  0, 11, 12,  0, 13,  0, 14,
+   15, 16,  0,  0,  0,  0,  0,  1, 17, 18,  0, 19,  7,  1,  0,  0,
+    0, 20, 20,  7, 20, 20, 20, 20, 20, 20, 20,  8, 21,  0, 22,  0,
+    7, 23, 24,  0, 20, 20, 25,  0,  0,  0, 26, 27,  1,  7, 20, 20,
+   20, 20, 20,  1, 28, 29, 30, 31,  0,  0, 20,  0,  0,  0,  0,  0,
+    0,  0, 10,  0,  0,  0,  0,  0,  0,  0, 20, 20, 20,  1,  0,  0,
+    8, 21, 32,  4,  0, 10,  0, 33,  7, 20, 20, 20,  0,  0,  0,  0,
+    8, 34, 34, 35, 36, 34, 37,  0, 38,  1, 20, 20,  0,  0, 39,  0,
+    1,  1,  0,  8, 21,  1, 20,  0,  0,  0,  1,  0,  0, 40,  1,  1,
+    0,  0,  8, 21,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0, 26, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 21,  7, 20, 41, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 21,  0, 42, 43, 44,  0, 45,  0,  8, 21,  0,
+    0,  0,  0,  0,  0,  0,  0, 46,  7,  1, 10,  1,  0,  0,  0,  1,
+   20, 20,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 26, 34,  9,
+    0,  0, 20, 20,  1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,
+    0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47,
+   48,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 60, 13, 13,
-   13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13, 13, 13, 64, 65,
-   20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13, 68, 20, 20, 20,
+   15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20,
+   20, 20, 20, 20, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+   31, 32, 20, 33, 34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20,
+   38, 20, 39, 40, 41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20,
+   20, 20, 20, 45, 46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52,
+   53, 54, 55, 56, 57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 60, 13, 13, 13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13,
+   13, 13, 64, 65, 20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13,
+   68, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -1417,389 +1528,387 @@
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-   20, 20, 20, 20, 69,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,
-    1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
-    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
-    9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55, 55, 55, 55, 55,
-   55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
-    6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  4,  4,
-    4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-   14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14,
-   14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,  2,  2,  3,  3,
-    3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  0,  0,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,  3,  3, 37, 37,
-   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
-   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
-    2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-   64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
-   90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95,
-   95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37,
-   37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,
-    2,  2,  2,  2,  2,  3,  3,  3,  0,  3,  3,  3,  3,  3,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  7,  7,
-    7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,
-    5,  5,  5,  2,  2,  5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  2,
-    5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  5,  2,
-    2,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  5,  2,  2,
-    2,  2,  5,  5,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  2,  2, 11, 11, 11,  2, 11, 11, 11, 11, 11,
-   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11, 11,
-   11, 11, 11, 11, 11, 11, 11,  2, 11, 11, 11, 11, 11, 11, 11,  2,
-   11, 11,  2, 11, 11,  2, 11, 11,  2,  2, 11,  2, 11, 11, 11,  2,
-    2, 11, 11, 11,  2,  2,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11,
-   11, 11, 11,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,
-   11, 11, 11, 11, 11,  2,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10,
-   10, 10, 10, 10,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,
-   10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,  2,
-   10, 10,  2, 10, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10, 10, 10,
-    2, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,  2,  2, 10, 10,
-   10, 10,  2,  2, 10, 10, 10, 10,  2,  2,  2,  2,  2,  2,  2, 10,
-   10, 10, 10, 10, 10, 10,  2, 21, 21, 21,  2, 21, 21, 21, 21, 21,
-   21, 21, 21,  2,  2, 21, 21,  2,  2, 21, 21, 21, 21, 21, 21, 21,
-   21, 21, 21, 21, 21, 21, 21,  2, 21, 21, 21, 21, 21, 21, 21,  2,
-   21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21, 21, 21,  2,
-    2, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21,  2,  2,
-    2,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2,
-   22, 22,  2, 22, 22, 22, 22, 22, 22,  2,  2,  2, 22, 22, 22,  2,
-   22, 22, 22, 22,  2,  2,  2, 22, 22,  2, 22,  2, 22, 22,  2,  2,
-    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-    2,  2,  2,  2, 22, 22, 22,  2,  2,  2,  2,  2,  2, 22,  2,  2,
-    2,  2,  2,  2, 22, 22, 22, 22, 22,  2,  2,  2,  2,  2, 23, 23,
-   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2, 23, 23, 23,  2,
-   23, 23, 23, 23, 23, 23, 23, 23,  2,  2, 23, 23, 23, 23, 23,  2,
-   23, 23, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 23,  2, 23, 23,
-   23,  2,  2, 23,  2,  2, 23, 23, 23, 23,  2,  2, 23, 23,  2,  2,
-    2,  2,  2,  2,  2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16, 16,  2, 16, 16, 16,  2, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16,  2, 16, 16, 16, 16, 16,  2,  2, 16, 16, 16, 16, 16,  2,
-   16, 16, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16, 16,  2, 16, 16,
-   16, 16,  2,  2, 16, 16,  2, 16, 16, 16,  2,  2,  2,  2, 20, 20,
-   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2,
-   20, 20, 20, 20, 20, 20,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20,
-   20, 20,  2,  2, 20, 20,  2, 36, 36, 36,  2, 36, 36, 36, 36, 36,
-   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,
-   36, 36, 36, 36, 36, 36, 36, 36,  2, 36, 36, 36, 36, 36, 36, 36,
-   36, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36, 36,
-   36, 36, 36,  2, 36,  2,  2,  2,  2,  2,  2,  2, 36, 36,  2,  2,
-   36, 36, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0, 24, 24,
-   24, 24,  2,  2,  2,  2,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
-   18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-   18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18,
-   18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2, 18, 18,
-    2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25,
-   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2, 25, 25,
-   25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,  0,  0,  0, 25,
-   25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,
-    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  8,  2,  2,
-    2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12,
-   12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30,  2,
-   30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30, 30,
-   30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30,
-    2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-   29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
-   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
-   35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,
-    2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-   45, 45, 45, 45,  2,  2,  2,  2,  2,  2,  2,  2,  2, 45, 44, 44,
-   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43,
-   43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,  2,  2, 46, 46,
-   46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2,
-   46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-   31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,
-    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    2,  2,  2,  2,  2,  2, 32,  2,  2,  2,  2,  2,  2,  2, 32, 32,
-   32,  2,  2,  2,  2,  2, 28, 28, 28, 28, 28, 28,  2,  2, 48, 48,
-   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,  2, 48, 48,
-   48, 48,  2,  2,  2,  2, 48,  2,  2,  2, 48, 48, 48, 48, 52, 52,
-   52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,  2,  2, 52, 52,
-   52, 52, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-   58, 58,  2,  2,  2,  2, 58, 58,  2,  2,  2,  2,  2,  2, 58, 58,
-   58,  2,  2,  2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
-   54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-   91, 91, 91, 91, 91,  2, 91, 91, 91, 91, 91,  2,  2, 91, 91, 91,
-    2,  2,  2,  2,  2,  2, 91, 91, 91, 91, 91, 91,  2,  2,  1,  1,
-    1,  1,  1,  1,  1,  2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
-   62, 62, 62,  2, 62, 62, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93,
-   93, 93, 93, 93, 93, 93, 93, 93, 93, 93,  2,  2,  2,  2,  2,  2,
-    2,  2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70,  2,  2,
-    2, 70, 70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73,
-   73, 73, 73, 73, 73, 73,  6,  6,  6,  2,  2,  2,  2,  2,  8,  8,
-    8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,
-    1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0,
-    0,  0,  1,  0,  0,  0,  1,  1,  0,  2,  2,  2,  2,  2, 19, 19,
-   19, 19, 19, 19,  9,  9,  9,  9,  9,  6, 19, 19, 19, 19, 19, 19,
-   19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19,  9,  9,  9,  9,
-    9, 19, 19, 19, 19, 19,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19, 19, 19, 19, 19,  9,  9,  9,  9,  9,  9,  9,  2,  2,  2,  9,
-    2,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,
-    9,  9,  2,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  2,  2,
-    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  0,  0,
-    0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0, 19,
-    2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,
-    0,  0,  0,  0,  0,  2, 19, 19, 19, 19, 19,  2,  2,  2,  0,  2,
-    2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2,  0,  0,
-    0,  0,  0,  0,  9,  0,  0,  0, 19, 19,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 19,  0, 19,  0,  0,  0,  2,  2,  2,  2,  0,  0,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  2, 27, 27,
-   27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,
-    0,  0,  0,  0,  2,  0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55,
-   55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
-   61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13, 13, 13,
-   13, 13,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13,  2,  2,  0,  0,
-    0,  0,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-    1,  1,  1,  1, 12, 12, 13, 13, 13, 13,  0,  0,  0,  0,  2, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17,  0,  0, 17, 17, 17,  2,  2,  2,  2,  2, 26, 26, 26, 26, 26,
-   26, 26, 26, 26, 26, 26,  2, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-   12, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  0, 12, 12,
-   12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17, 17,  0, 39, 39,
-   39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39,
-   39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
-   77, 77, 77, 77, 77, 77, 77, 77, 77, 77,  2,  2,  2,  2, 79, 79,
-   79, 79, 79, 79, 79, 79,  0,  0, 19, 19, 19, 19, 19, 19,  0,  0,
-    0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  2,  2, 19, 19,
-    2, 19,  2, 19, 19, 19,  2,  2, 19, 19, 19, 19, 19, 19, 60, 60,
-   60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,  2,  2,  2, 65, 65,
-   65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
-   75, 75, 75, 75,  2,  2,  2,  2,  2,  2,  2,  2, 75, 75, 75, 75,
-    2,  2,  2,  2,  2,  2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
-   69, 69, 69, 69,  0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
-   74, 74,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 74, 12, 12,
-   12, 12, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
-   84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33,
-   33, 33, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
-   68, 68, 68, 68, 68,  2, 68, 68, 68, 68, 68, 68,  2,  2, 68, 68,
-    2,  2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-   92,  2,  2,  2,  2,  2,  2,  2,  2, 92, 92, 92, 92, 92, 87, 87,
-   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,  2,  2, 30,
-   30, 30, 30, 30, 30,  2, 19, 19, 19,  0, 19, 19, 19, 19, 19, 19,
-   19, 19, 19,  9, 19, 19, 19, 19,  0,  0,  2,  2,  2,  2, 87, 87,
-   87, 87, 87, 87,  2,  2, 87, 87,  2,  2,  2,  2,  2,  2, 12, 12,
-   12, 12,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12, 12, 13, 13,
-    2,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19, 19,  2,  2,  2,
-    2,  4,  4,  4,  4,  4,  2,  2,  2,  2,  2, 14, 14, 14, 14, 14,
-   14, 14, 14, 14, 14,  2, 14, 14, 14, 14, 14,  2, 14,  2, 14, 14,
-    2, 14, 14,  2, 14, 14,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,
-    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  0,  2,  2,
-    3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  3,  1,  1,
-    1,  1,  1,  1,  6,  6,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,
-    0,  0,  2,  2,  2,  2,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,
-    3,  3,  3,  2,  2,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0,  2,  2,
-   12, 12, 12, 12, 12, 12,  2,  2, 12, 12, 12,  2,  2,  2,  2,  0,
-    0,  0,  0,  0,  2,  2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-   49, 49,  2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  2, 49, 49,
-   49,  2, 49, 49,  2, 49, 49, 49, 49, 49, 49, 49,  2,  2, 49, 49,
-   49,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  0,  0,  0,
-    0,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2,  2,  9,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  1,  2,  2, 71, 71,
-   71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,  2,  2,  2, 67, 67,
-   67, 67, 67, 67, 67, 67, 67,  2,  2,  2,  2,  2,  2,  2,  1,  0,
-    0,  0,  0,  0,  0,  0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
-   42, 42,  2,  2,  2,  2,  2,  2,  2,  2,  2, 42, 42, 42, 41, 41,
-   41, 41, 41, 41, 41, 41, 41, 41, 41,  2,  2,  2,  2,  2,118,118,
-  118,118,118,118,118,118,118,118,118,  2,  2,  2,  2,  2, 53, 53,
-   53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59,
-   59, 59, 59, 59, 59, 59, 59, 59, 59, 59,  2,  2,  2,  2, 59, 59,
-   59, 59, 59, 59,  2,  2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51,
-   51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
-   50, 50, 50, 50,  2,  2, 50, 50,  2,  2,  2,  2,  2,  2,135,135,
-  135,135,135,135,135,135,135,135,135,135,  2,  2,  2,  2,106,106,
-  106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,
-  104,104,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,104,161,161,
-  161,161,161,161,161,161,161,161,161,  2,161,161,161,161,161,161,
-  161,  2,161,161,  2,161,161,161,  2,161,161,161,161,161,161,161,
-    2,161,161,  2,  2,  2,170,170,170,170,170,170,170,170,170,170,
-  170,170,  2,  2,  2,  2,110,110,110,110,110,110,110,110,110,110,
-  110,110,110,110,110,  2,110,110,110,110,110,110,  2,  2, 19, 19,
-   19, 19, 19, 19,  2, 19, 19,  2, 19, 19, 19, 19, 19, 19, 19, 19,
-   19,  2,  2,  2,  2,  2, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2,
-   47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
-   47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81,
-   81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,  2, 81,120,120,
-  120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116,
-  116,116,116,116,116,  2,  2,  2,  2,  2,  2,  2,  2,116,128,128,
-  128,128,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
-    2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
-   66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
-    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97,
-   97, 97, 97, 97, 97, 97,  2,  2,  2,  2, 97, 97, 97, 97,  2,  2,
-   97, 97, 97, 97, 97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2,  2,
-    2,  2, 57, 57, 57, 57, 57, 57, 57, 57,  2, 57, 57, 57,  2, 57,
-   57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
-   57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,
-    2,  2,  2,  2,  2,  2, 88, 88, 88, 88, 88, 88, 88, 88,117,117,
-  117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112,
-  112,112,112,112,112,  2,  2,  2,  2,112,112,112,112,112, 78, 78,
-   78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78,
-   78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
-   82,  2,  2,  2,  2,  2,122,122,122,122,122,122,122,122,122,122,
-    2,  2,  2,  2,  2,  2,  2,122,122,122,122,  2,  2,  2,  2,122,
-  122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89,  2,
-    2,  2,  2,  2,  2,  2,130,130,130,130,130,130,130,130,130,130,
-  130,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,130,130,144,144,
-  144,144,144,144,144,144,144,144,  2,  2,  2,  2,  2,  2,165,165,
-  165,165,165,165,165,165,165,165,165,165,165,165,  2,  2,  2,165,
-  165,165,165,165,165,165,  2,  2,  2,  2,  2,  2,165,165,156,156,
-  156,156,156,156,156,156,156,156,  2,156,156,156,  2,  2,156,156,
-    2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  2,  2,  2,  2,  2,
-    2,  2,  3,  3,  3,  3,147,147,147,147,147,147,147,147,148,148,
-  148,148,148,148,148,148,148,148,  2,  2,  2,  2,  2,  2,158,158,
-  158,158,158,158,158,158,158,158,  2,  2,  2,  2,  2,  2,153,153,
-  153,153,153,153,153,153,153,153,153,153,  2,  2,  2,  2,149,149,
-  149,149,149,149,149,149,149,149,149,149,149,149,149,  2, 94, 94,
-   94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2,
-   94, 94, 94, 94, 94, 94,  2,  2,  2,  2,  2,  2,  2, 94, 85, 85,
-   85, 85, 85, 85, 85, 85, 85, 85, 85,  2,  2,  2,  2,  2,  2,  2,
-    2,  2,  2, 85,  2,  2,101,101,101,101,101,101,101,101,101,  2,
-    2,  2,  2,  2,  2,  2,101,101,  2,  2,  2,  2,  2,  2, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,  2, 96, 96,111,111,
-  111,111,111,111,111,111,111,111,111,111,111,111,111,  2,100,100,
-  100,100,100,100,100,100,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-   36, 36, 36,  2,  2,  2,108,108,108,108,108,108,108,108,108,108,
-    2,108,108,108,108,108,108,108,  2,  2,  2,  2,  2,  2,129,129,
-  129,129,129,129,129,  2,129,  2,129,129,129,129,  2,129,129,129,
-  129,129,129,129,129,129,129,129,129,129,129,129,  2,129,129,129,
-    2,  2,  2,  2,  2,  2,109,109,109,109,109,109,109,109,109,109,
-  109,  2,  2,  2,  2,  2,109,109,  2,  2,  2,  2,  2,  2,107,107,
-  107,107,  2,107,107,107,107,107,107,107,107,  2,  2,107,107,  2,
-    2,107,107,107,107,107,107,107,107,107,107,107,107,107,107,  2,
-  107,107,107,107,107,107,107,  2,107,107,  2,107,107,107,107,107,
-    2,  1,107,107,107,107,107,  2,  2,107,107,107,  2,  2,107,  2,
-    2,  2,  2,  2,  2,107,  2,  2,  2,  2,  2,107,107,107,107,107,
-  107,107,  2,  2,107,107,107,107,107,107,107,  2,  2,  2,171,171,
-  171,171,171,171,171,171,171,171,  2,171,  2,  2,171,  2,171,171,
-  171,171,171,171,  2,171,171,  2,171,  2,  2,171,  2,171,171,171,
-  171,  2,171,171,171,171,171,  2,  2,  2,  2,  2,  2,  2,  2,171,
-  171,  2,  2,  2,  2,  2,137,137,137,137,137,137,137,137,137,137,
-  137,137,  2,137,137,137,137,137,  2,  2,  2,  2,  2,  2,124,124,
-  124,124,124,124,124,124,124,124,  2,  2,  2,  2,  2,  2,123,123,
-  123,123,123,123,123,123,123,123,123,123,123,123,  2,  2,114,114,
-  114,114,114,114,114,114,114,114,114,114,114,  2,  2,  2,114,114,
-    2,  2,  2,  2,  2,  2, 32, 32, 32, 32, 32,  2,  2,  2,102,102,
-  102,102,102,102,102,102,102,102,  2,  2,  2,  2,  2,  2, 33, 33,
-   33, 33,  2,  2,  2,  2,126,126,126,126,126,126,126,126,126,126,
-  126,  2,  2,126,126,126,126,126,126,126,  2,  2,  2,  2,126,126,
-  126,126,126,126,126,  2,142,142,142,142,142,142,142,142,142,142,
-  142,142,  2,  2,  2,  2,125,125,125,125,125,125,125,125,125,125,
-  125,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,125,154,154,
-  154,154,154,154,154,  2,  2,154,  2,  2,154,154,154,154,154,154,
-  154,154,  2,154,154,  2,154,154,154,154,154,154,154,154,154,154,
-  154,154,154,154,  2,154,154,  2,  2,154,154,154,154,154,154,154,
-    2,  2,  2,  2,  2,  2,150,150,150,150,150,150,150,150,  2,  2,
-  150,150,150,150,150,150,150,150,150,150,150,  2,  2,  2,141,141,
-  141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140,
-  140,  2,  2,  2,  2,  2,121,121,121,121,121,121,121,121,121,  2,
-    2,  2,  2,  2,  2,  2,  7,  7,  2,  2,  2,  2,  2,  2,169,169,
-  169,169,169,169,169,169,169,169,  2,  2,  2,  2,  2,  2,133,133,
-  133,133,133,133,133,133,133,  2,133,133,133,133,133,133,133,133,
-  133,133,133,133,133,  2,133,133,133,133,133,133,  2,  2,133,133,
-  133,133,133,  2,  2,  2,134,134,134,134,134,134,134,134,  2,  2,
-  134,134,134,134,134,134,  2,134,134,134,134,134,134,134,134,134,
-  134,134,134,134,134,  2,138,138,138,138,138,138,138,  2,138,138,
-    2,138,138,138,138,138,138,138,138,138,138,138,138,138,  2,  2,
-  138,  2,138,138,  2,138,138,138,  2,  2,  2,  2,  2,  2,143,143,
-  143,143,143,143,  2,143,143,  2,143,143,143,143,143,143,143,143,
-  143,143,143,143,143,143,143,143,143,143,143,143,143,  2,143,143,
-    2,143,143,143,143,143,143,  2,  2,  2,  2,  2,  2,  2,143,143,
-    2,  2,  2,  2,  2,  2,145,145,145,145,145,145,145,145,145,  2,
-    2,  2,  2,  2,  2,  2,163,163,163,163,163,163,163,163,163,  2,
-  163,163,163,163,163,163,163,163,163,  2,  2,  2,163,163,163,163,
-  163,  2,  2,  2,  2,  2, 86,  2,  2,  2,  2,  2,  2,  2, 22, 22,
-    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 22, 63, 63,
-   63, 63, 63, 63, 63, 63, 63, 63,  2,  2,  2,  2,  2,  2, 63, 63,
-   63, 63, 63, 63, 63,  2, 63, 63, 63, 63, 63,  2,  2,  2, 63, 63,
-   63, 63,  2,  2,  2,  2,157,157,157,157,157,157,157,157,157,157,
-  157,  2,  2,  2,  2,  2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
-   80, 80, 80, 80,  2,  2, 80, 80, 80,  2,  2,  2,  2,  2,127,127,
-  127,127,127,127,127,127,127,127,127,127,127,127,127,  2,166,166,
-  166,166,166,166,166,166,166,166,  2,  2,  2,  2,  2,  2, 79,  2,
-    2,  2,  2,  2,  2,  2,115,115,115,115,115,115,115,115,115,115,
-  115,115,115,115,115,  2,115,115,  2,  2,  2,  2,115,115,159,159,
-  159,159,159,159,159,159,159,159,159,159,159,159,159,  2,159,159,
-    2,  2,  2,  2,  2,  2,103,103,103,103,103,103,103,103,103,103,
-  103,103,103,103,  2,  2,119,119,119,119,119,119,119,119,119,119,
-  119,119,119,119,  2,  2,119,119,  2,119,119,119,119,119,  2,  2,
-    2,  2,  2,119,119,119,167,167,167,167,167,167,167,167,167,167,
-    2,  2,  2,  2,  2,  2,146,146,146,146,146,146,146,146,146,146,
-  146,  2,  2,  2,  2,  2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-   99,  2,  2,  2,  2, 99,  2,  2,  2,  2,  2,  2,  2, 99,136,139,
-   13, 13,155,  2,  2,  2,136,136,136,136,136,136,136,136,155,155,
-  155,155,155,155,155,155,155,155,155,155,155,155,  2,  2,  2,  2,
-    2,  2,  2,  2,  2,155,136,  2,  2,  2,  2,  2,  2,  2, 17, 17,
-   17, 17,  2, 17, 17, 17, 17, 17, 17, 17,  2, 17, 17,  2, 17, 15,
-   15, 15, 15, 15, 15, 15, 17, 17, 17,  2,  2,  2,  2,  2,  2,  2,
-   15,  2,  2,  2,  2,  2, 15, 15, 15,  2,  2, 17,  2,  2,  2,  2,
-    2,  2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139,
-  139,139,  2,  2,  2,  2,105,105,105,105,105,105,105,105,105,105,
-  105,  2,  2,  2,  2,  2,105,105,105,105,105,  2,  2,  2,105,  2,
-    2,  2,  2,  2,  2,  2,105,105,  2,  2,105,105,105,105,  1,  1,
-    1,  1,  1,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,
-    1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,
-    1,  1,  1,  1,  0,  0,  2,  2,  0,  2,  2,  0,  0,  2,  2,  0,
-    0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  2,  0,  0,  0,  0,  0,
-    0,  0,  2,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,  0,
-    2,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  2,  0,  2,  2,  2,
-    0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,131,131,
-  131,131,131,131,131,131,131,131,131,131,  2,  2,  2,  2,  2,  2,
-    2,131,131,131,131,131,  2,131,131,131,131,131,131,131,  2,  2,
-    2,  2,  2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56,  2, 56,  2,
-    2, 56, 56, 56, 56, 56, 56, 56,  2, 56, 56,  2, 56, 56, 56, 56,
-   56,  2,  2,  2,  2,  2,  6,  6,  6,  6,  6,  6,  2,  2,  2,  2,
-    2,  2,  2,  2,  2,  6,151,151,151,151,151,151,151,151,151,151,
-  151,151,151,  2,  2,  2,151,151,151,151,151,151,  2,  2,151,151,
-    2,  2,  2,  2,151,151,160,160,160,160,160,160,160,160,160,160,
-  160,160,160,160,160,  2,152,152,152,152,152,152,152,152,152,152,
-    2,  2,  2,  2,  2,152,164,164,164,164,164,164,164,164,164,164,
-    2,  2,  2,  2,  2,  2,168,168,168,168,168,168,168,168,168,168,
-  168,  2,  2,  2,  2,168, 30, 30, 30, 30,  2, 30, 30,  2,113,113,
-  113,113,113,113,113,113,113,113,113,113,113,  2,  2,113,113,113,
-  113,113,113,113,113,  2,132,132,132,132,132,132,132,132,132,132,
-  132,132,  2,  2,  2,  2,132,132,  2,  2,  2,  2,132,132,  3,  3,
-    3,  3,  2,  3,  3,  3,  2,  3,  3,  2,  3,  2,  2,  3,  2,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,  2,  3,
-    2,  3,  2,  2,  2,  2,  2,  2,  3,  2,  2,  2,  2,  3,  2,  3,
-    2,  3,  2,  3,  3,  3,  2,  3,  2,  3,  2,  3,  2,  3,  2,  3,
-    3,  3,  3,  2,  3,  2,  3,  3,  2,  3,  3,  3,  3,  3,  3,  3,
-    3,  3,  2,  2,  2,  2,  2,  3,  3,  3,  2,  3,  3,  3,  3,  3,
-    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0, 15,  0,
-    0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  2,  2,
-    2,  0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  2,  0,  0,  0,
-    0,  0,  0,  2,  2,  0, 13,  2,  2,  2,  2,  2,  2,  2, 13, 13,
-   13,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  0,  1,
-    2,  3,  4,  5,  6,  7,  8,  9,  9,  9,  9, 10,  9, 11, 12, 13,
-    9,  9,  9, 14,  9,  9, 15,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   20, 20, 20, 20, 20, 20, 20, 20, 69,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,
+    0,  0, 19, 19, 19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,
+    0,  0, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,
+    0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,
+    9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,
+    9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55,
+   55, 55, 55, 55, 55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,
+    6,  6,  6,  6,  6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  2,  4,  4,  4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,
+    2,  2, 14, 14, 14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,
+    2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,
+    3,  0,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,
+    3,  3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+    2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38,
+   38, 38, 38, 38,  2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64,
+   64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90,
+   90, 90, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90,
+   90,  2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2,
+   95,  2, 37, 37, 37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,
+    3,  2,  3,  3,  2,  2,  2,  2,  2,  3,  3,  3,  0,  3,  3,  3,
+    3,  3,  7,  7,  7,  7,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,
+    7,  7,  7,  7,  7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,
+    5,  5,  5,  5,  5,  5,  5,  2,  2,  5,  5,  2,  2,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  5,  5,  5,  5,
+    5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,
+    5,  5,  5,  2,  2,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,
+    2,  5,  2,  2,  2,  2,  5,  5,  2,  5,  5,  5,  5,  5,  2,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2, 11, 11, 11,  2, 11,
+   11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11,
+   11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2, 11, 11, 11, 11,
+   11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,  2,  2, 11,  2,
+   11, 11, 11,  2,  2, 11, 11, 11,  2,  2,  2, 11,  2,  2,  2,  2,
+    2,  2,  2, 11, 11, 11, 11,  2, 11,  2,  2,  2,  2,  2,  2,  2,
+   11, 11, 11, 11, 11, 11, 11, 11, 11,  2,  2, 10, 10, 10,  2, 10,
+   10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,  2, 10, 10, 10,
+   10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10, 10,
+   10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10, 10,  2,  2, 10, 10,
+   10, 10, 10, 10,  2, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,
+    2,  2, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10,  2,  2,  2,  2,
+    2,  2,  2, 10, 10, 10, 10, 10, 10, 10,  2, 21, 21, 21,  2, 21,
+   21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2, 21, 21, 21, 21,
+   21, 21, 21,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21,
+   21, 21, 21,  2,  2, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2, 21,
+   21, 21,  2,  2,  2,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2,
+   21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22, 22,  2,  2,  2,
+   22, 22, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22, 22,  2, 22,  2,
+   22, 22,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22,
+   22, 22, 22, 22,  2,  2,  2,  2, 22, 22, 22,  2,  2,  2,  2,  2,
+    2, 22,  2,  2,  2,  2,  2,  2, 22, 22, 22, 22, 22,  2,  2,  2,
+    2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2,
+   23, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23,  2,  2, 23, 23,
+   23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23,
+   23,  2, 23, 23, 23,  2,  2, 23,  2,  2, 23, 23, 23, 23,  2,  2,
+   23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16,  2, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16, 16,  2,  2, 16, 16,
+   16, 16, 16,  2, 16, 16, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16,
+   16,  2, 16, 16, 16, 16,  2,  2, 16, 16,  2, 16, 16, 16,  2,  2,
+    2,  2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2,
+   20, 20, 20,  2, 20, 20, 20, 20, 20, 20,  2,  2,  2,  2, 20, 20,
+   20, 20, 20, 20, 20, 20,  2,  2, 20, 20,  2, 36, 36, 36,  2, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36,  2, 36, 36, 36,
+   36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,
+    2, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,  2,  2,  2,  2,
+   36, 36,  2,  2, 36, 36, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,
+    2,  0, 24, 24, 24, 24,  2,  2,  2,  2,  2, 18, 18,  2, 18,  2,
+   18, 18, 18, 18, 18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,
+    2,  2, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18,
+   18,  2, 18, 18,  2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25,
+   25, 25,  2, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,
+    2,  2, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,
+    0,  0,  0, 25, 25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33,
+   33, 33,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    2,  8,  2,  2,  2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,
+    8,  8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30,
+   30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30,
+   30,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,
+    2,  2, 30, 30,  2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29,
+   29, 29, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28,
+   28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,
+    2,  2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0,
+   35, 35, 35,  2,  2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45,
+   45, 45, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,  2,  2,  2,  2,
+    2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,
+    0,  2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,
+    2,  2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2,
+   46, 46, 46,  2, 46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31,
+   31, 31, 31, 31, 31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,
+    2,  2, 32, 32,  0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32,  2,  2,  2,  2,  2,  2, 32,  2,  2,  2,  2,  2,
+    2,  2, 32, 32, 32,  2,  2,  2,  2,  2, 28, 28, 28, 28, 28, 28,
+    2,  2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+   48,  2, 48, 48, 48, 48,  2,  2,  2,  2, 48,  2,  2,  2, 48, 48,
+   48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    2,  2, 52, 52, 52, 52, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58,  2,  2,  2,  2, 58, 58,  2,  2,  2,  2,
+    2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54, 54, 54, 54, 54,
+   54, 54, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91,  2, 91, 91, 91, 91, 91,  2,
+    2, 91, 91, 91,  2,  2,  2,  2,  2,  2, 91, 91, 91, 91, 91, 91,
+    2,  2,  1,  1,  1,  1,  1,  1,  1,  2, 62, 62, 62, 62, 62, 62,
+   62, 62, 62, 62, 62, 62, 62,  2, 62, 62, 76, 76, 76, 76, 76, 76,
+   76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,  2,  2,
+    2,  2,  2,  2,  2,  2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70,
+   70, 70,  2,  2,  2, 70, 70, 70, 70, 70, 70, 70,  2,  2,  2, 70,
+   70, 70, 73, 73, 73, 73, 73, 73, 73, 73,  6,  6,  6,  2,  2,  2,
+    2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  1,
+    1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,
+    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  1,  0,  2,  2,  2,
+    2,  2, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9,  6, 19, 19,
+   19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19,
+    9,  9,  9,  9,  9, 19, 19, 19, 19, 19,  6, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9,  9,  9,
+    2,  2,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  2,
+    9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,  9,  9,  2,  9,
+    9,  9,  2,  2,  9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  2,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  2,
+    0,  0,  0, 19,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 19,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19, 19, 19, 19,  2,
+    2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,
+    2,  2,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0, 19, 19,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 19,  0, 19,  0,  0,  0,  2,  2,
+    2,  2,  0,  0,  2,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,
+    2,  2, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  2,  2,
+    0,  0,  0,  0,  0,  0,  0,  0,  2,  0, 56, 56, 56, 56, 56, 56,
+   56, 56, 55, 55, 55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55,
+   55, 55, 61, 61, 61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,
+    2, 61, 61,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,
+    2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13,
+   13, 13, 13, 13, 13, 13,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13,
+    2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13,
+   13, 13, 13, 13,  1,  1,  1,  1, 12, 12, 13, 13, 13, 13,  0,  0,
+    0,  0,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,  1,  0,  0, 15,
+   15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17,  0,  0, 17, 17, 17,  2,  2,  2,  2,  2, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2,
+    2,  0, 12, 12, 12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17,
+   17,  0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,
+    2,  2, 39, 39, 39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86,
+   86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,  2,  2,
+    2,  2, 79, 79, 79, 79, 79, 79, 79, 79,  0,  0, 19, 19, 19, 19,
+   19, 19,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+    2,  2, 19, 19,  2, 19,  2, 19, 19, 19,  2,  2, 19, 19, 19, 19,
+   19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,  2,
+    2,  2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75,
+   75, 75, 75, 75, 75, 75, 75, 75,  2,  2,  2,  2,  2,  2,  2,  2,
+   75, 75, 75, 75,  2,  2,  2,  2,  2,  2, 69, 69, 69, 69, 69, 69,
+   69, 69, 69, 69, 69, 69, 69, 69,  0, 69, 74, 74, 74, 74, 74, 74,
+   74, 74, 74, 74, 74, 74,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2, 74, 12, 12, 12, 12, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84,
+   84, 84, 84, 84, 84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2,
+   84, 84, 33, 33, 33, 33, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68,
+   68, 68, 68, 68, 68, 68, 68, 68, 68,  2, 68, 68, 68, 68, 68, 68,
+    2,  2, 68, 68,  2,  2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92,
+   92, 92, 92, 92, 92,  2,  2,  2,  2,  2,  2,  2,  2, 92, 92, 92,
+   92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+   87,  2,  2, 30, 30, 30, 30, 30, 30,  2, 19, 19, 19,  0, 19, 19,
+   19, 19, 19, 19, 19, 19, 19,  9, 19, 19, 19, 19,  0,  0,  2,  2,
+    2,  2, 87, 87, 87, 87, 87, 87,  2,  2, 87, 87,  2,  2,  2,  2,
+    2,  2, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12,
+   12, 12, 13, 13,  2,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19,
+   19,  2,  2,  2,  2,  4,  4,  4,  4,  4,  2,  2,  2,  2,  2, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14,  2, 14, 14, 14, 14, 14,  2,
+   14,  2, 14, 14,  2, 14, 14,  2, 14, 14,  3,  3,  3,  2,  2,  2,
+    2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    0,  0,  2,  2,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,
+    2,  3,  1,  1,  1,  1,  1,  1,  6,  6,  0,  0,  0,  2,  0,  0,
+    0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  3,  3,  3,  3,  3,  2,
+    3,  3,  3,  3,  3,  3,  3,  2,  2,  0,  2,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17, 17, 17, 17, 17,
+    0,  0,  2,  2, 12, 12, 12, 12, 12, 12,  2,  2, 12, 12, 12,  2,
+    2,  2,  2,  0,  0,  0,  0,  0,  2,  2, 49, 49, 49, 49, 49, 49,
+   49, 49, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+   49,  2, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49, 49, 49, 49, 49,
+    2,  2, 49, 49, 49,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,
+    2,  0,  0,  0,  0,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,
+    2,  2,  9,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  1,
+    2,  2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,  2,
+    2,  2, 67, 67, 67, 67, 67, 67, 67, 67, 67,  2,  2,  2,  2,  2,
+    2,  2,  1,  0,  0,  0,  0,  0,  0,  0, 42, 42, 42, 42, 42, 42,
+   42, 42, 42, 42, 42, 42,  2,  2,  2,  2,  2,  2,  2,  2,  2, 42,
+   42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,  2,  2,  2,
+    2,  2,118,118,118,118,118,118,118,118,118,118,118,  2,  2,  2,
+    2,  2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+    2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,  2,  2,
+    2,  2, 59, 59, 59, 59, 59, 59,  2,  2, 40, 40, 40, 40, 40, 40,
+   40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50,
+   50, 50, 50, 50, 50, 50, 50, 50,  2,  2, 50, 50,  2,  2,  2,  2,
+    2,  2,135,135,135,135,135,135,135,135,135,135,135,135,  2,  2,
+    2,  2,106,106,106,106,106,106,106,106,104,104,104,104,104,104,
+  104,104,104,104,104,104,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,104,161,161,161,161,161,161,161,161,161,161,161,  2,161,161,
+  161,161,161,161,161,  2,161,161,  2,161,161,161,  2,161,161,161,
+  161,161,161,161,  2,161,161,  2,  2,  2,170,170,170,170,170,170,
+  170,170,170,170,170,170,  2,  2,  2,  2,110,110,110,110,110,110,
+  110,110,110,110,110,110,110,110,110,  2,110,110,110,110,110,110,
+    2,  2, 19, 19, 19, 19, 19, 19,  2, 19, 19,  2, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  2,  2,  2,  2,  2, 47, 47, 47, 47, 47, 47,
+    2,  2, 47,  2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+   47, 47, 47, 47, 47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,
+    2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+    2, 81,120,120,120,120,120,120,120,120,116,116,116,116,116,116,
+  116,116,116,116,116,116,116,116,116,  2,  2,  2,  2,  2,  2,  2,
+    2,116,128,128,128,128,128,128,128,128,128,128,128,  2,128,128,
+    2,  2,  2,  2,  2,128,128,128,128,128, 66, 66, 66, 66, 66, 66,
+   66, 66, 66, 66, 66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72,
+   72, 72, 72, 72,  2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 98, 98,
+   98, 98, 97, 97, 97, 97, 97, 97, 97, 97,  2,  2,  2,  2, 97, 97,
+   97, 97,  2,  2, 97, 97, 97, 97, 97, 97, 57, 57, 57, 57,  2, 57,
+   57,  2,  2,  2,  2,  2, 57, 57, 57, 57, 57, 57, 57, 57,  2, 57,
+   57, 57,  2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+   57, 57, 57, 57, 57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,
+    2, 57, 57,  2,  2,  2,  2,  2,  2,  2, 88, 88, 88, 88, 88, 88,
+   88, 88,117,117,117,117,117,117,117,117,112,112,112,112,112,112,
+  112,112,112,112,112,112,112,112,112,  2,  2,  2,  2,112,112,112,
+  112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+    2,  2,  2, 78, 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83,
+   83, 83, 83, 83, 83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82,
+   82, 82, 82, 82, 82,  2,  2,  2,  2,  2,122,122,122,122,122,122,
+  122,122,122,122,  2,  2,  2,  2,  2,  2,  2,122,122,122,122,  2,
+    2,  2,  2,122,122,122,122,122,122,122, 89, 89, 89, 89, 89, 89,
+   89, 89, 89,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,130,130,
+  130,130,130,130,130,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,
+  130,130,144,144,144,144,144,144,144,144,144,144,  2,  2,  2,  2,
+    2,  2,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+    2,  2,  2,165,165,165,165,165,165,165,  2,  2,  2,  2,  2,  2,
+  165,165,156,156,156,156,156,156,156,156,156,156,  2,156,156,156,
+    2,  2,156,156,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  2,
+    2,  2,  2,  2,  2,  2,  3,  3,  3,  3,147,147,147,147,147,147,
+  147,147,148,148,148,148,148,148,148,148,148,148,  2,  2,  2,  2,
+    2,  2,158,158,158,158,158,158,158,158,158,158,  2,  2,  2,  2,
+    2,  2,153,153,153,153,153,153,153,153,153,153,153,153,  2,  2,
+    2,  2,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+  149,  2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+    2,  2,  2,  2, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2,  2,  2,
+    2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2, 85,  2,  2,101,101,101,101,101,101,
+  101,101,101,  2,  2,  2,  2,  2,  2,  2,101,101,  2,  2,  2,  2,
+    2,  2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,  2,
+   96, 96,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,  2,100,100,100,100,100,100,100,100,  2, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36,  2,  2,  2,108,108,108,108,108,108,
+  108,108,108,108,  2,108,108,108,108,108,108,108,  2,  2,  2,  2,
+    2,  2,129,129,129,129,129,129,129,  2,129,  2,129,129,129,129,
+    2,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+    2,129,129,129,  2,  2,  2,  2,  2,  2,109,109,109,109,109,109,
+  109,109,109,109,109,  2,  2,  2,  2,  2,109,109,  2,  2,  2,  2,
+    2,  2,107,107,107,107,  2,107,107,107,107,107,107,107,107,  2,
+    2,107,107,  2,  2,107,107,107,107,107,107,107,107,107,107,107,
+  107,107,107,  2,107,107,107,107,107,107,107,  2,107,107,  2,107,
+  107,107,107,107,  2,  1,107,107,107,107,107,  2,  2,107,107,107,
+    2,  2,107,  2,  2,  2,  2,  2,  2,107,  2,  2,  2,  2,  2,107,
+  107,107,107,107,107,107,  2,  2,107,107,107,107,107,107,107,  2,
+    2,  2,171,171,171,171,171,171,171,171,171,171,  2,171,  2,  2,
+  171,  2,171,171,171,171,171,171,  2,171,171,  2,171,  2,  2,171,
+    2,171,171,171,171,  2,171,171,171,171,171,  2,  2,  2,  2,  2,
+    2,  2,  2,171,171,  2,  2,  2,  2,  2,137,137,137,137,137,137,
+  137,137,137,137,137,137,  2,137,137,137,137,137,  2,  2,  2,  2,
+    2,  2,124,124,124,124,124,124,124,124,124,124,  2,  2,  2,  2,
+    2,  2,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+    2,  2,114,114,114,114,114,114,114,114,114,114,114,114,114,  2,
+    2,  2,114,114,  2,  2,  2,  2,  2,  2, 32, 32, 32, 32, 32,  2,
+    2,  2,102,102,102,102,102,102,102,102,102,102,  2,  2,  2,  2,
+    2,  2, 33, 33, 33, 33,  2,  2,  2,  2,126,126,126,126,126,126,
+  126,126,126,126,126,  2,  2,126,126,126,126,126,126,126,  2,  2,
+    2,  2,126,126,126,126,126,126,126,  2,142,142,142,142,142,142,
+  142,142,142,142,142,142,  2,  2,  2,  2,125,125,125,125,125,125,
+  125,125,125,125,125,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,125,154,154,154,154,154,154,154,  2,  2,154,  2,  2,154,154,
+  154,154,154,154,154,154,  2,154,154,  2,154,154,154,154,154,154,
+  154,154,154,154,154,154,154,154,  2,154,154,  2,  2,154,154,154,
+  154,154,154,154,  2,  2,  2,  2,  2,  2,150,150,150,150,150,150,
+  150,150,  2,  2,150,150,150,150,150,150,150,150,150,150,150,  2,
+    2,  2,141,141,141,141,141,141,141,141,140,140,140,140,140,140,
+  140,140,140,140,140,  2,  2,  2,  2,  2,121,121,121,121,121,121,
+  121,121,121,  2,  2,  2,  2,  2,  2,  2,  7,  7,  2,  2,  2,  2,
+    2,  2,169,169,169,169,169,169,169,169,169,169,  2,  2,  2,  2,
+    2,  2,133,133,133,133,133,133,133,133,133,  2,133,133,133,133,
+  133,133,133,133,133,133,133,133,133,  2,133,133,133,133,133,133,
+    2,  2,133,133,133,133,133,  2,  2,  2,134,134,134,134,134,134,
+  134,134,  2,  2,134,134,134,134,134,134,  2,134,134,134,134,134,
+  134,134,134,134,134,134,134,134,134,  2,138,138,138,138,138,138,
+  138,  2,138,138,  2,138,138,138,138,138,138,138,138,138,138,138,
+  138,138,  2,  2,138,  2,138,138,  2,138,138,138,  2,  2,  2,  2,
+    2,  2,143,143,143,143,143,143,  2,143,143,  2,143,143,143,143,
+  143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+  143,  2,143,143,  2,143,143,143,143,143,143,  2,  2,  2,  2,  2,
+    2,  2,143,143,  2,  2,  2,  2,  2,  2,145,145,145,145,145,145,
+  145,145,145,  2,  2,  2,  2,  2,  2,  2,163,163,163,163,163,163,
+  163,163,163,  2,163,163,163,163,163,163,163,163,163,  2,  2,  2,
+  163,163,163,163,163,  2,  2,  2,  2,  2, 86,  2,  2,  2,  2,  2,
+    2,  2, 22, 22,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,  2,  2,  2,  2,
+    2,  2, 63, 63, 63, 63, 63, 63, 63,  2, 63, 63, 63, 63, 63,  2,
+    2,  2, 63, 63, 63, 63,  2,  2,  2,  2,157,157,157,157,157,157,
+  157,157,157,157,157,  2,  2,  2,  2,  2, 80, 80, 80, 80, 80, 80,
+   80, 80, 80, 80, 80, 80, 80, 80,  2,  2, 80, 80, 80,  2,  2,  2,
+    2,  2,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+  127,  2,166,166,166,166,166,166,166,166,166,166,  2,  2,  2,  2,
+    2,  2, 79,  2,  2,  2,  2,  2,  2,  2,115,115,115,115,115,115,
+  115,115,115,115,115,115,115,115,115,  2,115,115,  2,  2,  2,  2,
+  115,115,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+  159,  2,159,159,  2,  2,  2,  2,  2,  2,103,103,103,103,103,103,
+  103,103,103,103,103,103,103,103,  2,  2,119,119,119,119,119,119,
+  119,119,119,119,119,119,119,119,  2,  2,119,119,  2,119,119,119,
+  119,119,  2,  2,  2,  2,  2,119,119,119,167,167,167,167,167,167,
+  167,167,167,167,  2,  2,  2,  2,  2,  2,146,146,146,146,146,146,
+  146,146,146,146,146,  2,  2,  2,  2,  2, 99, 99, 99, 99, 99, 99,
+   99, 99, 99, 99, 99,  2,  2,  2,  2, 99,  2,  2,  2,  2,  2,  2,
+    2, 99,136,139, 13, 13,155,  2,  2,  2,136,136,136,136,136,136,
+  136,136,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,155,136,  2,  2,  2,  2,  2,
+    2,  2, 17, 17, 17, 17,  2, 17, 17, 17, 17, 17, 17, 17,  2, 17,
+   17,  2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17,  2,  2,  2,
+    2,  2,  2,  2, 15,  2,  2,  2,  2,  2, 15, 15, 15,  2,  2, 17,
+    2,  2,  2,  2,  2,  2, 17, 17, 17, 17,139,139,139,139,139,139,
+  139,139,139,139,139,139,  2,  2,  2,  2,105,105,105,105,105,105,
+  105,105,105,105,105,  2,  2,  2,  2,  2,105,105,105,105,105,  2,
+    2,  2,105,  2,  2,  2,  2,  2,  2,  2,105,105,  2,  2,105,105,
+  105,105,  1,  1,  1,  1,  1,  1,  2,  2,  0,  0,  0,  0,  0,  0,
+    0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
+    1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  0,  0,
+    0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  2,  2,  0,  2,  2,  0,
+    0,  2,  2,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  2,  0,
+    0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  2,  2,  0,
+    0,  0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  2,
+    0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,
+    0,  0,131,131,131,131,131,131,131,131,131,131,131,131,  2,  2,
+    2,  2,  2,  2,  2,131,131,131,131,131,  2,131,131,131,131,131,
+  131,131,  2,  2,  2,  2,  2, 19, 19, 19, 56, 56, 56, 56, 56, 56,
+   56,  2, 56,  2,  2, 56, 56, 56, 56, 56, 56, 56,  2, 56, 56,  2,
+   56, 56, 56, 56, 56,  2,  2,  2,  2,  2,  6,  6,  6,  6,  6,  6,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  6,151,151,151,151,151,151,
+  151,151,151,151,151,151,151,  2,  2,  2,151,151,151,151,151,151,
+    2,  2,151,151,  2,  2,  2,  2,151,151,160,160,160,160,160,160,
+  160,160,160,160,160,160,160,160,160,  2,152,152,152,152,152,152,
+  152,152,152,152,  2,  2,  2,  2,  2,152,164,164,164,164,164,164,
+  164,164,164,164,  2,  2,  2,  2,  2,  2,168,168,168,168,168,168,
+  168,168,168,168,168,  2,  2,  2,  2,168, 30, 30, 30, 30,  2, 30,
+   30,  2,113,113,113,113,113,113,113,113,113,113,113,113,113,  2,
+    2,113,113,113,113,113,113,113,113,  2,132,132,132,132,132,132,
+  132,132,132,132,132,132,  2,  2,  2,  2,132,132,  2,  2,  2,  2,
+  132,132,  3,  3,  3,  3,  2,  3,  3,  3,  2,  3,  3,  2,  3,  2,
+    2,  3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,
+    3,  3,  2,  3,  2,  3,  2,  2,  2,  2,  2,  2,  3,  2,  2,  2,
+    2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  2,  3,  2,  3,  2,  3,
+    2,  3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  3,  2,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  3,  3,  3,  2,  3,
+    3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    0,  0, 15,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  2,
+    2,  0,  0,  0,  0,  0,  0,  2,  2,  0, 13,  2,  2,  2,  2,  2,
+    2,  2, 13, 13, 13,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,
+    2,  2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  9,  9,  9, 10,
+    9, 11, 12, 13,  9,  9,  9, 14,  9,  9, 15,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 16, 17,  9,  9,  9,  9,
-   18,  9,  9,  9,  9,  9, 19, 20, 21,  9, 22,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 16, 17,
+    9,  9,  9,  9, 18,  9,  9,  9,  9,  9, 19, 20, 21,  9, 22,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 23,  9,
-    9,  9,  9,  9, 24,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9, 23,  9,  9,  9,  9,  9, 24,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 25,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 25,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
@@ -1807,65 +1916,66 @@
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 26, 27,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,
-    9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 26, 27,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  8,  9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0,
+   31, 32,  0, 33,  0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0, 31, 32,  0, 33,
-    0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 40,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0,  0,  0,
+    0,  0, 40,  0,  0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  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, 43, 44,
-    0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,  0,  0,  0, 48,
-    0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,  0,  0,  0,  0,
-   54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,  0,  0,  0,  0,
-   56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,  0,  0, 66,  0,
+    0,  0, 43, 44,  0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,
+    0,  0,  0, 48,  0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,
+    0,  0,  0,  0, 54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,
+    0,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,
+    0,  0, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 67, 68,  0, 69,
-   70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74,
-   75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
-   91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104,  0,
-    0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,108,  0,109,  0,
-  110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,  0,  0,116,  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,117,  0,  0,  0,  0,  0,  0,
+   67, 68,  0, 69, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+   87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,
+  103,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,104,  0,  0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,
+  108,  0,109,  0,110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,
+    0,  0,116,  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,117,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-  118,119,120,121,  0,122,123,124,125,126,  0,127,  0,  0,  0,  0,
+    0,  0,  0,  0,118,119,120,121,  0,122,123,124,125,126,  0,127,
     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,128,129,130,131,
-  132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,
-  148,149,150,151,152,153,154,155,156,157,  0,  0,  0,158,159,160,
-  161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,162,  0,163,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,164,165,  0,  0,  0,  0,  0,  0,  0,166,  0,
+  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+  144,145,146,147,148,149,150,151,152,153,154,155,156,157,  0,  0,
+    0,158,159,160,161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,162,  0,163,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,164,165,  0,  0,  0,  0,  0,
+    0,  0,166,  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,
-  167,  0,  0,  0,168,169,  0,  0,170,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,171,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,172,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,173,
+    0,  0,  0,  0,167,  0,  0,  0,168,169,  0,  0,170,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,171,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,172,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,174,  0,
+    0,  0,  0,173,  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,174,  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,175,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,175,  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,176,177,  0,  0,  0,  0,178,179,  0,  0,  0,180,181,182,183,
-  184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,
-  200,201,202,203,204,205,206,207,208,209,210,211,212,213,  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,  1,  2,  3,  4,
+    0,  0,  0,  0,  0,176,177,  0,  0,  0,  0,178,179,  0,  0,  0,
+  180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,
+  196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,
+  212,213,  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,  1,  2,  3,  4,
 };
-static const uint16_t _hb_ucd_u16[10400]=
+static const uint16_t _hb_ucd_u16[11168]=
 {
      0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
     13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
@@ -1888,6 +1998,7 @@
     48,  48,  48,  48, 168, 169,  48,  48, 168,  48,  48, 170, 171, 172,  48,  48,
     48, 171,  48,  48,  48, 173, 174, 175,  48, 176,   9,   9,   9,   9,   9, 177,
    178,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48, 179,  48, 180, 181,  48,  48,  48,  48, 182, 183,
     48, 184,  48, 185,  48, 186, 187, 188,  48,  48,  48, 189, 190, 191, 192, 193,
    194, 192,  48,  48, 195,  48,  48, 196, 197,  48, 198,  48,  48,  48,  48, 199,
@@ -1908,6 +2019,7 @@
    209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279,
    209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
    279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302,
+   279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
    209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209,
      9,   9,   9,  11,  11,  11, 306, 307,  13,  13,  13,  13,  13,  13, 308, 309,
     11,  11, 310,  48,  48,  48, 311, 312,  48, 313, 314, 314, 314, 314,  32,  32,
@@ -1916,9 +2028,15 @@
    324, 325, 326, 327, 136,  48,  48,  48,  48, 328, 178,  48,  48,  48,  48, 329,
    330,  48,  48, 136,  48,  48,  48,  48, 200, 331,  48,  48, 209, 209, 332,  48,
    209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209,
+   209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 209, 209, 209, 209,
     48, 337,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48, 151, 209, 209, 209, 338,  48,  48, 229,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
    339,  48, 340, 140,  13,  13, 341, 342,  13, 343,  48,  48,  48,  48, 344, 345,
     31, 346, 347, 348,  13,  13,  13, 349, 350, 351, 352, 353, 354, 355, 140, 356,
    357,  48, 358, 359,  48,  48,  48, 360, 361,  48,  48, 362, 363, 192,  32, 364,
@@ -1925,11 +2043,17 @@
     64,  48, 365,  48, 366, 367,  48, 151,  76,  48,  48, 368, 369, 370, 371, 372,
     48,  48, 373, 374, 375, 376,  48, 377,  48,  48,  48, 378, 379, 380, 381, 382,
    383, 384, 314,  11,  11, 385, 386,  11,  11,  11,  11,  11,  48,  48, 387, 192,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 388,  48, 389,  48,  48, 206,
    390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
+   390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
    391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
+   391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
+   391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48, 204,  48,  48,  48,  48,  48,  48, 207, 140, 140,
    392, 393, 394, 395, 396,  48,  48,  48,  48,  48,  48, 397, 398, 399,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48, 400, 209,  48,  48,  48,  48, 401,  48,  48, 402, 140, 140, 403,
     32, 404,  32, 405, 406, 407, 408, 409,  48,  48,  48,  48,  48,  48,  48, 410,
    411,   2,   3,   4,   5, 412, 413, 414,  48, 415,  48, 200, 416, 417, 418, 419,
@@ -1939,6 +2063,7 @@
     48,  48, 431,  48, 432,  48,  48, 433,  48, 434,  48,  48, 435, 436, 140, 140,
      9,   9, 437,  11,  11,  48,  48,  48,  48, 204, 192,   9,   9, 438,  11, 439,
     48,  48, 440,  48,  48,  48, 441, 442, 442, 443, 444, 445,  48,  48,  48, 388,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48, 313,  48, 199, 440, 140, 446,  27,  27, 447, 140, 140, 140, 140,
    448,  48,  48, 449,  48, 450,  48, 451,  48, 200, 452, 140, 140, 140,  48, 453,
     48, 454,  48, 455, 140, 140, 140, 140,  48,  48,  48, 456, 271, 457, 271, 271,
@@ -1964,28 +2089,42 @@
    567,  48,  48, 568, 569, 192, 570,  48, 571, 572, 192, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,  48, 573,
    574, 115,  48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48, 207, 140, 140, 140, 140, 140, 140,
    272, 272, 272, 272, 272, 272, 581, 582,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140,  48,  48,  48,  48,  48,  48, 583,
     48,  48,  48, 584, 585, 586,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  71,
     48,  48,  48,  48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
     48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
     48,  48,  48, 196,  48, 200, 370,  48,  48,  48,  48, 200, 192,  48, 204, 589,
     48,  48,  48, 590, 591, 592, 593, 594,  48, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 595,  48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140,   9,   9,  11,  11, 271, 597, 140, 140, 140, 140, 140, 140,
     48,  48,  48,  48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 440,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 199, 140, 605,
    196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48, 607, 608, 140, 609, 610,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 206,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
     48,  48,  48,  48,  48,  48,  71, 151, 196, 611, 612, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192,
+   209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
    209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140,
     32,  32, 613,  32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140,
    209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323,
@@ -1996,13 +2135,19 @@
    631, 632,  11, 633, 634, 635, 636,   9, 637,  11,   9, 622,  11, 623, 624,  11,
    241,   9, 626, 636,   9, 637,  11,   9, 622,  11, 638,   9, 639, 640, 641, 642,
     11, 643,   9, 644, 645, 646, 647,  11, 648,   9, 649,  11, 650, 538, 538, 538,
+   209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+   209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
     32,  32,  32, 651,  32,  32, 652, 653, 654, 655,  45, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    659, 660, 661,  27,  27,  27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140,
     48,  48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140,  48, 666, 140,  48,  48, 667, 668,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,  48, 669, 192,
    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,  48, 587, 670,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 672, 614, 140, 140,
      9,   9, 626,  11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
@@ -2009,6 +2154,7 @@
    140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140,
    503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    678,  48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
    209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323,
    690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209,
    693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140,
@@ -2016,20 +2162,32 @@
    209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426,
    209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427,
    688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140,
+   209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
    209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694,
    209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 140, 140,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48, 207,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48, 204,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 481,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 100,  48,
     48,  48,  48,  48,  48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
     48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+   140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  71,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
     48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 140, 140, 140, 140, 140,
    704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140,
     32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 140,
+   391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
    391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705,
+   391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
    391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706,
      0,   1,   2,   3,   4,   4,   4,   4,   4,   4,   5,   6,   7,   8,   9,  10,
     11,  11,  12,  11,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
@@ -2537,11 +2695,11 @@
 
 static inline uint8_t _hb_ucd_gc (unsigned u)
 {
-  return u<1114110 ? _hb_ucd_u8[6472u+(((_hb_ucd_u8[816u+(((_hb_ucd_u16[((_hb_ucd_u8[272u+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15))])<<4)+((u>>1>>3)&15)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2;
+  return u<1114110 ? _hb_ucd_u8[7832u+((_hb_ucd_u8[2176u+((_hb_ucd_u16[((_hb_ucd_u8[((((((u)>>1))>>3))>>5)])<<5)+((((((u)>>1))>>3))&31)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2;
 }
 static inline uint8_t _hb_ucd_ccc (unsigned u)
 {
-  return u<125259 ? _hb_ucd_u8[8504u+(((_hb_ucd_u8[7936u+(((_hb_ucd_u8[7460u+(((_hb_ucd_u8[7100u+(((_hb_ucd_u8[6854u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0;
+  return u<125259 ? _hb_ucd_u8[10268u+((_hb_ucd_u8[9180u+((_hb_ucd_u8[8460u+((_hb_ucd_u8[8214u+((((((u)>>2))>>3))>>4)])<<4)+((((((u)>>2))>>3))&15)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0;
 }
 static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i)
 {
@@ -2549,15 +2707,15 @@
 }
 static inline int16_t _hb_ucd_bmg (unsigned u)
 {
-  return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9252u+(((_hb_ucd_u8[9132u+(((_hb_ucd_b4(_hb_ucd_u8+9004u,u>>2>>3>>3))<<3)+((u>>2>>3)&7))])<<3)+((u>>2)&7))])<<2)+((u)&3)] : 0;
+  return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[11016u+((_hb_ucd_u8[10896u+((_hb_ucd_b4(_hb_ucd_u8+10768u,((((((u)>>2))>>3))>>3)))<<3)+((((((u)>>2))>>3))&7)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0;
 }
 static inline uint8_t _hb_ucd_sc (unsigned u)
 {
-  return u<918000 ? _hb_ucd_u8[10486u+(((_hb_ucd_u16[3744u+(((_hb_ucd_u16[2624u+(((_hb_ucd_u8[9588u+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15))])<<3)+((u>>3)&7))])<<3)+((u)&7))] : 2;
+  return u<918000 ? _hb_ucd_u8[12250u+((_hb_ucd_u16[4512u+((_hb_ucd_u16[3392u+((_hb_ucd_u8[11352u+((((((u)>>3))>>3))>>4)])<<4)+((((((u)>>3))>>3))&15)])<<3)+((((u)>>3))&7)])<<3)+((u)&7)] : 2;
 }
 static inline uint16_t _hb_ucd_dm (unsigned u)
 {
-  return u<195102 ? _hb_ucd_u16[6976u+(((_hb_ucd_u8[16716u+(((_hb_ucd_u8[16334u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0;
+  return u<195102 ? _hb_ucd_u16[7744u+((_hb_ucd_u8[18480u+((_hb_ucd_u8[18098u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0;
 }
 
 
@@ -4284,11 +4442,11 @@
 
 static inline uint8_t _hb_ucd_gc (unsigned u)
 {
-  return u<1114110 ? _hb_ucd_u8[6472u+(((_hb_ucd_u8[816u+(((_hb_ucd_u16[((_hb_ucd_u8[272u+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15))])<<4)+((u>>1>>3)&15)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2;
+  return u<1114110 ? _hb_ucd_u8[6472u+((_hb_ucd_u8[816u+((_hb_ucd_u16[((_hb_ucd_u8[272u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>4))>>4)])<<4)+((((((((u)>>1))>>3))>>4))&15)])<<4)+((((((u)>>1))>>3))&15)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2;
 }
 static inline uint8_t _hb_ucd_ccc (unsigned u)
 {
-  return u<125259 ? _hb_ucd_u8[8504u+(((_hb_ucd_u8[7936u+(((_hb_ucd_u8[7460u+(((_hb_ucd_u8[7100u+(((_hb_ucd_u8[6854u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0;
+  return u<125259 ? _hb_ucd_u8[8504u+((_hb_ucd_u8[7936u+((_hb_ucd_u8[7460u+((_hb_ucd_u8[7100u+((_hb_ucd_u8[6854u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 0;
 }
 static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i)
 {
@@ -4296,15 +4454,15 @@
 }
 static inline int16_t _hb_ucd_bmg (unsigned u)
 {
-  return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9396u+(((_hb_ucd_u8[9164u+(((_hb_ucd_u8[9068u+(((_hb_ucd_b4(_hb_ucd_u8+9004u,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7))])<<3)+((u>>1>>2)&7))])<<2)+((u>>1)&3))])<<1)+((u)&1)] : 0;
+  return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9396u+((_hb_ucd_u8[9164u+((_hb_ucd_u8[9068u+((_hb_ucd_b4(_hb_ucd_u8+9004u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)])<<1)+((u)&1)] : 0;
 }
 static inline uint8_t _hb_ucd_sc (unsigned u)
 {
-  return u<918000 ? _hb_ucd_u8[10398u+(((_hb_ucd_u16[3952u+(((_hb_ucd_u16[2624u+(((_hb_ucd_u8[9870u+(((_hb_ucd_u8[9644u+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15))])<<3)+((u>>3>>2)&7))])<<2)+((u>>3)&3))])<<3)+((u)&7))] : 2;
+  return u<918000 ? _hb_ucd_u8[10398u+((_hb_ucd_u16[3952u+((_hb_ucd_u16[2624u+((_hb_ucd_u8[9870u+((_hb_ucd_u8[9644u+((((((((u)>>3))>>2))>>3))>>4)])<<4)+((((((((u)>>3))>>2))>>3))&15)])<<3)+((((((u)>>3))>>2))&7)])<<2)+((((u)>>3))&3)])<<3)+((u)&7)] : 2;
 }
 static inline uint16_t _hb_ucd_dm (unsigned u)
 {
-  return u<195102 ? _hb_ucd_u16[6244u+(((_hb_ucd_u8[16628u+(((_hb_ucd_u8[16246u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0;
+  return u<195102 ? _hb_ucd_u16[6244u+((_hb_ucd_u8[16628u+((_hb_ucd_u8[16246u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0;
 }
 
 
@@ -5507,11 +5665,11 @@
 
 static inline uint8_t _hb_ucd_gc (unsigned u)
 {
-  return u<1114112 ? _hb_ucd_u8[5208u+(((_hb_ucd_u8[1168u+(((_hb_ucd_u16[((_hb_ucd_u8[544u+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15))])<<3)+((u>>1>>3)&7)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2;
+  return u<1114112 ? _hb_ucd_u8[5208u+((_hb_ucd_u8[1168u+((_hb_ucd_u16[((_hb_ucd_u8[544u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>3))>>4)])<<4)+((((((((u)>>1))>>3))>>3))&15)])<<3)+((((((u)>>1))>>3))&7)])<<3)+((((u)>>1))&7)])<<1)+((u)&1)] : 2;
 }
 static inline uint8_t _hb_ucd_ccc (unsigned u)
 {
-  return u<125259 ? _hb_ucd_u8[7206u+(((_hb_ucd_u8[6638u+(((_hb_ucd_u8[6162u+(((_hb_ucd_u8[5802u+(((_hb_ucd_u8[5556u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0;
+  return u<125259 ? _hb_ucd_u8[7206u+((_hb_ucd_u8[6638u+((_hb_ucd_u8[6162u+((_hb_ucd_u8[5802u+((_hb_ucd_u8[5556u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 0;
 }
 static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i)
 {
@@ -5519,15 +5677,15 @@
 }
 static inline int16_t _hb_ucd_bmg (unsigned u)
 {
-  return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8098u+(((_hb_ucd_u8[7866u+(((_hb_ucd_u8[7770u+(((_hb_ucd_b4(_hb_ucd_u8+7706u,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7))])<<3)+((u>>1>>2)&7))])<<2)+((u>>1)&3))])<<1)+((u)&1)] : 0;
+  return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8098u+((_hb_ucd_u8[7866u+((_hb_ucd_u8[7770u+((_hb_ucd_b4(_hb_ucd_u8+7706u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)])<<1)+((u)&1)] : 0;
 }
 static inline uint8_t _hb_ucd_sc (unsigned u)
 {
-  return u<918016 ? _hb_ucd_u8[11464u+(((_hb_ucd_u8[10472u+(((_hb_ucd_u8[9452u+(((_hb_ucd_u8[8764u+(((_hb_ucd_u8[8460u+(((_hb_ucd_u8[8346u+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15))])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 2;
+  return u<918016 ? _hb_ucd_u8[11464u+((_hb_ucd_u8[10472u+((_hb_ucd_u8[9452u+((_hb_ucd_u8[8764u+((_hb_ucd_u8[8460u+((_hb_ucd_u8[8346u+((((((((((u)>>2))>>2))>>2))>>3))>>4)])<<4)+((((((((((u)>>2))>>2))>>2))>>3))&15)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2;
 }
 static inline uint16_t _hb_ucd_dm (unsigned u)
 {
-  return u<195102 ? _hb_ucd_u16[1656u+(((_hb_ucd_u8[12834u+(((_hb_ucd_u8[12452u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0;
+  return u<195102 ? _hb_ucd_u16[1656u+((_hb_ucd_u8[12834u+((_hb_ucd_u8[12452u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2025-08-21 07:53:07 UTC (rev 76107)
@@ -84,6 +84,27 @@
   }
   ~hb_vector_t () { fini (); }
 
+  template <unsigned n>
+  void
+  set_storage (Type (&array)[n])
+  {
+    set_storage (array, n);
+  }
+
+  void
+  set_storage (Type *array, unsigned n)
+  {
+    if (unlikely (in_error ()))
+      return;
+
+    assert (n > 0);
+    assert (allocated == 0);
+    assert (length == 0);
+
+    arrayZ = array;
+    length = n;
+  }
+
   template <typename Iterable,
 	    hb_requires (hb_is_iterable (Iterable))>
   void extend (const Iterable &o)
@@ -139,11 +160,9 @@
     /* We allow a hack to make the vector point to a foreign array
      * by the user. In that case length/arrayZ are non-zero but
      * allocated is zero. Don't free anything. */
-    if (allocated)
-    {
-      shrink_vector (0);
+    shrink_vector (0);
+    if (is_owned ())
       hb_free (arrayZ);
-    }
     init ();
   }
 
@@ -260,6 +279,11 @@
     return new (p) Type (std::forward<Args> (args)...);
   }
 
+  bool is_owned () const
+  {
+    return allocated != 0 && allocated != -1;
+  }
+
   bool in_error () const { return allocated < 0; }
   void set_error ()
   {
@@ -272,26 +296,34 @@
     allocated = -(allocated + 1);
   }
 
-  template <typename T = Type,
-	    hb_enable_if (hb_is_trivially_copy_assignable(T))>
   Type *
-  realloc_vector (unsigned new_allocated, hb_priority<0>)
+  _realloc (unsigned new_allocated)
   {
     if (!new_allocated)
     {
-      hb_free (arrayZ);
+      if (is_owned ())
+	hb_free (arrayZ);
       return nullptr;
     }
+    if (!allocated && arrayZ)
+    {
+      /* If we have a non-null arrayZ but allocated is 0, then we are
+       * reallocating from a foreign array. */
+      Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
+      if (unlikely (!new_array))
+	return nullptr;
+      hb_memcpy ((void *) new_array, (const void *) arrayZ, length * sizeof (Type));
+      return new_array;
+    }
     return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
   }
-  template <typename T = Type,
-	    hb_enable_if (!hb_is_trivially_copy_assignable(T))>
   Type *
-  realloc_vector (unsigned new_allocated, hb_priority<0>)
+  _malloc_move (unsigned new_allocated)
   {
     if (!new_allocated)
     {
-      hb_free (arrayZ);
+      if (is_owned ())
+	hb_free (arrayZ);
       return nullptr;
     }
     Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
@@ -303,10 +335,26 @@
 	new_array[i] = std::move (arrayZ[i]);
 	arrayZ[i].~Type ();
       }
-      hb_free (arrayZ);
+      if (is_owned ())
+	hb_free (arrayZ);
     }
     return new_array;
   }
+
+  template <typename T = Type,
+	    hb_enable_if (hb_is_trivially_copy_assignable(T))>
+  Type *
+  realloc_vector (unsigned new_allocated, hb_priority<0>)
+  {
+    return _realloc (new_allocated);
+  }
+  template <typename T = Type,
+	    hb_enable_if (!hb_is_trivially_copy_assignable(T))>
+  Type *
+  realloc_vector (unsigned new_allocated, hb_priority<0>)
+  {
+    return _malloc_move (new_allocated);
+  }
   /* Specialization for types that can be moved using realloc(). */
   template <typename T = Type,
 	    hb_enable_if (T::realloc_move)>
@@ -313,12 +361,7 @@
   Type *
   realloc_vector (unsigned new_allocated, hb_priority<1>)
   {
-    if (!new_allocated)
-    {
-      hb_free (arrayZ);
-      return nullptr;
-    }
-    return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+    return _realloc (new_allocated);
   }
 
   template <typename T = Type,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/Cargo.toml
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/Cargo.toml	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/Cargo.toml	2025-08-21 07:53:07 UTC (rev 76107)
@@ -5,7 +5,8 @@
 
 [dependencies]
 skrifa = { version = "0.*", optional = true }
-harfrust = { version = "0.1.*", optional = true }
+harfrust = { version = "0.1.2", optional = true }
+# harfrust = { git = "https://github.com/harfbuzz/harfrust", optional = true }
 
 [lib]
 name = "harfbuzz_rust"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/shape.rs
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/shape.rs	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/rust/shape.rs	2025-08-21 07:53:07 UTC (rev 76107)
@@ -3,10 +3,11 @@
 use super::hb::*;
 
 use std::ffi::c_void;
+use std::mem::transmute;
 use std::ptr::null_mut;
 use std::str::FromStr;
 
-use harfrust::{FontRef, NormalizedCoord, ShaperData, ShaperInstance, Tag};
+use harfrust::{FontRef, NormalizedCoord, Shaper, ShaperData, ShaperInstance, Tag};
 
 pub struct HBHarfRustFaceData<'a> {
     face_blob: *mut hb_blob_t,
@@ -51,7 +52,8 @@
 }
 
 pub struct HBHarfRustFontData {
-    shaper_instance: ShaperInstance,
+    shaper_instance: Box<ShaperInstance>,
+    shaper: Shaper<'static>,
 }
 
 fn font_to_shaper_instance(font: *mut hb_font_t, font_ref: &FontRef<'_>) -> ShaperInstance {
@@ -74,9 +76,19 @@
     let face_data = face_data as *const HBHarfRustFaceData;
 
     let font_ref = &(*face_data).font_ref;
-    let shaper_instance = font_to_shaper_instance(font, font_ref);
+    let shaper_instance = Box::new(font_to_shaper_instance(font, font_ref));
 
-    let hr_font_data = Box::new(HBHarfRustFontData { shaper_instance });
+    let shaper_instance_ref = &*(&*shaper_instance as *const _);
+    let shaper = (*face_data)
+        .shaper_data
+        .shaper(font_ref)
+        .instance(Some(shaper_instance_ref))
+        .build();
+
+    let hr_font_data = Box::new(HBHarfRustFontData {
+        shaper_instance,
+        shaper: transmute::<harfrust::Shaper<'_>, harfrust::Shaper<'_>>(shaper),
+    });
     let hr_font_data_ptr = Box::into_raw(hr_font_data);
 
     hr_font_data_ptr as *mut c_void
@@ -113,16 +125,12 @@
 #[no_mangle]
 pub unsafe extern "C" fn _hb_harfrust_shape_plan_create_rs(
     font_data: *const c_void,
-    face_data: *const c_void,
     script: hb_script_t,
     language: hb_language_t,
     direction: hb_direction_t,
 ) -> *mut c_void {
     let font_data = font_data as *const HBHarfRustFontData;
-    let face_data = face_data as *const HBHarfRustFaceData;
 
-    let font_ref = &(*face_data).font_ref;
-
     let script = harfrust::Script::from_iso15924_tag(Tag::from_u32(script));
     let language = hb_language_to_hr_language(language);
     let direction = match direction {
@@ -133,14 +141,9 @@
         _ => harfrust::Direction::Invalid,
     };
 
-    let shaper = (*face_data)
-        .shaper_data
-        .shaper(font_ref)
-        .instance(Some(&(*font_data).shaper_instance))
-        .build();
+    let shaper = &(*font_data).shaper;
 
-    let hr_shape_plan =
-        harfrust::ShapePlan::new(&shaper, direction, script, language.as_ref(), &[]);
+    let hr_shape_plan = harfrust::ShapePlan::new(shaper, direction, script, language.as_ref(), &[]);
     let hr_shape_plan = Box::new(hr_shape_plan);
     Box::into_raw(hr_shape_plan) as *mut c_void
 }
@@ -223,6 +226,8 @@
     let count = hb_buffer_get_length(buffer);
     let infos = hb_buffer_get_glyph_infos(buffer, null_mut());
 
+    hr_buffer.reserve(count as usize);
+
     for i in 0..count {
         let info = &*infos.add(i as usize);
         let unicode = info.codepoint;
@@ -233,12 +238,16 @@
     let ptem = hb_font_get_ptem(font);
     let ptem = if ptem > 0.0 { Some(ptem) } else { None };
 
-    let shaper = (*face_data)
-        .shaper_data
-        .shaper(font_ref)
-        .instance(Some(&(*font_data).shaper_instance))
-        .point_size(ptem)
-        .build();
+    let shaper = if ptem.is_some() {
+        (*face_data)
+            .shaper_data
+            .shaper(font_ref)
+            .instance(Some(&(*font_data).shaper_instance))
+            .point_size(ptem)
+            .build()
+    } else {
+        (*font_data).shaper.clone()
+    };
 
     let features = if features.is_null() {
         Vec::new()
@@ -275,19 +284,32 @@
         hb_buffer_content_type_t_HB_BUFFER_CONTENT_TYPE_GLYPHS,
     );
     hb_buffer_set_length(buffer, count as u32);
-    if hb_buffer_get_length(buffer) != count as u32 {
+    let mut count_out: u32 = 0;
+    let infos = hb_buffer_get_glyph_infos(buffer, &mut count_out);
+    let positions = hb_buffer_get_glyph_positions(buffer, null_mut());
+    if count != count_out as usize {
         return false as hb_bool_t;
     }
-    let infos = hb_buffer_get_glyph_infos(buffer, null_mut());
-    let positions = hb_buffer_get_glyph_positions(buffer, null_mut());
 
     let mut x_scale: i32 = 0;
     let mut y_scale: i32 = 0;
     hb_font_get_scale(font, &mut x_scale, &mut y_scale);
     let upem = shaper.units_per_em();
-    let x_scale = x_scale as f32 / upem as f32;
-    let y_scale = y_scale as f32 / upem as f32;
+    let upem = if upem > 0 { upem } else { 1000 };
+    let x_mult = if x_scale < 0 {
+        -((-x_scale as i64) << 16)
+    } else {
+        (x_scale as i64) << 16
+    } / upem as i64;
+    let y_mult = if y_scale < 0 {
+        -((-y_scale as i64) << 16)
+    } else {
+        (y_scale as i64) << 16
+    } / upem as i64;
 
+    let em_mult =
+        |v: i32, mult: i64| -> hb_position_t { ((v as i64 * mult + 32768) >> 16) as hb_position_t };
+
     for (i, (hr_info, hr_pos)) in glyphs
         .glyph_infos()
         .iter()
@@ -308,10 +330,10 @@
         if hr_info.safe_to_insert_tatweel() {
             info.mask |= hb_glyph_flags_t_HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL;
         }
-        pos.x_advance = (hr_pos.x_advance as f32 * x_scale + 0.5).floor() as hb_position_t;
-        pos.y_advance = (hr_pos.y_advance as f32 * y_scale + 0.5).floor() as hb_position_t;
-        pos.x_offset = (hr_pos.x_offset as f32 * x_scale + 0.5).floor() as hb_position_t;
-        pos.y_offset = (hr_pos.y_offset as f32 * y_scale + 0.5).floor() as hb_position_t;
+        pos.x_advance = em_mult(hr_pos.x_advance, x_mult);
+        pos.y_advance = em_mult(hr_pos.y_advance, y_mult);
+        pos.x_offset = em_mult(hr_pos.x_offset, x_mult);
+        pos.y_offset = em_mult(hr_pos.y_offset, y_mult);
     }
 
     let hr_buffer = glyphs.clear();

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2025-08-20 23:42:00 UTC (rev 76106)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2025-08-21 07:53:07 UTC (rev 76107)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [11.4.1])
+m4_define([harfbuzz_version], [11.4.2])



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