From b1b2f62915b1f231a673dcf03eec0fe93178033e Mon Sep 17 00:00:00 2001 From: Andrew Hughes Date: Tue, 3 Mar 2026 01:26:31 +0000 Subject: [PATCH] Include backports of libpng & harfbuzz updates ahead of 25.0.3 - Add JDK-8375063 libpng 1.6.54 ahead of 25.0.3 - Add JDK-8375057 harfbuzz 12.3.2 ahead of 25.0.3 - Add JDK-8377526 libpng 1.6.55 ahead of 25.0.3 - Bump libpng version to 1.6.55 following JDK-8375063 & JDK-8377526 - Bump harfbuzz version to 12.3.2 following JDK-8375057 Resolves: RHEL-146649 Resolves: RHEL-148327 Resolves: RHEL-148830 --- java-25-openjdk.spec | 26 +- jdk8375057-harfbuzz-12.3.2.patch | 31844 +++++++++++++++++++++++++++++ jdk8375063-libpng-1.6.54.patch | 4384 ++++ jdk8377526-libpng-1.6.55.patch | 248 + 4 files changed, 36499 insertions(+), 3 deletions(-) create mode 100644 jdk8375057-harfbuzz-12.3.2.patch create mode 100644 jdk8375063-libpng-1.6.54.patch create mode 100644 jdk8377526-libpng-1.6.55.patch diff --git a/java-25-openjdk.spec b/java-25-openjdk.spec index 6cd1389..2e2bb66 100644 --- a/java-25-openjdk.spec +++ b/java-25-openjdk.spec @@ -1392,6 +1392,15 @@ Patch1001: fips-%{featurever}u-%{fipsver}.patch # JDK-8372534: Update Libpng to 1.6.51 # Integrated in 25.0.3 Patch2001: jdk8372534-libpng-1.6.51.patch +# JDK-8375063: Update Libpng to 1.6.54 +# Integrated in 25.0.3 +Patch2002: jdk8375063-libpng-1.6.54.patch +# JDK-8375057: Update HarfBuzz to 12.3.2 +# Integrated in 25.0.3 +Patch2003: jdk8375057-harfbuzz-12.3.2.patch +# JDK-8377526: Update Libpng to 1.6.55 +# Integrated in 25.0.3 +Patch2004: jdk8377526-libpng-1.6.55.patch ############################################# # @@ -1483,13 +1492,13 @@ Provides: bundled(freetype) = 2.13.3 # Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h Provides: bundled(giflib) = 5.2.2 # Version in src/java.desktop/share/native/libharfbuzz/hb-version.h -Provides: bundled(harfbuzz) = 10.4.0 +Provides: bundled(harfbuzz) = 12.3.2 # Version in src/java.desktop/share/native/liblcms/lcms2.h Provides: bundled(lcms2) = 2.17.0 # Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h Provides: bundled(libjpeg) = 6b # Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h -Provides: bundled(libpng) = 1.6.51 +Provides: bundled(libpng) = 1.6.55 # Version in src/java.base/share/native/libzip/zlib/zlib.h Provides: bundled(zlib) = 1.3.1 %endif @@ -1925,8 +1934,11 @@ sh %{SOURCE12} %{top_level_dir_name} pushd %{top_level_dir_name} # Add crypto policy and FIPS support %patch -P1001 -p1 -# Add libpng update ahead of 25.0.3 +# Add libpng & harfbuzz updates ahead of 25.0.3 %patch -P2001 -p1 +%patch -P2002 -p1 +%patch -P2003 -p1 +%patch -P2004 -p1 popd # openjdk # Patch NSS adapter @@ -2604,7 +2616,15 @@ exit 0 * Tue Mar 03 2026 Andrew Hughes - 1:25.0.2.0.10-3 - Update FIPS patch to e55ada9353e to include the fix for the too restrictive provider lockdown - Fix FIPS issue list to represent the new 25u version +- Add JDK-8375063 libpng 1.6.54 ahead of 25.0.3 +- Add JDK-8375057 harfbuzz 12.3.2 ahead of 25.0.3 +- Add JDK-8377526 libpng 1.6.55 ahead of 25.0.3 +- Bump libpng version to 1.6.55 following JDK-8375063 & JDK-8377526 +- Bump harfbuzz version to 12.3.2 following JDK-8375057 - Resolves: RHEL-155000 +- Resolves: RHEL-146649 +- Resolves: RHEL-148327 +- Resolves: RHEL-148830 * Wed Feb 18 2026 Andrew Hughes - 1:25.0.2.0.10-2 - Bump rpmrelease for CentOS build diff --git a/jdk8375057-harfbuzz-12.3.2.patch b/jdk8375057-harfbuzz-12.3.2.patch new file mode 100644 index 0000000..08a6410 --- /dev/null +++ b/jdk8375057-harfbuzz-12.3.2.patch @@ -0,0 +1,31844 @@ +commit c8379fcc5dc7ac7edba673c3857258cb7fc12495 +Author: Andrew John Hughes +AuthorDate: Wed Feb 11 16:15:00 2026 +0000 +Commit: Andrew John Hughes +CommitDate: Wed Feb 11 16:15:00 2026 +0000 + + 8375057: Update HarfBuzz to 12.3.2 + + Backport-of: 4db0f7f29154d6618c63a30ef2a86267c842ebb3 + +diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md +index e0c40705ed6..3aa5ca841d6 100644 +--- a/src/java.desktop/share/legal/harfbuzz.md ++++ b/src/java.desktop/share/legal/harfbuzz.md +@@ -1,4 +1,4 @@ +-## Harfbuzz 11.2.0 ++## Harfbuzz 12.3.2 + + ### Harfbuzz License + +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh +index 73e6b4c305b..011b5ad5520 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh +@@ -104,7 +104,7 @@ public: + foreground (foreground_), + instancer (instancer_) + { +- if (font->is_synthetic ()) ++ if (font->is_synthetic) + { + font = hb_font_create_sub_font (font); + hb_font_set_synthetic_bold (font, 0, 0, true); +@@ -178,7 +178,10 @@ struct hb_colrv1_closure_context_t : + { glyphs->add (glyph_id); } + + void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers) +- { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); } ++ { ++ if (num_of_layers == 0) return; ++ layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); ++ } + + void add_palette_index (unsigned palette_index) + { palette_indices->add (palette_index); } +@@ -650,10 +653,10 @@ struct PaintColrLayers + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); +- return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex), +- HB_SERIALIZE_ERROR_INT_OVERFLOW)); + +- return_trace (true); ++ uint32_t first_layer_index = numLayers ? c->plan->colrv1_layers.get (firstLayerIndex) : 0; ++ return_trace (c->serializer->check_assign (out->firstLayerIndex, first_layer_index, ++ HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + + bool sanitize (hb_sanitize_context_t *c) const +@@ -1075,9 +1078,9 @@ struct PaintTranslate + float ddx = dx + c->instancer (varIdxBase, 0); + float ddy = dy + c->instancer (varIdxBase, 1); + +- bool p1 = c->funcs->push_translate (c->data, ddx, ddy); ++ c->funcs->push_translate (c->data, ddx, ddy); + c->recurse (this+src); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ +@@ -1124,9 +1127,9 @@ struct PaintScale + float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); + float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); + +- bool p1 = c->funcs->push_scale (c->data, sx, sy); ++ c->funcs->push_scale (c->data, sx, sy); + c->recurse (this+src); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ +@@ -1177,13 +1180,9 @@ struct PaintScaleAroundCenter + float tCenterX = centerX + c->instancer (varIdxBase, 2); + float tCenterY = centerY + c->instancer (varIdxBase, 3); + +- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); +- bool p2 = c->funcs->push_scale (c->data, sx, sy); +- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); ++ c->funcs->push_scale_around_center (c->data, sx, sy, tCenterX, tCenterY); + c->recurse (this+src); +- if (p3) c->funcs->pop_transform (c->data); +- if (p2) c->funcs->pop_transform (c->data); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ +@@ -1228,9 +1227,9 @@ struct PaintScaleUniform + TRACE_PAINT (this); + float s = scale.to_float (c->instancer (varIdxBase, 0)); + +- bool p1 = c->funcs->push_scale (c->data, s, s); ++ c->funcs->push_scale (c->data, s, s); + c->recurse (this+src); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ +@@ -1278,13 +1277,9 @@ struct PaintScaleUniformAroundCenter + float tCenterX = centerX + c->instancer (varIdxBase, 1); + float tCenterY = centerY + c->instancer (varIdxBase, 2); + +- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); +- bool p2 = c->funcs->push_scale (c->data, s, s); +- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); ++ c->funcs->push_scale_around_center (c->data, s, s, tCenterX, tCenterY); + c->recurse (this+src); +- if (p3) c->funcs->pop_transform (c->data); +- if (p2) c->funcs->pop_transform (c->data); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ +@@ -1328,9 +1323,9 @@ struct PaintRotate + TRACE_PAINT (this); + float a = angle.to_float (c->instancer (varIdxBase, 0)); + +- bool p1 = c->funcs->push_rotate (c->data, a); ++ c->funcs->push_rotate (c->data, a); + c->recurse (this+src); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ +@@ -1378,13 +1373,9 @@ struct PaintRotateAroundCenter + float tCenterX = centerX + c->instancer (varIdxBase, 1); + float tCenterY = centerY + c->instancer (varIdxBase, 2); + +- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); +- bool p2 = c->funcs->push_rotate (c->data, a); +- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); ++ c->funcs->push_rotate_around_center (c->data, a, tCenterX, tCenterY); + c->recurse (this+src); +- if (p3) c->funcs->pop_transform (c->data); +- if (p2) c->funcs->pop_transform (c->data); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ +@@ -1432,9 +1423,9 @@ struct PaintSkew + float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); + float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); + +- bool p1 = c->funcs->push_skew (c->data, sx, sy); ++ c->funcs->push_skew (c->data, sx, sy); + c->recurse (this+src); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ +@@ -1485,13 +1476,9 @@ struct PaintSkewAroundCenter + float tCenterX = centerX + c->instancer (varIdxBase, 2); + float tCenterY = centerY + c->instancer (varIdxBase, 3); + +- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); +- bool p2 = c->funcs->push_skew (c->data, sx, sy); +- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); ++ c->funcs->push_skew_around_center (c->data, sx, sy, tCenterX, tCenterY); + c->recurse (this+src); +- if (p3) c->funcs->pop_transform (c->data); +- if (p2) c->funcs->pop_transform (c->data); +- if (p1) c->funcs->pop_transform (c->data); ++ c->funcs->pop_transform (c->data); + } + + HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ +@@ -1626,7 +1613,7 @@ struct ClipBox + const ItemVarStoreInstancer &instancer) const + { + TRACE_SUBSET (this); +- switch (u.format) { ++ switch (u.format.v) { + case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION)); + case 2: return_trace (u.format2.subset (c, instancer)); + default:return_trace (c->default_return_value ()); +@@ -1635,7 +1622,7 @@ struct ClipBox + + void closurev1 (hb_colrv1_closure_context_t* c) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 2: u.format2.closurev1 (c); return; + default:return; + } +@@ -1644,9 +1631,9 @@ struct ClipBox + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); +@@ -1657,7 +1644,7 @@ struct ClipBox + const ItemVarStoreInstancer &instancer) const + { + ClipBoxData clip_box; +- switch (u.format) { ++ switch (u.format.v) { + case 1: + u.format1.get_clip_box (clip_box, instancer); + break; +@@ -1677,7 +1664,7 @@ struct ClipBox + + protected: + union { +- HBUINT8 format; /* Format identifier */ ++ struct { HBUINT8 v; } format; /* Format identifier */ + ClipBoxFormat1 format1; + ClipBoxFormat2 format2; + } u; +@@ -1857,9 +1844,9 @@ struct Paint + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.paintformat1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.paintformat2, std::forward (ds)...)); + case 3: return_trace (c->dispatch (u.paintformat3, std::forward (ds)...)); +@@ -1898,7 +1885,7 @@ struct Paint + + protected: + union { +- HBUINT8 format; ++ struct { HBUINT8 v; } format; + PaintColrLayers paintformat1; + NoVariable paintformat2; + Variable paintformat3; +@@ -2073,7 +2060,7 @@ struct delta_set_index_map_subset_plan_t + outer_bit_count = 1; + inner_bit_count = 1; + +- if (unlikely (!output_map.resize (map_count, false))) return false; ++ if (unlikely (!output_map.resize_dirty (map_count))) return false; + + for (unsigned idx = 0; idx < map_count; idx++) + { +@@ -2693,7 +2680,8 @@ struct COLR + { + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), +- hb_array (font->coords, font->num_coords)); ++ hb_array (font->coords, ++ font->has_nonzero_coords ? font->num_coords : 0)); + hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); + + hb_decycler_node_t node (c.glyphs_decycler); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh +index 51fc1b52af4..71417fdf3cf 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh +@@ -307,6 +307,7 @@ struct CPAL + if (first_color_to_layer_index.has (first_color_record_idx)) continue; + + first_color_index_for_layer.push (first_color_record_idx); ++ if (unlikely (!c->serializer->propagate_error (first_color_index_for_layer))) return_trace (false); + first_color_to_layer_index.set (first_color_record_idx, + first_color_index_for_layer.length - 1); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh +index 35d73c7b858..28678856373 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh +@@ -46,7 +46,7 @@ struct Coverage + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + CoverageFormat1_3 format1; + CoverageFormat2_4 format2; + #ifndef HB_NO_BEYOND_64K +@@ -55,7 +55,7 @@ struct Coverage + #endif + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + + #ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +@@ -63,9 +63,9 @@ struct Coverage + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) ++ switch (u.format.v) + { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); +@@ -86,7 +86,7 @@ struct Coverage + unsigned int get (hb_codepoint_t k) const { return get_coverage (k); } + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: return u.format1.get_coverage (glyph_id); + case 2: return u.format2.get_coverage (glyph_id); + #ifndef HB_NO_BEYOND_64K +@@ -97,18 +97,38 @@ struct Coverage + } + } + unsigned int get_coverage (hb_codepoint_t glyph_id, +- hb_ot_lookup_cache_t *cache) const ++ hb_ot_layout_mapping_cache_t *cache) const + { + unsigned coverage; +- if (cache && cache->get (glyph_id, &coverage)) return coverage; ++ if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; + coverage = get_coverage (glyph_id); +- if (cache) cache->set (glyph_id, coverage); ++ if (cache) { ++ if (coverage == NOT_COVERED) ++ cache->set_unchecked (glyph_id, cache->MAX_VALUE); ++ else if (likely (coverage < cache->MAX_VALUE)) ++ cache->set_unchecked (glyph_id, coverage); ++ } ++ return coverage; ++ } ++ ++ unsigned int get_coverage_binary (hb_codepoint_t glyph_id, ++ hb_ot_layout_binary_cache_t *cache) const ++ { ++ unsigned coverage; ++ if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; ++ coverage = get_coverage (glyph_id); ++ if (cache) { ++ if (coverage == NOT_COVERED) ++ cache->set_unchecked (glyph_id, cache->MAX_VALUE); ++ else ++ cache->set_unchecked (glyph_id, 0); ++ } + return coverage; + } + + unsigned get_population () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: return u.format1.get_population (); + case 2: return u.format2.get_population (); + #ifndef HB_NO_BEYOND_64K +@@ -140,11 +160,11 @@ struct Coverage + last = g; + if (g > max) max = g; + } +- u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2; ++ u.format.v = !unsorted && count <= num_ranges * 3 ? 1 : 2; + + #ifndef HB_NO_BEYOND_64K + if (max > 0xFFFFu) +- u.format += 2; ++ u.format.v += 2; + if (unlikely (max > 0xFFFFFFu)) + #else + if (unlikely (max > 0xFFFFu)) +@@ -154,7 +174,7 @@ struct Coverage + return_trace (false); + } + +- switch (u.format) ++ switch (u.format.v) + { + case 1: return_trace (u.format1.serialize (c, glyphs)); + case 2: return_trace (u.format2.serialize (c, glyphs)); +@@ -185,7 +205,7 @@ struct Coverage + + bool intersects (const hb_set_t *glyphs) const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: return u.format1.intersects (glyphs); + case 2: return u.format2.intersects (glyphs); +@@ -198,7 +218,7 @@ struct Coverage + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: return u.format1.intersects_coverage (glyphs, index); + case 2: return u.format2.intersects_coverage (glyphs, index); +@@ -212,7 +232,7 @@ struct Coverage + + unsigned cost () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); + #ifndef HB_NO_BEYOND_64K +@@ -228,7 +248,7 @@ struct Coverage + template + bool collect_coverage (set_t *glyphs) const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: return u.format1.collect_coverage (glyphs); + case 2: return u.format2.collect_coverage (glyphs); +@@ -244,7 +264,7 @@ struct Coverage + hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> + void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); + case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); +@@ -262,7 +282,7 @@ struct Coverage + iter_t (const Coverage &c_ = Null (Coverage)) + { + hb_memset (this, 0, sizeof (*this)); +- format = c_.u.format; ++ format = c_.u.format.v; + switch (format) + { + case 1: u.format1.init (c_.u.format1); return; +@@ -332,7 +352,7 @@ struct Coverage + } + iter_t __end__ () const + { +- iter_t it = {}; ++ iter_t it; + it.format = format; + switch (format) + { +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh +index 97ea51089ec..122326e3024 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh +@@ -41,11 +41,11 @@ struct CoverageFormat1_3 + { + friend struct Coverage; + +- protected: ++ public: + HBUINT16 coverageFormat; /* Format identifier--format = 1 */ + SortedArray16Of + glyphArray; /* Array of GlyphIDs--in numerical order */ +- public: ++ + DEFINE_SIZE_ARRAY (4, glyphArray); + + private: +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh +index 0c9bd09cbf7..8287c8d4d4d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh +@@ -40,7 +40,7 @@ struct CoverageFormat2_4 + { + friend struct Coverage; + +- protected: ++ public: + HBUINT16 coverageFormat; /* Format identifier--format = 2 */ + SortedArray16Of> + rangeRecord; /* Array of glyph ranges--ordered by +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh +index ceba37b0619..89e110990bc 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh +@@ -252,7 +252,7 @@ struct CaretValue + hb_codepoint_t glyph_id, + const ItemVariationStore &var_store) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: return u.format1.get_caret_value (font, direction); + case 2: return u.format2.get_caret_value (font, direction, glyph_id); + case 3: return u.format3.get_caret_value (font, direction, var_store); +@@ -263,9 +263,9 @@ struct CaretValue + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); +@@ -275,7 +275,7 @@ struct CaretValue + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: + case 2: + return; +@@ -289,9 +289,9 @@ struct CaretValue + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); +@@ -301,13 +301,13 @@ struct CaretValue + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + CaretValueFormat1 format1; + CaretValueFormat2 format2; + CaretValueFormat3 format3; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + struct LigGlyph +@@ -519,7 +519,7 @@ struct MarkGlyphSets + { + bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: return u.format1.covers (set_index, glyph_id); + default:return false; + } +@@ -528,7 +528,7 @@ struct MarkGlyphSets + template + void collect_coverage (hb_vector_t &sets) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: u.format1.collect_coverage (sets); return; + default:return; + } +@@ -537,7 +537,7 @@ struct MarkGlyphSets + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return; + default:return; + } +@@ -546,7 +546,7 @@ struct MarkGlyphSets + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); +- switch (u.format) { ++ switch (u.format.v) { + case 1: return_trace (u.format1.subset (c)); + default:return_trace (false); + } +@@ -555,9 +555,9 @@ struct MarkGlyphSets + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 1: return_trace (u.format1.sanitize (c)); + default:return_trace (true); + } +@@ -565,11 +565,11 @@ struct MarkGlyphSets + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + MarkGlyphSetsFormat1 format1; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + +@@ -977,7 +977,7 @@ struct GDEF + } + + #ifndef HB_NO_GDEF_CACHE +- table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests); ++ table->get_mark_glyph_sets ().collect_coverage (mark_glyph_sets); + #endif + } + ~accelerator_t () { table.destroy (); } +@@ -1002,18 +1002,34 @@ struct GDEF + + } + ++ HB_ALWAYS_INLINE + bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const + { + return + #ifndef HB_NO_GDEF_CACHE +- mark_glyph_set_digests[set_index].may_have (glyph_id) && ++ // We can access arrayZ directly because of sanitize_lookup_props() guarantee. ++ mark_glyph_sets.arrayZ[set_index].may_have (glyph_id) && + #endif +- table->mark_set_covers (set_index, glyph_id); ++ table->mark_set_covers (set_index, glyph_id) ++ ; ++ } ++ ++ unsigned sanitize_lookup_props (unsigned lookup_props) const ++ { ++#ifndef HB_NO_GDEF_CACHE ++ if (lookup_props & LookupFlag::UseMarkFilteringSet && ++ (lookup_props >> 16) >= mark_glyph_sets.length) ++ { ++ // Invalid mark filtering set index; unset the flag. ++ lookup_props &= ~LookupFlag::UseMarkFilteringSet; ++ } ++#endif ++ return lookup_props; + } + + hb_blob_ptr_t table; + #ifndef HB_NO_GDEF_CACHE +- hb_vector_t mark_glyph_set_digests; ++ hb_vector_t mark_glyph_sets; + mutable hb_cache_t<21, 3> glyph_props_cache; + static_assert (sizeof (glyph_props_cache) == 512, ""); + #endif +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh +index 7802e397f4c..1938803fa7c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh +@@ -13,20 +13,20 @@ struct Anchor + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + AnchorFormat1 format1; + AnchorFormat2 format2; + AnchorFormat3 format3; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); +@@ -38,7 +38,7 @@ struct Anchor + float *x, float *y) const + { + *x = *y = 0; +- switch (u.format) { ++ switch (u.format.v) { + case 1: u.format1.get_anchor (c, glyph_id, x, y); return; + case 2: u.format2.get_anchor (c, glyph_id, x, y); return; + case 3: u.format3.get_anchor (c, glyph_id, x, y); return; +@@ -49,7 +49,7 @@ struct Anchor + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); +- switch (u.format) { ++ switch (u.format.v) { + case 1: return_trace (bool (reinterpret_cast (u.format1.copy (c->serializer)))); + case 2: + if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) +@@ -66,7 +66,7 @@ struct Anchor + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: case 2: + return; + case 3: +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh +index 61bd90310a5..c49705bea0e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh +@@ -37,12 +37,12 @@ struct AnchorFormat3 + *x = font->em_fscale_x (xCoordinate); + *y = font->em_fscale_y (yCoordinate); + +- if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) ++ if ((font->x_ppem || font->has_nonzero_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + { + hb_barrier (); + *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); + } +- if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) ++ if ((font->y_ppem || font->has_nonzero_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + { + hb_barrier (); + *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); +@@ -91,10 +91,13 @@ struct AnchorFormat3 + } + } + +- /* in case that all axes are pinned or no variations after instantiation, +- * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ +- if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && +- y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) ++ ++ bool no_downgrade = (!xDeviceTable.is_null () && !(this+xDeviceTable).is_variation_device ()) || ++ x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || ++ y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || ++ (!yDeviceTable.is_null () && !(this+yDeviceTable).is_variation_device ()); ++ ++ if (!no_downgrade) + return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + + if (!c->serializer->embed (xDeviceTable)) return_trace (false); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh +index 9da9fff50ba..128ced6c176 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh +@@ -77,6 +77,13 @@ struct AnchorMatrix + + return_trace (true); + } ++ ++ bool offset_is_null (unsigned row, unsigned col, unsigned num_cols) const ++ { ++ if (unlikely (row >= rows || col >= num_cols)) return true; ++ auto &offset = matrixZ[row * num_cols + col]; ++ return offset.is_null (); ++ } + }; + + +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh +index 0105a9b8542..38a29dd9ed5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePos.hh +@@ -11,7 +11,7 @@ struct CursivePos + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + CursivePosFormat1 format1; + } u; + +@@ -19,9 +19,9 @@ struct CursivePos + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh +index 361aaed658a..f5a09e07d73 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh +@@ -50,8 +50,9 @@ struct EntryExitRecord + DEFINE_SIZE_STATIC (4); + }; + +-static void +-reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) { ++static inline void ++reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) ++{ + int chain = pos[i].attach_chain(), type = pos[i].attach_type(); + if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) + return; +@@ -130,7 +131,7 @@ struct CursivePosFormat1 + unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); + hb_barrier (); + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_input; + skippy_iter.reset_fast (buffer->idx); + unsigned unsafe_from; + if (unlikely (!skippy_iter.prev (&unsafe_from))) +@@ -229,8 +230,13 @@ struct CursivePosFormat1 + */ + reverse_cursive_minor_offset (pos, child, c->direction, parent); + +- pos[child].attach_type() = ATTACH_TYPE_CURSIVE; + pos[child].attach_chain() = (int) parent - (int) child; ++ if (pos[child].attach_chain() != (int) parent - (int) child) ++ { ++ pos[child].attach_chain() = 0; ++ goto overflow; ++ } ++ pos[child].attach_type() = ATTACH_TYPE_CURSIVE; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) + pos[child].y_offset = y_offset; +@@ -256,6 +262,7 @@ struct CursivePosFormat1 + i, j); + } + ++ overflow: + buffer->idx++; + return_trace (true); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh +index ce3f74d8c3b..b80f606f7b5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh +@@ -80,9 +80,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, + { + /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate + * offset of glyph they are attached to. */ +- int chain = pos[i].attach_chain(), type = pos[i].attach_type(); +- if (likely (!chain)) +- return; ++ int chain = pos[i].attach_chain(); ++ int type = pos[i].attach_type(); + + pos[i].attach_chain() = 0; + +@@ -94,7 +93,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, + if (unlikely (!nesting_level)) + return; + +- propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); ++ if (pos[j].attach_chain()) ++ propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); + + assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE)); + +@@ -110,17 +110,37 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, + pos[i].x_offset += pos[j].x_offset; + pos[i].y_offset += pos[j].y_offset; + +- assert (j < i); +- if (HB_DIRECTION_IS_FORWARD (direction)) +- for (unsigned int k = j; k < i; k++) { +- pos[i].x_offset -= pos[k].x_advance; +- pos[i].y_offset -= pos[k].y_advance; +- } +- else +- for (unsigned int k = j + 1; k < i + 1; k++) { +- pos[i].x_offset += pos[k].x_advance; +- pos[i].y_offset += pos[k].y_advance; +- } ++ // i is the position of the mark; j is the base. ++ if (j < i) ++ { ++ /* This is the common case: mark follows base. ++ * And currently the only way in OpenType. */ ++ if (HB_DIRECTION_IS_FORWARD (direction)) ++ for (unsigned int k = j; k < i; k++) { ++ pos[i].x_offset -= pos[k].x_advance; ++ pos[i].y_offset -= pos[k].y_advance; ++ } ++ else ++ for (unsigned int k = j + 1; k < i + 1; k++) { ++ pos[i].x_offset += pos[k].x_advance; ++ pos[i].y_offset += pos[k].y_advance; ++ } ++ } ++ else // j > i ++ { ++ /* This can happen with `kerx`: a mark attaching ++ * to a base after it in the logical order. */ ++ if (HB_DIRECTION_IS_FORWARD (direction)) ++ for (unsigned int k = i; k < j; k++) { ++ pos[i].x_offset += pos[k].x_advance; ++ pos[i].y_offset += pos[k].y_advance; ++ } ++ else ++ for (unsigned int k = i + 1; k < j + 1; k++) { ++ pos[i].x_offset -= pos[k].x_advance; ++ pos[i].y_offset -= pos[k].y_advance; ++ } ++ } + } + } + +@@ -149,8 +169,20 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) + + /* Handle attachments */ + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) +- for (unsigned i = 0; i < len; i++) +- propagate_attachment_offsets (pos, len, i, direction); ++ { ++ auto *pos = buffer->pos; ++ // https://github.com/harfbuzz/harfbuzz/issues/5514 ++ if (HB_DIRECTION_IS_FORWARD (direction)) ++ { ++ for (unsigned i = 0; i < len; i++) ++ if (pos[i].attach_chain()) ++ propagate_attachment_offsets (pos, len, i, direction); ++ } else { ++ for (unsigned i = len; i-- > 0; ) ++ if (pos[i].attach_chain()) ++ propagate_attachment_offsets (pos, len, i, direction); ++ } ++ } + + if (unlikely (font->slant_xy) && + HB_DIRECTION_IS_HORIZONTAL (direction)) +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh +index eecdb95a95f..113b693dc3e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh +@@ -19,22 +19,30 @@ struct LigatureArray : List16OfOffset16To + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, +- const hb_map_t *klass_mapping) const ++ const hb_map_t *klass_mapping, ++ hb_sorted_vector_t &new_coverage /* OUT */) const + { + TRACE_SUBSET (this); +- const hb_set_t &glyphset = *c->plan->glyphset_gsub (); ++ const hb_map_t &glyph_map = c->plan->glyph_map_gsub; + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + bool ret = false; + for (const auto _ : + hb_zip (coverage, *this) +- | hb_filter (glyphset, hb_first)) ++ | hb_filter (glyph_map, hb_first)) + { ++ const LigatureAttach& src = (this + _.second); ++ bool non_empty = + hb_range (src.rows * class_count) ++ | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) ++ | hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); }) ++ | hb_any; ++ ++ if (!non_empty) continue; ++ + auto *matrix = out->serialize_append (c->serializer); + if (unlikely (!matrix)) return_trace (false); + +- const LigatureAttach& src = (this + _.second); + auto indexes = + + hb_range (src.rows * class_count) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) +@@ -44,6 +52,9 @@ struct LigatureArray : List16OfOffset16To + this, + src.rows, + indexes); ++ ++ hb_codepoint_t new_gid = glyph_map.get (_.first); ++ new_coverage.push (new_gid); + } + return_trace (ret); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh +index abae8f1c607..bddc5e7fe9e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh +@@ -47,10 +47,15 @@ struct MarkArray : Array16Of /* Array of MarkRecords--in Cove + } + + hb_glyph_position_t &o = buffer->cur_pos(); ++ o.attach_chain() = (int) glyph_pos - (int) buffer->idx; ++ if (o.attach_chain() != (int) glyph_pos - (int) buffer->idx) ++ { ++ o.attach_chain() = 0; ++ goto overflow; ++ } ++ o.attach_type() = ATTACH_TYPE_MARK; + o.x_offset = roundf (base_x - mark_x); + o.y_offset = roundf (base_y - mark_y); +- o.attach_type() = ATTACH_TYPE_MARK; +- o.attach_chain() = (int) glyph_pos - (int) buffer->idx; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + + if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) +@@ -60,6 +65,7 @@ struct MarkArray : Array16Of /* Array of MarkRecords--in Cove + c->buffer->idx, glyph_pos); + } + ++ overflow: + buffer->idx++; + return_trace (true); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh +index b1d1118a86b..65f343bda8b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePos.hh +@@ -11,7 +11,7 @@ struct MarkBasePos + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + MarkBasePosFormat1_2 format1; + #ifndef HB_NO_BEYOND_64K + MarkBasePosFormat1_2 format2; +@@ -22,9 +22,9 @@ struct MarkBasePos + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh +index e633f7a1be1..ad071f327ea 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh +@@ -119,7 +119,7 @@ struct MarkBasePosFormat1_2 + /* Now we search backwards for a non-mark glyph. + * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */ + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_input; + skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); + + if (c->last_base_until > buffer->idx) +@@ -209,19 +209,22 @@ struct MarkBasePosFormat1_2 + ; + + new_coverage.reset (); +- + base_iter +- | hb_map (hb_first) +- | hb_map (glyph_map) +- | hb_sink (new_coverage) +- ; +- +- if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) +- return_trace (false); +- + hb_sorted_vector_t base_indexes; +- for (const unsigned row : + base_iter +- | hb_map (hb_second)) ++ auto &base_array = (this+baseArray); ++ for (const auto _ : + base_iter) + { ++ unsigned row = _.second; ++ bool non_empty = + hb_range ((unsigned) classCount) ++ | hb_filter (klass_mapping) ++ | hb_map ([&] (const unsigned col) { return !base_array.offset_is_null (row, col, (unsigned) classCount); }) ++ | hb_any ++ ; ++ ++ if (!non_empty) continue; ++ ++ hb_codepoint_t new_g = glyph_map.get ( _.first); ++ new_coverage.push (new_g); ++ + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) +@@ -229,8 +232,12 @@ struct MarkBasePosFormat1_2 + ; + } + ++ if (!new_coverage) return_trace (false); ++ if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) ++ return_trace (false); ++ + return_trace (out->baseArray.serialize_subset (c, baseArray, this, +- base_iter.len (), ++ new_coverage.length, + base_indexes.iter ())); + } + }; +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh +index b10102880c0..ee237eb479f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPos.hh +@@ -11,7 +11,7 @@ struct MarkLigPos + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + MarkLigPosFormat1_2 format1; + #ifndef HB_NO_BEYOND_64K + MarkLigPosFormat1_2 format2; +@@ -22,9 +22,9 @@ struct MarkLigPos + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh +index cf4cbae9a3f..509a26c2485 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh +@@ -101,7 +101,7 @@ struct MarkLigPosFormat1_2 + + /* Now we search backwards for a non-mark glyph */ + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_input; + skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); + + if (c->last_base_until > buffer->idx) +@@ -200,19 +200,13 @@ struct MarkLigPosFormat1_2 + &klass_mapping))) + return_trace (false); + +- auto new_ligature_coverage = +- + hb_iter (this + ligatureCoverage) +- | hb_take ((this + ligatureArray).len) +- | hb_map_retains_sorting (glyph_map) +- | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; }) +- ; +- +- if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) ++ hb_sorted_vector_t new_lig_coverage; ++ if (!out->ligatureArray.serialize_subset (c, ligatureArray, this, ++ hb_iter (this+ligatureCoverage), ++ classCount, &klass_mapping, new_lig_coverage)) + return_trace (false); + +- return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, +- hb_iter (this+ligatureCoverage), +- classCount, &klass_mapping)); ++ return_trace (out->ligatureCoverage.serialize_serialize (c->serializer, new_lig_coverage.iter ())); + } + + }; +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh +index e0d9eca0280..c06f013cdce 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPos.hh +@@ -11,7 +11,7 @@ struct MarkMarkPos + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + MarkMarkPosFormat1_2 format1; + #ifndef HB_NO_BEYOND_64K + MarkMarkPosFormat1_2 format2; +@@ -22,9 +22,9 @@ struct MarkMarkPos + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh +index 6519e79b443..c93dbbb3f06 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh +@@ -100,7 +100,7 @@ struct MarkMarkPosFormat1_2 + if (likely (mark1_index == NOT_COVERED)) return_trace (false); + + /* now we search backwards for a suitable mark glyph until a non-mark glyph */ +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_input; + skippy_iter.reset_fast (buffer->idx); + skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); + unsigned unsafe_from; +@@ -196,19 +196,23 @@ struct MarkMarkPosFormat1_2 + ; + + new_coverage.reset (); +- + mark2_iter +- | hb_map (hb_first) +- | hb_map (glyph_map) +- | hb_sink (new_coverage) +- ; +- +- if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) +- return_trace (false); +- + hb_sorted_vector_t mark2_indexes; +- for (const unsigned row : + mark2_iter +- | hb_map (hb_second)) ++ auto &mark2_array = (this+mark2Array); ++ for (const auto _ : + mark2_iter) + { ++ unsigned row = _.second; ++ ++ bool non_empty = + hb_range ((unsigned) classCount) ++ | hb_filter (klass_mapping) ++ | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) ++ | hb_any ++ ; ++ ++ if (!non_empty) continue; ++ ++ hb_codepoint_t new_g = glyph_map.get ( _.first); ++ new_coverage.push (new_g); ++ + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) +@@ -216,6 +220,10 @@ struct MarkMarkPosFormat1_2 + ; + } + ++ if (!new_coverage) return_trace (false); ++ if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) ++ return_trace (false); ++ + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, + mark2_iter.len (), + mark2_indexes.iter ())); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh +index e3794ea9ed5..bf7fff7face 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPos.hh +@@ -12,7 +12,7 @@ struct PairPos + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + PairPosFormat1_3 format1; + PairPosFormat2_4 format2; + #ifndef HB_NO_BEYOND_64K +@@ -25,9 +25,9 @@ struct PairPos + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh +index 2748882f527..1c067bde86f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh +@@ -103,52 +103,35 @@ struct PairPosFormat1_3 + + const Coverage &get_coverage () const { return this+coverage; } + +- unsigned cache_cost () const ++ struct external_cache_t + { +- return (this+coverage).cost (); +- } +- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) ++ hb_ot_layout_mapping_cache_t coverage; ++ }; ++ 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_lookup_cache_op_t::CREATE: +- { +- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); +- if (likely (cache)) +- cache->clear (); +- return cache; +- } +- case hb_ot_lookup_cache_op_t::ENTER: +- return (void *) true; +- case hb_ot_lookup_cache_op_t::LEAVE: +- return nullptr; +- case hb_ot_lookup_cache_op_t::DESTROY: +- { +- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; +- hb_free (cache); +- return nullptr; +- } ++ cache->coverage.clear (); + } +- return nullptr; ++ return cache; + } + +- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } +- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } +- bool _apply (hb_ot_apply_context_t *c, bool cached) const ++ bool apply (hb_ot_apply_context_t *c, void *external_cache) const + { + TRACE_APPLY (this); + + hb_buffer_t *buffer = c->buffer; + + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; +- 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 + if (index == NOT_COVERED) return_trace (false); + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_input; + skippy_iter.reset_fast (buffer->idx); + unsigned unsafe_to; + if (unlikely (!skippy_iter.next (&unsafe_to))) +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh +index d85b1ac2c17..ce731450f41 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh +@@ -123,63 +123,39 @@ struct PairPosFormat2_4 : ValueBase + + const Coverage &get_coverage () const { return this+coverage; } + +- struct pair_pos_cache_t ++ struct external_cache_t + { +- hb_ot_lookup_cache_t coverage; +- hb_ot_lookup_cache_t first; +- hb_ot_lookup_cache_t second; ++ hb_ot_layout_mapping_cache_t coverage; ++ hb_ot_layout_mapping_cache_t first; ++ hb_ot_layout_mapping_cache_t second; + }; +- +- unsigned cache_cost () const +- { +- return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost (); +- } +- static void * cache_func (void *p, hb_ot_lookup_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_lookup_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_lookup_cache_op_t::ENTER: +- return (void *) true; +- case hb_ot_lookup_cache_op_t::LEAVE: +- return nullptr; +- case hb_ot_lookup_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_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } +- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } +- bool _apply (hb_ot_apply_context_t *c, bool cached) const ++ bool apply (hb_ot_apply_context_t *c, void *external_cache) const + { + TRACE_APPLY (this); + + hb_buffer_t *buffer = c->buffer; + + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr; ++ 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 + if (index == NOT_COVERED) return_trace (false); + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_input; + skippy_iter.reset_fast (buffer->idx); + unsigned unsafe_to; + if (unlikely (!skippy_iter.next (&unsafe_to))) +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh +index a0243a218c5..30fc1aacda8 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh +@@ -12,7 +12,7 @@ struct SinglePos + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + SinglePosFormat1 format1; + SinglePosFormat2 format2; + } u; +@@ -41,7 +41,7 @@ struct SinglePos + const hb_hashmap_t> *layout_variation_idx_delta_map, + unsigned newFormat) + { +- if (unlikely (!c->extend_min (u.format))) return; ++ if (unlikely (!c->extend_min (u.format.v))) return; + unsigned format = 2; + ValueFormat new_format; + new_format = newFormat; +@@ -49,8 +49,8 @@ struct SinglePos + if (glyph_val_iter_pairs) + format = get_format (glyph_val_iter_pairs); + +- u.format = format; +- switch (u.format) { ++ u.format.v = format; ++ switch (u.format.v) { + case 1: u.format1.serialize (c, + src, + glyph_val_iter_pairs, +@@ -70,9 +70,9 @@ struct SinglePos + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh +index 731d1ffca1a..b961a5139d8 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh +@@ -56,9 +56,14 @@ struct ValueFormat : HBUINT16 + * PosTable (may be NULL) */ + #endif + +- IntType& operator = (uint16_t i) { v = i; return *this; } +- +- unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } ++ NumType& operator = (uint16_t i) { v = i; return *this; } ++ ++ // Note: spec says skip 2 bytes per bit in the valueformat. But reports ++ // from Microsoft developers indicate that only the fields that are ++ // currently defined are counted. We don't expect any new fields to ++ // be added to ValueFormat. As such, we use the faster hb_popcount8 ++ // that only processes the lowest 8 bits. ++ unsigned int get_len () const { return hb_popcount8 ((uint8_t) *this); } + unsigned int get_size () const { return get_len () * Value::static_size; } + + hb_vector_t get_device_table_indices () const { +@@ -111,8 +116,8 @@ struct ValueFormat : HBUINT16 + + if (!has_device ()) return ret; + +- bool use_x_device = font->x_ppem || font->num_coords; +- bool use_y_device = font->y_ppem || font->num_coords; ++ bool use_x_device = font->x_ppem || font->has_nonzero_coords; ++ bool use_y_device = font->y_ppem || font->has_nonzero_coords; + + if (!use_x_device && !use_y_device) return ret; + +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh +index b5d506f36f9..f13c5e7e251 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSet.hh +@@ -91,6 +91,19 @@ struct AlternateSet + return alternates.len; + } + ++ void ++ collect_alternates (hb_codepoint_t gid, ++ hb_map_t *alternate_count /* IN/OUT */, ++ hb_map_t *alternate_glyphs /* IN/OUT */) const ++ { ++ + hb_enumerate (alternates) ++ | hb_map ([gid] (hb_pair_t _) { return hb_pair (gid + (_.first << 24), _.second); }) ++ | hb_apply ([&] (const hb_pair_t &p) -> void ++ { _hb_collect_glyph_alternates_add (p.first, p.second, ++ alternate_count, alternate_glyphs); }) ++ ; ++ } ++ + template + bool serialize (hb_serialize_context_t *c, +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh +index 8951f5a7a17..a43c75c8f4e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubst.hh +@@ -12,7 +12,7 @@ struct AlternateSubst + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + AlternateSubstFormat1_2 format1; + #ifndef HB_NO_BEYOND_64K + AlternateSubstFormat1_2 format2; +@@ -23,9 +23,9 @@ struct AlternateSubst + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +@@ -42,10 +42,10 @@ struct AlternateSubst + hb_array_t alternate_glyphs_list) + { + TRACE_SERIALIZE (this); +- if (unlikely (!c->extend_min (u.format))) return_trace (false); ++ if (unlikely (!c->extend_min (u.format.v))) return_trace (false); + unsigned int format = 1; +- u.format = format; +- switch (u.format) { ++ u.format.v = format; ++ switch (u.format.v) { + case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list)); + default:return_trace (false); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh +index 421a6e06627..7a3a2511b7f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh +@@ -69,6 +69,19 @@ struct AlternateSubstFormat1_2 + { return (this+alternateSet[(this+coverage).get_coverage (gid)]) + .get_alternates (start_offset, alternate_count, alternate_glyphs); } + ++ void ++ collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, ++ hb_map_t *alternate_glyphs /* IN/OUT */) const ++ { ++ + hb_iter (alternateSet) ++ | hb_map (hb_add (this)) ++ | hb_zip (this+coverage) ++ | hb_apply ([&] (const hb_pair_t &, hb_codepoint_t> _) { ++ _.first.collect_alternates (_.second, alternate_count, alternate_glyphs); ++ }) ++ ; ++ } ++ + bool apply (hb_ot_apply_context_t *c) const + { + TRACE_APPLY (this); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh +index 726da458fac..7bc98d31f32 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh +@@ -44,6 +44,18 @@ struct Ligature + c->output->add (ligGlyph); + } + ++ template ++ void collect_second (set_t &s) const ++ { ++ if (unlikely (!component.get_length ())) ++ { ++ // A ligature without any components. Anything matches. ++ s = set_t::full (); ++ return; ++ } ++ s.add (component.arrayZ[0]); ++ } ++ + bool would_apply (hb_would_apply_context_t *c) const + { + if (c->len != component.lenP1) +@@ -91,15 +103,6 @@ struct Ligature + 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 +110,9 @@ struct Ligature + 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 +129,10 @@ struct Ligature + 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 +143,6 @@ struct Ligature + + ligate_input (c, + count, +- match_positions, + match_end, + ligGlyph, + total_component_count); +@@ -156,8 +155,6 @@ struct Ligature + pos); + } + +- if (match_positions != match_positions_stack) +- hb_free (match_positions); + return_trace (true); + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh +index ff0ffce94d7..81c5c2bcfe4 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh +@@ -11,11 +11,11 @@ namespace GSUB_impl { + template + struct LigatureSet + { +- protected: ++ public: + Array16OfOffset16To> + ligature; /* Array LigatureSet tables + * ordered by preference */ +- public: ++ + DEFINE_SIZE_ARRAY (2, ligature); + + bool sanitize (hb_sanitize_context_t *c) const +@@ -62,6 +62,15 @@ struct LigatureSet + ; + } + ++ template ++ void collect_seconds (set_t &s) const ++ { ++ + hb_iter (ligature) ++ | hb_map (hb_add (this)) ++ | hb_apply ([&s] (const Ligature &_) { _.collect_second (s); }) ++ ; ++ } ++ + bool would_apply (hb_would_apply_context_t *c) const + { + return +@@ -72,14 +81,14 @@ struct LigatureSet + ; + } + +- 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); + + 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,21 +100,21 @@ struct LigatureSet + 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. */ + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_context; + skippy_iter.reset (c->buffer->idx); + 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 @@ struct LigatureSet + 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)) + { +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh +index cffa910295f..22ce9b79d7f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubst.hh +@@ -12,7 +12,7 @@ struct LigatureSubst + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + LigatureSubstFormat1_2 format1; + #ifndef HB_NO_BEYOND_64K + LigatureSubstFormat1_2 format2; +@@ -23,9 +23,9 @@ struct LigatureSubst + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +@@ -45,10 +45,10 @@ struct LigatureSubst + hb_array_t component_list /* Starting from second for each ligature */) + { + TRACE_SERIALIZE (this); +- if (unlikely (!c->extend_min (u.format))) return_trace (false); ++ if (unlikely (!c->extend_min (u.format.v))) return_trace (false); + unsigned int format = 1; +- u.format = format; +- switch (u.format) { ++ u.format.v = format; ++ switch (u.format.v) { + case 1: return_trace (u.format1.serialize (c, + first_glyphs, + ligature_per_first_glyph_count_list, +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh +index 6ae24b33754..909ddca220f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh +@@ -78,52 +78,44 @@ struct LigatureSubstFormat1_2 + return lig_set.would_apply (c); + } + +- unsigned cache_cost () const ++ struct external_cache_t + { +- return (this+coverage).cost (); +- } +- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) ++ hb_ot_layout_mapping_cache_t coverage; ++ hb_set_digest_t seconds; ++ }; ++ 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_lookup_cache_op_t::CREATE: +- { +- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); +- if (likely (cache)) +- cache->clear (); +- return cache; +- } +- case hb_ot_lookup_cache_op_t::ENTER: +- return (void *) true; +- case hb_ot_lookup_cache_op_t::LEAVE: +- return nullptr; +- case hb_ot_lookup_cache_op_t::DESTROY: +- { +- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_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 &_) { _.collect_seconds (cache->seconds); }) ++ ; + } +- return nullptr; ++ return cache; + } + +- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } +- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } +- bool _apply (hb_ot_apply_context_t *c, bool cached) const ++ bool apply (hb_ot_apply_context_t *c, void *external_cache) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; +- 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 +- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); ++ 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, +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh +index cf3d754e3cc..8fb663825b5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubst.hh +@@ -12,7 +12,7 @@ struct MultipleSubst + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + MultipleSubstFormat1_2 format1; + #ifndef HB_NO_BEYOND_64K + MultipleSubstFormat1_2 format2; +@@ -24,9 +24,9 @@ struct MultipleSubst + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); +@@ -41,10 +41,10 @@ struct MultipleSubst + Iterator it) + { + TRACE_SERIALIZE (this); +- if (unlikely (!c->extend_min (u.format))) return_trace (false); ++ if (unlikely (!c->extend_min (u.format.v))) return_trace (false); + unsigned int format = 1; +- u.format = format; +- switch (u.format) { ++ u.format.v = format; ++ switch (u.format.v) { + case 1: return_trace (u.format1.serialize (c, it)); + default:return_trace (false); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh +index 5ad463fea79..e33148d770b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubst.hh +@@ -12,7 +12,7 @@ struct ReverseChainSingleSubst + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + ReverseChainSingleSubstFormat1 format1; + } u; + +@@ -20,9 +20,9 @@ struct ReverseChainSingleSubst + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh +index a5e93a98bef..b3295bee16d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh +@@ -115,7 +115,7 @@ struct Sequence + + for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) + { +- if (buf < p) ++ if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) + *p++ = ','; + snprintf (p, sizeof(buf) - (p - buf), "%u", i); + p += strlen(p); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh +index b84259e7f00..323eb4d0f90 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh +@@ -13,7 +13,7 @@ struct SingleSubst + { + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + SingleSubstFormat1_3 format1; + SingleSubstFormat2_4 format2; + #ifndef HB_NO_BEYOND_64K +@@ -27,9 +27,9 @@ struct SingleSubst + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + #ifndef HB_NO_BEYOND_64K +@@ -47,7 +47,7 @@ struct SingleSubst + Iterator glyphs) + { + TRACE_SERIALIZE (this); +- if (unlikely (!c->extend_min (u.format))) return_trace (false); ++ if (unlikely (!c->extend_min (u.format.v))) return_trace (false); + unsigned format = 2; + unsigned delta = 0; + if (glyphs) +@@ -71,8 +71,8 @@ struct SingleSubst + if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; + } + +- u.format = format; +- switch (u.format) { ++ u.format.v = format; ++ switch (u.format.v) { + case 1: return_trace (u.format1.serialize (c, + + glyphs + | hb_map_retains_sorting (hb_first), +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh +index be6cd820d28..5ee2c1d1f46 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh +@@ -123,6 +123,21 @@ struct SingleSubstFormat1_3 + return 1; + } + ++ void ++ collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, ++ hb_map_t *alternate_glyphs /* IN/OUT */) const ++ { ++ hb_codepoint_t d = deltaGlyphID; ++ hb_codepoint_t mask = get_mask (); ++ ++ + hb_iter (this+coverage) ++ | hb_map ([d, mask] (hb_codepoint_t g) { return hb_pair (g, (g + d) & mask); }) ++ | hb_apply ([&] (const hb_pair_t &p) -> void ++ { _hb_collect_glyph_alternates_add (p.first, p.second, ++ alternate_count, alternate_glyphs); }) ++ ; ++ } ++ + bool apply (hb_ot_apply_context_t *c) const + { + TRACE_APPLY (this); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh +index e9096460451..0d51d130fee 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh +@@ -100,6 +100,17 @@ struct SingleSubstFormat2_4 + return 1; + } + ++ void ++ collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, ++ hb_map_t *alternate_glyphs /* IN/OUT */) const ++ { ++ + hb_zip (this+coverage, substitute) ++ | hb_apply ([&] (const hb_pair_t &p) -> void ++ { _hb_collect_glyph_alternates_add (p.first, p.second, ++ alternate_count, alternate_glyphs); }) ++ ; ++ } ++ + bool apply (hb_ot_apply_context_t *c) const + { + TRACE_APPLY (this); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh +index 527f64114b4..5cf9eb368aa 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh +@@ -29,8 +29,11 @@ + #ifndef OT_LAYOUT_TYPES_HH + #define OT_LAYOUT_TYPES_HH + +-using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>; +-static_assert (sizeof (hb_ot_lookup_cache_t) == 256, ""); ++using hb_ot_layout_mapping_cache_t = hb_cache_t<16, 8, 8>; ++static_assert (sizeof (hb_ot_layout_mapping_cache_t) == 512, ""); ++ ++using hb_ot_layout_binary_cache_t = hb_cache_t<14, 1, 8>; ++static_assert (sizeof (hb_ot_layout_binary_cache_t) == 256, ""); + + namespace OT { + namespace Layout { +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.cc b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.cc +new file mode 100644 +index 00000000000..f0e7f934579 +--- /dev/null ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.cc +@@ -0,0 +1,421 @@ ++#include "VARC.hh" ++ ++#ifndef HB_NO_VAR_COMPOSITES ++ ++#include "../../../hb-draw.hh" ++#include "../../../hb-ot-layout-common.hh" ++#include "../../../hb-ot-layout-gdef-table.hh" ++ ++namespace OT { ++ ++//namespace Var { ++ ++ ++#ifndef HB_NO_DRAW ++ ++struct hb_transforming_pen_context_t ++{ ++ hb_transform_t<> transform; ++ hb_draw_funcs_t *dfuncs; ++ void *data; ++ hb_draw_state_t *st; ++}; ++ ++static void ++hb_transforming_pen_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, ++ void *data, ++ hb_draw_state_t *st, ++ float to_x, float to_y, ++ void *user_data HB_UNUSED) ++{ ++ hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; ++ ++ c->transform.transform_point (to_x, to_y); ++ ++ c->dfuncs->move_to (c->data, *c->st, to_x, to_y); ++} ++ ++static void ++hb_transforming_pen_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, ++ void *data, ++ hb_draw_state_t *st, ++ float to_x, float to_y, ++ void *user_data HB_UNUSED) ++{ ++ hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; ++ ++ c->transform.transform_point (to_x, to_y); ++ ++ c->dfuncs->line_to (c->data, *c->st, to_x, to_y); ++} ++ ++static void ++hb_transforming_pen_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, ++ void *data, ++ hb_draw_state_t *st, ++ float control_x, float control_y, ++ float to_x, float to_y, ++ void *user_data HB_UNUSED) ++{ ++ hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; ++ ++ c->transform.transform_point (control_x, control_y); ++ c->transform.transform_point (to_x, to_y); ++ ++ c->dfuncs->quadratic_to (c->data, *c->st, control_x, control_y, to_x, to_y); ++} ++ ++static void ++hb_transforming_pen_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, ++ void *data, ++ hb_draw_state_t *st, ++ float control1_x, float control1_y, ++ float control2_x, float control2_y, ++ float to_x, float to_y, ++ void *user_data HB_UNUSED) ++{ ++ hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; ++ ++ c->transform.transform_point (control1_x, control1_y); ++ c->transform.transform_point (control2_x, control2_y); ++ c->transform.transform_point (to_x, to_y); ++ ++ c->dfuncs->cubic_to (c->data, *c->st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); ++} ++ ++static void ++hb_transforming_pen_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED, ++ void *data, ++ hb_draw_state_t *st, ++ void *user_data HB_UNUSED) ++{ ++ hb_transforming_pen_context_t *c = (hb_transforming_pen_context_t *) data; ++ ++ c->dfuncs->close_path (c->data, *c->st); ++} ++ ++static inline void free_static_transforming_pen_funcs (); ++ ++static struct hb_transforming_pen_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t ++{ ++ static hb_draw_funcs_t *create () ++ { ++ hb_draw_funcs_t *funcs = hb_draw_funcs_create (); ++ ++ hb_draw_funcs_set_move_to_func (funcs, hb_transforming_pen_move_to, nullptr, nullptr); ++ hb_draw_funcs_set_line_to_func (funcs, hb_transforming_pen_line_to, nullptr, nullptr); ++ hb_draw_funcs_set_quadratic_to_func (funcs, hb_transforming_pen_quadratic_to, nullptr, nullptr); ++ hb_draw_funcs_set_cubic_to_func (funcs, hb_transforming_pen_cubic_to, nullptr, nullptr); ++ hb_draw_funcs_set_close_path_func (funcs, hb_transforming_pen_close_path, nullptr, nullptr); ++ ++ hb_draw_funcs_make_immutable (funcs); ++ ++ hb_atexit (free_static_transforming_pen_funcs); ++ ++ return funcs; ++ } ++} static_transforming_pen_funcs; ++ ++static inline ++void free_static_transforming_pen_funcs () ++{ ++ static_transforming_pen_funcs.free_instance (); ++} ++ ++static hb_draw_funcs_t * ++hb_transforming_pen_get_funcs () ++{ ++ return static_transforming_pen_funcs.get_unconst (); ++} ++ ++hb_ubytes_t ++VarComponent::get_path_at (const hb_varc_context_t &c, ++ hb_codepoint_t parent_gid, ++ hb_array_t coords, ++ hb_transform_t<> total_transform, ++ hb_ubytes_t total_record, ++ hb_scalar_cache_t *cache) const ++{ ++ const unsigned char *end = total_record.arrayZ + total_record.length; ++ const unsigned char *record = total_record.arrayZ; ++ ++ auto &VARC = *c.font->face->table.VARC->table; ++ auto &varStore = &VARC+VARC.varStore; ++ ++#define READ_UINT32VAR(name) \ ++ HB_STMT_START { \ ++ if (unlikely (unsigned (end - record) < HBUINT32VAR::min_size)) return hb_ubytes_t (); \ ++ hb_barrier (); \ ++ auto &varint = * (const HBUINT32VAR *) record; \ ++ unsigned size = varint.get_size (); \ ++ if (unlikely (unsigned (end - record) < size)) return hb_ubytes_t (); \ ++ name = (uint32_t) varint; \ ++ record += size; \ ++ } HB_STMT_END ++ ++ uint32_t flags; ++ READ_UINT32VAR (flags); ++ ++ // gid ++ ++ hb_codepoint_t gid = 0; ++ if (flags & (unsigned) flags_t::GID_IS_24BIT) ++ { ++ if (unlikely (unsigned (end - record) < HBGlyphID24::static_size)) ++ return hb_ubytes_t (); ++ hb_barrier (); ++ gid = * (const HBGlyphID24 *) record; ++ record += HBGlyphID24::static_size; ++ } ++ else ++ { ++ if (unlikely (unsigned (end - record) < HBGlyphID16::static_size)) ++ return hb_ubytes_t (); ++ hb_barrier (); ++ gid = * (const HBGlyphID16 *) record; ++ record += HBGlyphID16::static_size; ++ } ++ ++ // Condition ++ bool show = true; ++ if (flags & (unsigned) flags_t::HAVE_CONDITION) ++ { ++ unsigned conditionIndex; ++ READ_UINT32VAR (conditionIndex); ++ const auto &condition = (&VARC+VARC.conditionList)[conditionIndex]; ++ auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache); ++ show = condition.evaluate (coords.arrayZ, coords.length, &instancer); ++ } ++ ++ // Axis values ++ ++ auto &axisIndices = c.scratch.axisIndices; ++ axisIndices.clear (); ++ auto &axisValues = c.scratch.axisValues; ++ axisValues.clear (); ++ if (flags & (unsigned) flags_t::HAVE_AXES) ++ { ++ unsigned axisIndicesIndex; ++ READ_UINT32VAR (axisIndicesIndex); ++ axisIndices.extend ((&VARC+VARC.axisIndicesList)[axisIndicesIndex]); ++ axisValues.resize (axisIndices.length); ++ const HBUINT8 *p = (const HBUINT8 *) record; ++ TupleValues::decompile (p, axisValues, (const HBUINT8 *) end); ++ record = (const unsigned char *) p; ++ } ++ ++ // Apply variations if any ++ if (flags & (unsigned) flags_t::AXIS_VALUES_HAVE_VARIATION) ++ { ++ uint32_t axisValuesVarIdx; ++ READ_UINT32VAR (axisValuesVarIdx); ++ if (show && coords && !axisValues.in_error ()) ++ varStore.get_delta (axisValuesVarIdx, coords, axisValues.as_array (), cache); ++ } ++ ++ auto component_coords = coords; ++ /* Copying coords is expensive; so we have put an arbitrary ++ * limit on the max number of coords for now. */ ++ if ((flags & (unsigned) flags_t::RESET_UNSPECIFIED_AXES) || ++ coords.length > HB_VAR_COMPOSITE_MAX_AXES) ++ component_coords = hb_array (c.font->coords, c.font->num_coords); ++ ++ // Transform ++ ++ uint32_t transformVarIdx = VarIdx::NO_VARIATION; ++ if (flags & (unsigned) flags_t::TRANSFORM_HAS_VARIATION) ++ READ_UINT32VAR (transformVarIdx); ++ ++#define PROCESS_TRANSFORM_COMPONENTS \ ++ HB_STMT_START { \ ++ PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TRANSLATE_X, translateX); \ ++ PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TRANSLATE_Y, translateY); \ ++ PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_ROTATION, rotation); \ ++ PROCESS_TRANSFORM_COMPONENT (F6DOT10, 1.0f, HAVE_SCALE_X, scaleX); \ ++ PROCESS_TRANSFORM_COMPONENT (F6DOT10, 1.0f, HAVE_SCALE_Y, scaleY); \ ++ PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_SKEW_X, skewX); \ ++ PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_SKEW_Y, skewY); \ ++ PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TCENTER_X, tCenterX); \ ++ PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TCENTER_Y, tCenterY); \ ++ } HB_STMT_END ++ ++ hb_transform_decomposed_t<> transform; ++ ++ // Read transform components ++#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ ++ if (flags & (unsigned) flags_t::flag) \ ++ { \ ++ static_assert (type::static_size == HBINT16::static_size, ""); \ ++ if (unlikely (unsigned (end - record) < HBINT16::static_size)) \ ++ return hb_ubytes_t (); \ ++ hb_barrier (); \ ++ transform.name = mult * * (const HBINT16 *) record; \ ++ record += HBINT16::static_size; \ ++ } ++ PROCESS_TRANSFORM_COMPONENTS; ++#undef PROCESS_TRANSFORM_COMPONENT ++ ++ // Read reserved records ++ unsigned i = flags & (unsigned) flags_t::RESERVED_MASK; ++ while (i) ++ { ++ HB_UNUSED uint32_t discard; ++ READ_UINT32VAR (discard); ++ i &= i - 1; ++ } ++ ++ /* Parsing is over now. */ ++ ++ if (show) ++ { ++ // Only use coord_setter if there's actually any axis overrides. ++ coord_setter_t coord_setter (axisIndices ? component_coords : hb_array ()); ++ // Go backwards, to reduce coord_setter vector reallocations. ++ for (unsigned i = axisIndices.length; i; i--) ++ coord_setter[axisIndices[i - 1]] = axisValues[i - 1]; ++ if (axisIndices) ++ component_coords = coord_setter.get_coords (); ++ ++ // Apply transform variations if any ++ if (transformVarIdx != VarIdx::NO_VARIATION && coords) ++ { ++ float transformValues[9]; ++ unsigned numTransformValues = 0; ++#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ ++ if (flags & (unsigned) flags_t::flag) \ ++ transformValues[numTransformValues++] = transform.name / mult; ++ PROCESS_TRANSFORM_COMPONENTS; ++#undef PROCESS_TRANSFORM_COMPONENT ++ varStore.get_delta (transformVarIdx, coords, hb_array (transformValues, numTransformValues), cache); ++ numTransformValues = 0; ++#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ ++ if (flags & (unsigned) flags_t::flag) \ ++ transform.name = transformValues[numTransformValues++] * mult; ++ PROCESS_TRANSFORM_COMPONENTS; ++#undef PROCESS_TRANSFORM_COMPONENT ++ } ++ ++ // Divide them by their divisors ++#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ ++ if (flags & (unsigned) flags_t::flag) \ ++ { \ ++ HBINT16 int_v; \ ++ int_v = roundf (transform.name); \ ++ type typed_v = * (const type *) &int_v; \ ++ float float_v = (float) typed_v; \ ++ transform.name = float_v; \ ++ } ++ PROCESS_TRANSFORM_COMPONENTS; ++#undef PROCESS_TRANSFORM_COMPONENT ++ ++ if (!(flags & (unsigned) flags_t::HAVE_SCALE_Y)) ++ transform.scaleY = transform.scaleX; ++ ++ total_transform.transform (transform.to_transform ()); ++ total_transform.scale (c.font->x_mult ? 1.f / c.font->x_multf : 0.f, ++ c.font->y_mult ? 1.f / c.font->y_multf : 0.f); ++ ++ bool same_coords = component_coords.length == coords.length && ++ component_coords.arrayZ == coords.arrayZ; ++ ++ c.depth_left--; ++ VARC.get_path_at (c, gid, ++ component_coords, total_transform, ++ parent_gid, ++ same_coords ? cache : nullptr); ++ c.depth_left++; ++ } ++ ++#undef PROCESS_TRANSFORM_COMPONENTS ++#undef READ_UINT32VAR ++ ++ return hb_ubytes_t (record, end - record); ++} ++ ++bool ++VARC::get_path_at (const hb_varc_context_t &c, ++ hb_codepoint_t glyph, ++ hb_array_t coords, ++ hb_transform_t<> transform, ++ hb_codepoint_t parent_glyph, ++ hb_scalar_cache_t *parent_cache) const ++{ ++ // Don't recurse on the same glyph. ++ unsigned idx = glyph == parent_glyph ? ++ NOT_COVERED : ++ (this+coverage).get_coverage (glyph); ++ if (idx == NOT_COVERED) ++ { ++ if (c.draw_session) ++ { ++ // Build a transforming pen to apply the transform. ++ hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); ++ hb_transforming_pen_context_t context {transform, ++ c.draw_session->funcs, ++ c.draw_session->draw_data, ++ &c.draw_session->st}; ++ hb_draw_session_t transformer_session {transformer_funcs, &context}; ++ hb_draw_session_t &shape_draw_session = transform.is_identity () ? *c.draw_session : transformer_session; ++ ++ if (c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch)) return true; ++#ifndef HB_NO_CFF ++ if (c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords)) return true; ++ if (c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) return true; // Doesn't have variations ++#endif ++ return false; ++ } ++ else if (c.extents) ++ { ++ hb_glyph_extents_t glyph_extents; ++ if (!c.font->face->table.glyf->get_extents_at (c.font, glyph, &glyph_extents, coords)) ++#ifndef HB_NO_CFF ++ if (!c.font->face->table.cff2->get_extents_at (c.font, glyph, &glyph_extents, coords)) ++ if (!c.font->face->table.cff1->get_extents (c.font, glyph, &glyph_extents)) // Doesn't have variations ++#endif ++ return false; ++ ++ hb_extents_t<> comp_extents (glyph_extents); ++ transform.transform_extents (comp_extents); ++ c.extents->union_ (comp_extents); ++ } ++ return true; ++ } ++ ++ if (c.depth_left <= 0) ++ return true; ++ ++ if (c.edges_left <= 0) ++ return true; ++ (c.edges_left)--; ++ ++ hb_decycler_node_t node (c.decycler); ++ if (unlikely (!node.visit (glyph))) ++ return true; ++ ++ hb_ubytes_t record = (this+glyphRecords)[idx]; ++ ++ hb_scalar_cache_t static_cache; ++ hb_scalar_cache_t *cache = parent_cache ? ++ parent_cache : ++ (this+varStore).create_cache (&static_cache); ++ ++ transform.scale (c.font->x_multf, c.font->y_multf); ++ ++ VarCompositeGlyph::get_path_at (c, ++ glyph, ++ coords, transform, ++ record, ++ cache); ++ ++ if (cache != parent_cache) ++ (this+varStore).destroy_cache (cache, &static_cache); ++ ++ return true; ++} ++ ++#endif ++ ++//} // namespace Var ++} // namespace OT ++ ++#endif +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh +index 2ea1b6bca32..6b40f044556 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh +@@ -32,7 +32,7 @@ struct hb_varc_context_t + { + hb_font_t *font; + hb_draw_session_t *draw_session; +- hb_extents_t *extents; ++ hb_extents_t<> *extents; + mutable hb_decycler_t decycler; + mutable signed edges_left; + mutable signed depth_left; +@@ -65,9 +65,9 @@ struct VarComponent + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t parent_gid, + hb_array_t coords, +- hb_transform_t transform, ++ hb_transform_t<> transform, + hb_ubytes_t record, +- VarRegionList::cache_t *cache = nullptr) const; ++ hb_scalar_cache_t *cache = nullptr) const; + }; + + struct VarCompositeGlyph +@@ -76,9 +76,9 @@ struct VarCompositeGlyph + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, + hb_array_t coords, +- hb_transform_t transform, ++ hb_transform_t<> transform, + hb_ubytes_t record, +- VarRegionList::cache_t *cache) ++ hb_scalar_cache_t *cache) + { + while (record) + { +@@ -104,9 +104,9 @@ struct VARC + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, + hb_array_t coords, +- hb_transform_t transform = HB_TRANSFORM_IDENTITY, ++ hb_transform_t<> transform = HB_TRANSFORM_IDENTITY, + hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID, +- VarRegionList::cache_t *parent_cache = nullptr) const; ++ hb_scalar_cache_t *parent_cache = nullptr) const; + + bool + get_path (hb_font_t *font, +@@ -129,7 +129,7 @@ struct VARC + bool + get_extents (hb_font_t *font, + hb_codepoint_t gid, +- hb_extents_t *extents, ++ hb_extents_t<> *extents, + hb_varc_scratch_t &scratch) const + { + hb_varc_context_t c {font, +@@ -194,9 +194,10 @@ struct VARC + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { ++#ifndef HB_NO_DRAW + if (!table->has_data ()) return false; + +- hb_extents_t f_extents; ++ hb_extents_t<> f_extents; + + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; +@@ -207,6 +208,9 @@ struct VARC + *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0); + + return ret; ++#else ++ return false; ++#endif + } + + private: +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh +index 1805df262aa..8f5287e9457 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh +@@ -102,17 +102,15 @@ struct Glyph + if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; + hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + { ++ // Duplicated code. + int lsb = 0; +- int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? +- (int) header->xMin - lsb : 0; ++ face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); ++ int h_delta = (int) header->xMin - lsb; + HB_UNUSED int tsb = 0; +- int v_orig = (int) header->yMax + + #ifndef HB_NO_VERTICAL +- ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) +-#else +- 0 ++ face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); + #endif +- ; ++ int v_orig = (int) header->yMax + tsb; + unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid); + unsigned v_adv = + #ifndef HB_NO_VERTICAL +@@ -314,6 +312,7 @@ struct Glyph + bool use_my_metrics = true, + bool phantom_only = false, + hb_array_t coords = hb_array_t (), ++ hb_scalar_cache_t *gvar_cache = nullptr, + unsigned int depth = 0, + unsigned *edge_count = nullptr) const + { +@@ -328,7 +327,7 @@ struct Glyph + head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); + } + +- if (!coords) ++ if (!coords && font->has_nonzero_coords) + coords = hb_array (font->coords, font->num_coords); + + contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; +@@ -357,17 +356,15 @@ struct Glyph + if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; + hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + { ++ // Duplicated code. + int lsb = 0; +- int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? +- (int) header->xMin - lsb : 0; ++ glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); ++ int h_delta = (int) header->xMin - lsb; + HB_UNUSED int tsb = 0; +- int v_orig = (int) header->yMax + + #ifndef HB_NO_VERTICAL +- ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) +-#else +- 0 ++ glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); + #endif +- ; ++ int v_orig = (int) header->yMax + tsb; + unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); + unsigned v_adv = + #ifndef HB_NO_VERTICAL +@@ -383,7 +380,7 @@ struct Glyph + } + + #ifndef HB_NO_VAR +- if (coords) ++ if (hb_any (coords)) + { + #ifndef HB_NO_BEYOND_64K + if (glyf_accelerator.GVAR->has_data ()) +@@ -391,6 +388,7 @@ struct Glyph + coords, + points.as_array ().sub_array (old_length), + scratch, ++ gvar_cache, + phantom_only && type == SIMPLE); + else + #endif +@@ -398,6 +396,7 @@ struct Glyph + coords, + points.as_array ().sub_array (old_length), + scratch, ++ gvar_cache, + phantom_only && type == SIMPLE); + } + #endif +@@ -447,6 +446,7 @@ struct Glyph + use_my_metrics, + phantom_only, + coords, ++ gvar_cache, + depth + 1, + edge_count))) + { +@@ -533,7 +533,11 @@ struct Glyph + bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, + hb_glyph_extents_t *extents) const + { +- if (type == EMPTY) return true; /* Empty glyph; zero extents. */ ++ if (type == EMPTY) ++ { ++ *extents = {0, 0, 0, 0}; ++ return true; /* Empty glyph; zero extents. */ ++ } + return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh +index 601e1303792..507c94f7f3d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh +@@ -189,7 +189,7 @@ struct SimpleGlyph + + unsigned old_length = points.length; + points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy +- if (unlikely (!points.resize (points.length + num_points, false))) return false; ++ if (unlikely (!points.resize_dirty (points.length + num_points))) return false; + auto points_ = points.as_array ().sub_array (old_length); + if (!phantom_only) + hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points); +diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh +index d9e5fedfa92..3fe2506bec9 100644 +--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh ++++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh +@@ -220,7 +220,8 @@ struct glyf_accelerator_t + template + bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, + hb_array_t coords, +- hb_glyf_scratch_t &scratch) const ++ hb_glyf_scratch_t &scratch, ++ hb_scalar_cache_t *gvar_cache = nullptr) const + { + if (gid >= num_glyphs) return false; + +@@ -228,7 +229,7 @@ struct glyf_accelerator_t + all_points.resize (0); + + bool phantom_only = !consumer.is_consuming_contour_points (); +- if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) ++ if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords, gvar_cache))) + return false; + + unsigned count = all_points.length; +@@ -371,69 +372,67 @@ struct glyf_accelerator_t + contour_point_t *get_phantoms_sink () { return phantoms; } + }; + ++#ifndef HB_NO_VAR + unsigned +- get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const ++ get_advance_with_var_unscaled (hb_codepoint_t gid, ++ hb_font_t *font, ++ bool is_vertical, ++ hb_glyf_scratch_t &scratch, ++ hb_scalar_cache_t *gvar_cache = nullptr) const + { + if (unlikely (gid >= num_glyphs)) return 0; + + bool success = false; + + contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; +- if (font->num_coords) ++ success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), ++ hb_array (font->coords, ++ font->has_nonzero_coords ? font->num_coords : 0), ++ scratch, gvar_cache); ++ if (unlikely (!success)) + { +- hb_glyf_scratch_t scratch; +- success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), +- hb_array (font->coords, font->num_coords), +- scratch); ++ unsigned upem = font->face->get_upem (); ++ return is_vertical ? upem : upem / 2; + } + +- if (unlikely (!success)) +- return +-#ifndef HB_NO_VERTICAL +- is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : +-#endif +- hmtx->get_advance_without_var_unscaled (gid); +- + float result = is_vertical + ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y + : phantoms[glyf_impl::PHANTOM_RIGHT].x - phantoms[glyf_impl::PHANTOM_LEFT].x; + return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); + } + +- bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const ++ float ++ get_v_origin_with_var_unscaled (hb_codepoint_t gid, ++ hb_font_t *font, ++ hb_glyf_scratch_t &scratch, ++ hb_scalar_cache_t *gvar_cache = nullptr) const + { +- if (unlikely (gid >= num_glyphs)) return false; ++ if (unlikely (gid >= num_glyphs)) return 0; ++ ++ bool success = false; + +- hb_glyph_extents_t extents; +- hb_glyf_scratch_t scratch; + contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; +- if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false), +- hb_array (font->coords, font->num_coords), +- scratch))) +- return false; ++ success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), ++ hb_array (font->coords, ++ font->has_nonzero_coords ? font->num_coords : 0), ++ scratch, gvar_cache); ++ if (unlikely (!success)) ++ { ++ return font->face->get_upem (); ++ } + +- *lsb = is_vertical +- ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing +- : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); +- return true; ++ return phantoms[glyf_impl::PHANTOM_TOP].y; + } + #endif +- +- bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const +- { +- if (unlikely (gid >= num_glyphs)) return false; +- if (is_vertical) return false; // TODO Humm, what to do here? +- +- *lsb = glyph_for_gid (gid).get_header ()->xMin; +- return true; +- } ++#endif + + public: + + bool get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const +- { return get_extents_at (font, gid, extents, hb_array (font->coords, font->num_coords)); } ++ { return get_extents_at (font, gid, extents, hb_array (font->coords, ++ font->has_nonzero_coords ? font->num_coords : 0)); } + + bool get_extents_at (hb_font_t *font, + hb_codepoint_t gid, +@@ -445,12 +444,15 @@ struct glyf_accelerator_t + #ifndef HB_NO_VAR + if (coords) + { +- hb_glyf_scratch_t scratch; +- return get_points (font, +- gid, +- points_aggregator_t (font, extents, nullptr, true), +- coords, +- scratch); ++ hb_glyf_scratch_t *scratch = acquire_scratch (); ++ if (unlikely (!scratch)) return false; ++ bool ret = get_points (font, ++ gid, ++ points_aggregator_t (font, extents, nullptr, true), ++ coords, ++ *scratch); ++ release_scratch (scratch); ++ return ret; + } + #endif + return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); +@@ -485,33 +487,20 @@ struct glyf_accelerator_t + } + + bool +- get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const ++ get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, hb_scalar_cache_t *gvar_cache = nullptr) const + { + if (!has_data ()) return false; + +- hb_glyf_scratch_t *scratch; +- +- // Borrow the cached strach buffer. +- { +- scratch = cached_scratch.get_acquire (); +- if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) +- { +- scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); +- if (unlikely (!scratch)) +- return true; +- } +- } ++ hb_glyf_scratch_t *scratch = acquire_scratch (); ++ if (unlikely (!scratch)) return true; + + bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), +- hb_array (font->coords, font->num_coords), +- *scratch); ++ hb_array (font->coords, ++ font->has_nonzero_coords ? font->num_coords : 0), ++ *scratch, ++ gvar_cache); + +- // Put it back. +- if (!cached_scratch.cmpexch (nullptr, scratch)) +- { +- scratch->~hb_glyf_scratch_t (); +- hb_free (scratch); +- } ++ release_scratch (scratch); + + return ret; + } +@@ -519,12 +508,38 @@ struct glyf_accelerator_t + bool + get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, + hb_array_t coords, +- hb_glyf_scratch_t &scratch) const ++ hb_glyf_scratch_t &scratch, ++ hb_scalar_cache_t *gvar_cache = nullptr) const + { + if (!has_data ()) return false; + return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + coords, +- scratch); ++ scratch, ++ gvar_cache); ++ } ++ ++ ++ hb_glyf_scratch_t *acquire_scratch () const ++ { ++ if (!has_data ()) return nullptr; ++ hb_glyf_scratch_t *scratch = cached_scratch.get_acquire (); ++ if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) ++ { ++ scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); ++ if (unlikely (!scratch)) ++ return nullptr; ++ } ++ return scratch; ++ } ++ void release_scratch (hb_glyf_scratch_t *scratch) const ++ { ++ if (!scratch) ++ return; ++ if (!cached_scratch.cmpexch (nullptr, scratch)) ++ { ++ scratch->~hb_glyf_scratch_t (); ++ hb_free (scratch); ++ } + } + + #ifndef HB_NO_VAR +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh +index da6378820bb..d1f38b9de8a 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh +@@ -74,7 +74,7 @@ struct ClassDef : public OT::ClassDef + class_def_link->width = SmallTypes::size; + class_def_link->objidx = class_def_prime_id; + class_def_link->position = link_position; +- class_def_prime_vertex.add_parent (parent_id); ++ class_def_prime_vertex.add_parent (parent_id, false); + + return true; + } +@@ -117,7 +117,7 @@ struct ClassDef : public OT::ClassDef + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::ClassDef::min_size) return false; + hb_barrier (); +- switch (u.format) ++ switch (u.format.v) + { + case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); + case 2: return ((ClassDefFormat2*)this)->sanitize (vertex); +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh +index 61ca063e345..46c703524d9 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh +@@ -32,29 +32,27 @@ + + namespace graph { + +-struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3 +-{ +- bool sanitize (graph_t::vertex_t& vertex) const +- { +- int64_t vertex_len = vertex.obj.tail - vertex.obj.head; +- constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; +- if (vertex_len < min_size) return false; +- hb_barrier (); +- return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); +- } +-}; ++static bool sanitize ( ++ const OT::Layout::Common::CoverageFormat1_3* thiz, ++ graph_t::vertex_t& vertex ++) { ++ int64_t vertex_len = vertex.obj.tail - vertex.obj.head; ++ constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; ++ if (vertex_len < min_size) return false; ++ hb_barrier (); ++ return vertex_len >= min_size + thiz->glyphArray.get_size () - thiz->glyphArray.len.get_size (); ++} + +-struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4 +-{ +- bool sanitize (graph_t::vertex_t& vertex) const +- { +- int64_t vertex_len = vertex.obj.tail - vertex.obj.head; +- constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; +- if (vertex_len < min_size) return false; +- hb_barrier (); +- return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); +- } +-}; ++static bool sanitize ( ++ const OT::Layout::Common::CoverageFormat2_4* thiz, ++ graph_t::vertex_t& vertex ++) { ++ int64_t vertex_len = vertex.obj.tail - vertex.obj.head; ++ constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; ++ if (vertex_len < min_size) return false; ++ hb_barrier (); ++ return vertex_len >= min_size + thiz->rangeRecord.get_size () - thiz->rangeRecord.len.get_size (); ++} + + struct Coverage : public OT::Layout::Common::Coverage + { +@@ -98,11 +96,33 @@ struct Coverage : public OT::Layout::Common::Coverage + coverage_link->width = SmallTypes::size; + coverage_link->objidx = coverage_prime_id; + coverage_link->position = link_position; +- coverage_prime_vertex.add_parent (parent_id); ++ coverage_prime_vertex.add_parent (parent_id, false); + + return (Coverage*) coverage_prime_vertex.obj.head; + } + ++ // Filter an existing coverage table to glyphs at indices [start, end) and replace it with the filtered version. ++ static bool filter_coverage (gsubgpos_graph_context_t& c, ++ unsigned existing_coverage, ++ unsigned start, unsigned end) { ++ unsigned coverage_size = c.graph.vertices_[existing_coverage].table_size (); ++ auto& coverage_v = c.graph.vertices_[existing_coverage]; ++ Coverage* coverage_table = (Coverage*) coverage_v.obj.head; ++ if (!coverage_table || !coverage_table->sanitize (coverage_v)) ++ return false; ++ ++ auto new_coverage = ++ + hb_zip (coverage_table->iter (), hb_range ()) ++ | hb_filter ([&] (hb_pair_t p) { ++ return p.second >= start && p.second < end; ++ }) ++ | hb_map_retains_sorting (hb_first) ++ ; ++ ++ return make_coverage (c, new_coverage, existing_coverage, coverage_size * 2 + 100); ++ } ++ ++ // Replace the coverage table at dest obj with one covering 'glyphs'. + template + static bool make_coverage (gsubgpos_graph_context_t& c, + It glyphs, +@@ -141,10 +161,10 @@ struct Coverage : public OT::Layout::Common::Coverage + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + hb_barrier (); +- switch (u.format) ++ switch (u.format.v) + { +- case 1: return ((CoverageFormat1*)this)->sanitize (vertex); +- case 2: return ((CoverageFormat2*)this)->sanitize (vertex); ++ case 1: return graph::sanitize ((const OT::Layout::Common::CoverageFormat1_3*) this, vertex); ++ case 2: return graph::sanitize ((const OT::Layout::Common::CoverageFormat2_4*) this, vertex); + #ifndef HB_NO_BEYOND_64K + // Not currently supported + case 3: +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh +index ed1026f5866..78ae1a9dd5b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh +@@ -50,6 +50,7 @@ struct graph_t + private: + unsigned incoming_edges_ = 0; + unsigned single_parent = (unsigned) -1; ++ bool has_incoming_virtual_edges_ = false; + hb_hashmap_t parents; + public: + +@@ -66,6 +67,11 @@ struct graph_t + return parents.in_error (); + } + ++ bool has_incoming_virtual_edges () const ++ { ++ return has_incoming_virtual_edges_; ++ } ++ + bool link_positions_valid (unsigned num_objects, bool removed_nil) + { + hb_set_t assigned_bytes; +@@ -121,7 +127,9 @@ struct graph_t + } + } + +- bool equals (const vertex_t& other, ++ bool equals (unsigned this_index, ++ unsigned other_index, ++ const vertex_t& other, + const graph_t& graph, + const graph_t& other_graph, + unsigned depth) const +@@ -129,8 +137,10 @@ struct graph_t + if (!(as_bytes () == other.as_bytes ())) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, +- "vertex [%lu] bytes != [%lu] bytes, depth = %u", ++ "vertex %u [%lu bytes] != %u [%lu bytes], depth = %u", ++ this_index, + (unsigned long) table_size (), ++ other_index, + (unsigned long) other.table_size (), + depth); + +@@ -162,6 +172,7 @@ struct graph_t + hb_swap (a.single_parent, b.single_parent); + hb_swap (a.parents, b.parents); + hb_swap (a.incoming_edges_, b.incoming_edges_); ++ hb_swap (a.has_incoming_virtual_edges_, b.has_incoming_virtual_edges_); + hb_swap (a.start, b.start); + hb_swap (a.end, b.end); + hb_swap (a.priority, b.priority); +@@ -207,13 +218,16 @@ struct graph_t + void reset_parents () + { + incoming_edges_ = 0; ++ has_incoming_virtual_edges_ = false; + single_parent = (unsigned) -1; + parents.reset (); + } + +- void add_parent (unsigned parent_index) ++ void add_parent (unsigned parent_index, bool is_virtual) + { + assert (parent_index != (unsigned) -1); ++ has_incoming_virtual_edges_ |= is_virtual; ++ + if (incoming_edges_ == 0) + { + single_parent = parent_index; +@@ -408,7 +422,7 @@ struct graph_t + link_a.bias != link_b.bias) + return false; + +- if (!graph.vertices_[link_a.objidx].equals ( ++ if (!graph.vertices_[link_a.objidx].equals (link_a.objidx, link_b.objidx, + other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1)) + return false; + +@@ -456,8 +470,12 @@ struct graph_t + num_roots_for_space_.push (1); + bool removed_nil = false; + vertices_.alloc (objects.length); +- vertices_scratch_.alloc (objects.length); ++ ordering_.resize (objects.length); ++ ordering_scratch_.alloc (objects.length); ++ + unsigned count = objects.length; ++ unsigned order = objects.length; ++ unsigned skip = 0; + for (unsigned i = 0; i < count; i++) + { + // If this graph came from a serialization buffer object 0 is the +@@ -465,6 +483,9 @@ struct graph_t + if (i == 0 && !objects.arrayZ[i]) + { + removed_nil = true; ++ order--; ++ ordering_.resize(objects.length - 1); ++ skip++; + continue; + } + +@@ -474,6 +495,12 @@ struct graph_t + + check_success (v->link_positions_valid (count, removed_nil)); + ++ // To start we set the ordering to match the provided objects ++ // list. Note: objects are provided to us in reverse order (ie. ++ // the last object is the root). ++ unsigned obj_idx = i - skip; ++ ordering_[--order] = obj_idx; ++ + if (!removed_nil) continue; + // Fix indices to account for removed nil object. + for (auto& l : v->obj.all_links_writer ()) { +@@ -490,17 +517,20 @@ struct graph_t + + bool operator== (const graph_t& other) const + { +- return root ().equals (other.root (), *this, other, 0); ++ return root ().equals (root_idx(), other.root_idx(), other.root (), *this, other, 0); + } + + void print () const { +- for (int i = vertices_.length - 1; i >= 0; i--) ++ for (unsigned id : ordering_) + { +- const auto& v = vertices_[i]; +- printf("%d: %u [", i, (unsigned int)v.table_size()); ++ const auto& v = vertices_[id]; ++ printf("%u: %u [", id, (unsigned int)v.table_size()); + for (const auto &l : v.obj.real_links) { + printf("%u, ", l.objidx); + } ++ for (const auto &l : v.obj.virtual_links) { ++ printf("v%u, ", l.objidx); ++ } + printf("]\n"); + } + } +@@ -516,6 +546,7 @@ struct graph_t + { + return !successful || + vertices_.in_error () || ++ ordering_.in_error() || + num_roots_for_space_.in_error (); + } + +@@ -526,10 +557,10 @@ struct graph_t + + unsigned root_idx () const + { +- // Object graphs are in reverse order, the first object is at the end +- // of the vector. Since the graph is topologically sorted it's safe to ++ // First element of ordering_ is the root. ++ // Since the graph is topologically sorted it's safe to + // assume the first object has no incoming edges. +- return vertices_.length - 1; ++ return ordering_[0]; + } + + const hb_serialize_context_t::object_t& object (unsigned i) const +@@ -556,7 +587,7 @@ struct graph_t + link->width = 2; + link->objidx = child_id; + link->position = (char*) offset - (char*) v.obj.head; +- vertices_[child_id].add_parent (parent_id); ++ vertices_[child_id].add_parent (parent_id, false); + } + + /* +@@ -587,55 +618,51 @@ struct graph_t + + hb_priority_queue_t queue; + queue.alloc (vertices_.length); +- hb_vector_t &sorted_graph = vertices_scratch_; +- if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; +- hb_vector_t id_map; +- if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; ++ hb_vector_t &new_ordering = ordering_scratch_; ++ if (unlikely (!check_success (new_ordering.resize (vertices_.length)))) return; + + hb_vector_t removed_edges; + if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; + update_parents (); + + queue.insert (root ().modified_distance (0), root_idx ()); +- int new_id = root_idx (); + unsigned order = 1; ++ unsigned pos = 0; + while (!queue.in_error () && !queue.is_empty ()) + { + unsigned next_id = queue.pop_minimum().second; + +- sorted_graph[new_id] = std::move (vertices_[next_id]); +- const vertex_t& next = sorted_graph[new_id]; +- +- if (unlikely (!check_success(new_id >= 0))) { ++ if (unlikely (!check_success(pos < new_ordering.length))) { + // We are out of ids. Which means we've visited a node more than once. + // This graph contains a cycle which is not allowed. + DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle."); + return; + } +- +- id_map[next_id] = new_id--; ++ new_ordering[pos++] = next_id; ++ const vertex_t& next = vertices_[next_id]; + + for (const auto& link : next.obj.all_links ()) { + removed_edges[link.objidx]++; +- if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) ++ const auto& v = vertices_[link.objidx]; ++ if (!(v.incoming_edges () - removed_edges[link.objidx])) + // Add the order that the links were encountered to the priority. + // This ensures that ties between priorities objects are broken in a consistent + // way. More specifically this is set up so that if a set of objects have the same + // distance they'll be added to the topological order in the order that they are + // referenced from the parent object. +- queue.insert (vertices_[link.objidx].modified_distance (order++), ++ queue.insert (v.modified_distance (order++), + link.objidx); + } + } + + check_success (!queue.in_error ()); +- check_success (!sorted_graph.in_error ()); ++ check_success (!new_ordering.in_error ()); + +- check_success (remap_all_obj_indices (id_map, &sorted_graph)); +- vertices_ = std::move (sorted_graph); ++ hb_swap (ordering_, new_ordering); + +- if (!check_success (new_id == -1)) ++ if (!check_success (pos == vertices_.length)) { + print_orphaned_nodes (); ++ } + } + + /* +@@ -645,8 +672,8 @@ struct graph_t + */ + void find_space_roots (hb_set_t& visited, hb_set_t& roots) + { +- int root_index = (int) root_idx (); +- for (int i = root_index; i >= 0; i--) ++ unsigned root_index = root_idx (); ++ for (unsigned i : ordering_) + { + if (visited.has (i)) continue; + +@@ -829,7 +856,6 @@ struct graph_t + if (subgraph.in_error ()) + return false; + +- unsigned original_root_idx = root_idx (); + hb_map_t index_map; + bool made_changes = false; + for (auto entry : subgraph.iter ()) +@@ -852,14 +878,6 @@ struct graph_t + if (!made_changes) + return false; + +- if (original_root_idx != root_idx () +- && parents.has (original_root_idx)) +- { +- // If the root idx has changed since parents was determined, update root idx in parents +- parents.add (root_idx ()); +- parents.del (original_root_idx); +- } +- + auto new_subgraph = + + subgraph.keys () + | hb_map([&] (uint32_t node_idx) { +@@ -943,12 +961,14 @@ struct graph_t + /* + * Moves the child of old_parent_idx pointed to by old_offset to a new + * vertex at the new_offset. ++ * ++ * Returns the id of the child node that was moved. + */ + template +- void move_child (unsigned old_parent_idx, +- const O* old_offset, +- unsigned new_parent_idx, +- const O* new_offset) ++ unsigned move_child (unsigned old_parent_idx, ++ const O* old_offset, ++ unsigned new_parent_idx, ++ const O* new_offset) + { + distance_invalid = true; + positions_invalid = true; +@@ -965,10 +985,56 @@ struct graph_t + new_link->position = (const char*) new_offset - (const char*) new_v.obj.head; + + auto& child = vertices_[child_id]; +- child.add_parent (new_parent_idx); ++ child.add_parent (new_parent_idx, false); + + old_v.remove_real_link (child_id, old_offset); + child.remove_parent (old_parent_idx); ++ ++ return child_id; ++ } ++ ++ /* ++ * Moves all outgoing links in old parent that have ++ * a link position between [old_post_start, old_pos_end) ++ * to the new parent. Links are placed serially in the new ++ * parent starting at new_pos_start. ++ */ ++ template ++ void move_children (unsigned old_parent_idx, ++ unsigned old_pos_start, ++ unsigned old_pos_end, ++ unsigned new_parent_idx, ++ unsigned new_pos_start) ++ { ++ distance_invalid = true; ++ positions_invalid = true; ++ ++ auto& old_v = vertices_[old_parent_idx]; ++ auto& new_v = vertices_[new_parent_idx]; ++ ++ hb_vector_t old_links; ++ for (const auto& l : old_v.obj.real_links) ++ { ++ if (l.position < old_pos_start || l.position >= old_pos_end) ++ { ++ old_links.push(l); ++ continue; ++ } ++ ++ unsigned array_pos = l.position - old_pos_start; ++ ++ unsigned child_id = l.objidx; ++ auto* new_link = new_v.obj.real_links.push (); ++ new_link->width = O::static_size; ++ new_link->objidx = child_id; ++ new_link->position = new_pos_start + array_pos; ++ ++ auto& child = vertices_[child_id]; ++ child.add_parent (new_parent_idx, false); ++ child.remove_parent (old_parent_idx); ++ } ++ ++ old_v.obj.real_links = std::move (old_links); + } + + /* +@@ -1000,8 +1066,11 @@ struct graph_t + distance_invalid = true; + + auto* clone = vertices_.push (); ++ unsigned clone_idx = vertices_.length - 1; ++ ordering_.push(clone_idx); ++ + auto& child = vertices_[node_idx]; +- if (vertices_.in_error ()) { ++ if (vertices_.in_error () || ordering_.in_error()) { + return -1; + } + +@@ -1011,51 +1080,23 @@ struct graph_t + clone->space = child.space; + clone->reset_parents (); + +- unsigned clone_idx = vertices_.length - 2; + for (const auto& l : child.obj.real_links) + { + clone->obj.real_links.push (l); +- vertices_[l.objidx].add_parent (clone_idx); ++ vertices_[l.objidx].add_parent (clone_idx, false); + } + for (const auto& l : child.obj.virtual_links) + { + clone->obj.virtual_links.push (l); +- vertices_[l.objidx].add_parent (clone_idx); ++ vertices_[l.objidx].add_parent (clone_idx, true); + } + + check_success (!clone->obj.real_links.in_error ()); + check_success (!clone->obj.virtual_links.in_error ()); + +- // The last object is the root of the graph, so swap back the root to the end. +- // The root's obj idx does change, however since it's root nothing else refers to it. +- // all other obj idx's will be unaffected. +- hb_swap (vertices_[vertices_.length - 2], *clone); +- +- // Since the root moved, update the parents arrays of all children on the root. +- for (const auto& l : root ().obj.all_links ()) +- vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); +- + return clone_idx; + } + +- /* +- * Creates a copy of child and re-assigns the link from +- * parent to the clone. The copy is a shallow copy, objects +- * linked from child are not duplicated. +- * +- * Returns the index of the newly created duplicate. +- * +- * If the child_idx only has incoming edges from parent_idx, this +- * will do nothing and return the original child_idx. +- */ +- unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) +- { +- unsigned new_idx = duplicate (parent_idx, child_idx); +- if (new_idx == (unsigned) -1) return child_idx; +- return new_idx; +- } +- +- + /* + * Creates a copy of child and re-assigns the link from + * parent to the clone. The copy is a shallow copy, objects +@@ -1073,10 +1114,15 @@ struct graph_t + const auto& child = vertices_[child_idx]; + unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); + +- if (child.incoming_edges () <= links_to_child) ++ if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. ++ // ++ // We don't allow duplication of nodes with incoming virtual edges because we don't track ++ // the number of virtual vs real incoming edges. As a result we can't tell if a node ++ // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed ++ // to by virtual edges). + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u => %u", + parent_idx, child_idx); + return -1; +@@ -1091,12 +1137,15 @@ struct graph_t + if (parent_idx == clone_idx) parent_idx++; + + auto& parent = vertices_[parent_idx]; ++ unsigned count = 0; ++ unsigned num_real = parent.obj.real_links.length; + for (auto& l : parent.obj.all_links_writer ()) + { ++ count++; + if (l.objidx != child_idx) + continue; + +- reassign_link (l, parent_idx, clone_idx); ++ reassign_link (l, parent_idx, clone_idx, count > num_real); + } + + return clone_idx; +@@ -1129,10 +1178,15 @@ struct graph_t + links_to_child += child.incoming_edges_from_parent(parent_idx); + } + +- if (child.incoming_edges () <= links_to_child) ++ if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. ++ // ++ // We don't allow duplication of nodes with incoming virtual edges because we don't track ++ // the number of virtual vs real incoming edges. As a result we can't tell if a node ++ // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed ++ // to by virtual edges). + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + return -1; + } +@@ -1146,12 +1200,15 @@ struct graph_t + // duplicate shifts the root node idx, so if parent_idx was root update it. + if (parent_idx == clone_idx) parent_idx++; + auto& parent = vertices_[parent_idx]; ++ unsigned count = 0; ++ unsigned num_real = parent.obj.real_links.length; + for (auto& l : parent.obj.all_links_writer ()) + { ++ count++; + if (l.objidx != child_idx) + continue; + +- reassign_link (l, parent_idx, clone_idx); ++ reassign_link (l, parent_idx, clone_idx, count > num_real); + } + } + +@@ -1168,7 +1225,10 @@ struct graph_t + distance_invalid = true; + + auto* clone = vertices_.push (); +- if (vertices_.in_error ()) { ++ unsigned clone_idx = vertices_.length - 1; ++ ordering_.push(clone_idx); ++ ++ if (vertices_.in_error () || ordering_.in_error()) { + return -1; + } + +@@ -1177,18 +1237,35 @@ struct graph_t + clone->distance = 0; + clone->space = 0; + +- unsigned clone_idx = vertices_.length - 2; ++ return clone_idx; ++ } + +- // The last object is the root of the graph, so swap back the root to the end. +- // The root's obj idx does change, however since it's root nothing else refers to it. +- // all other obj idx's will be unaffected. +- hb_swap (vertices_[vertices_.length - 2], *clone); ++ /* ++ * Creates a new child node and remap the old child to it. ++ * ++ * Returns the index of the newly created child. ++ * ++ */ ++ unsigned remap_child (unsigned parent_idx, unsigned old_child_idx) ++ { ++ unsigned new_child_idx = duplicate (old_child_idx); ++ if (new_child_idx == (unsigned) -1) return -1; + +- // Since the root moved, update the parents arrays of all children on the root. +- for (const auto& l : root ().obj.all_links ()) +- vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); ++ auto& parent = vertices_[parent_idx]; ++ for (auto& l : parent.obj.real_links) ++ { ++ if (l.objidx != old_child_idx) ++ continue; ++ reassign_link (l, parent_idx, new_child_idx, false); ++ } + +- return clone_idx; ++ for (auto& l : parent.obj.virtual_links) ++ { ++ if (l.objidx != old_child_idx) ++ continue; ++ reassign_link (l, parent_idx, new_child_idx, true); ++ } ++ return new_child_idx; + } + + /* +@@ -1279,6 +1356,7 @@ struct graph_t + if (!DEBUG_ENABLED(SUBSET_REPACK)) return; + + DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); ++ + parents_invalid = true; + update_parents(); + +@@ -1348,7 +1426,8 @@ struct graph_t + size_t total_size = 0; + unsigned count = vertices_.length; + for (unsigned i = 0; i < count; i++) { +- size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head; ++ const auto& obj = vertices_.arrayZ[i].obj; ++ size_t size = obj.tail - obj.head; + total_size += size; + } + return total_size; +@@ -1398,8 +1477,11 @@ struct graph_t + + for (unsigned p = 0; p < count; p++) + { +- for (auto& l : vertices_.arrayZ[p].obj.all_links ()) +- vertices_[l.objidx].add_parent (p); ++ for (auto& l : vertices_.arrayZ[p].obj.real_links) ++ vertices_[l.objidx].add_parent (p, false); ++ ++ for (auto& l : vertices_.arrayZ[p].obj.virtual_links) ++ vertices_[l.objidx].add_parent (p, true); + } + + for (unsigned i = 0; i < count; i++) +@@ -1418,7 +1500,7 @@ struct graph_t + if (!positions_invalid) return; + + unsigned current_pos = 0; +- for (int i = root_idx (); i >= 0; i--) ++ for (unsigned i : ordering_) + { + auto& v = vertices_[i]; + v.start = current_pos; +@@ -1450,11 +1532,11 @@ struct graph_t + unsigned count = vertices_.length; + for (unsigned i = 0; i < count; i++) + vertices_.arrayZ[i].distance = hb_int_max (int64_t); +- vertices_.tail ().distance = 0; ++ vertices_[root_idx ()].distance = 0; + + hb_priority_queue_t queue; + queue.alloc (count); +- queue.insert (0, vertices_.length - 1); ++ queue.insert (0, root_idx ()); + + hb_vector_t visited; + visited.resize (vertices_.length); +@@ -1464,22 +1546,23 @@ struct graph_t + unsigned next_idx = queue.pop_minimum ().second; + if (visited[next_idx]) continue; + const auto& next = vertices_[next_idx]; +- int64_t next_distance = vertices_[next_idx].distance; ++ int64_t next_distance = next.distance; + visited[next_idx] = true; + + for (const auto& link : next.obj.all_links ()) + { + if (visited[link.objidx]) continue; + +- const auto& child = vertices_.arrayZ[link.objidx].obj; ++ auto& child_v = vertices_.arrayZ[link.objidx]; ++ const auto& child = child_v.obj; + unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide + int64_t child_weight = (child.tail - child.head) + +- ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1); ++ ((int64_t) 1 << (link_width * 8)) * (child_v.space + 1); + int64_t child_distance = next_distance + child_weight; + +- if (child_distance < vertices_.arrayZ[link.objidx].distance) ++ if (child_distance < child_v.distance) + { +- vertices_.arrayZ[link.objidx].distance = child_distance; ++ child_v.distance = child_distance; + queue.insert (child_distance, link.objidx); + } + } +@@ -1502,12 +1585,13 @@ struct graph_t + */ + void reassign_link (hb_serialize_context_t::object_t::link_t& link, + unsigned parent_idx, +- unsigned new_idx) ++ unsigned new_idx, ++ bool is_virtual) + { + unsigned old_idx = link.objidx; + link.objidx = new_idx; + vertices_[old_idx].remove_parent (parent_idx); +- vertices_[new_idx].add_parent (parent_idx); ++ vertices_[new_idx].add_parent (parent_idx, is_virtual); + } + + /* +@@ -1521,36 +1605,21 @@ struct graph_t + if (!id_map) return; + for (unsigned i : subgraph) + { +- for (auto& link : vertices_[i].obj.all_links_writer ()) ++ auto& obj = vertices_[i].obj; ++ unsigned num_real = obj.real_links.length; ++ unsigned count = 0; ++ for (auto& link : obj.all_links_writer ()) + { ++ count++; + const uint32_t *v; + if (!id_map.has (link.objidx, &v)) continue; +- if (only_wide && !(link.width == 4 && !link.is_signed)) continue; ++ if (only_wide && (link.is_signed || (link.width != 4 && link.width != 3))) continue; + +- reassign_link (link, i, *v); ++ reassign_link (link, i, *v, count > num_real); + } + } + } + +- /* +- * Updates all objidx's in all links using the provided mapping. +- */ +- bool remap_all_obj_indices (const hb_vector_t& id_map, +- hb_vector_t* sorted_graph) const +- { +- unsigned count = sorted_graph->length; +- for (unsigned i = 0; i < count; i++) +- { +- if (!(*sorted_graph)[i].remap_parents (id_map)) +- return false; +- for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ()) +- { +- link.objidx = id_map[link.objidx]; +- } +- } +- return true; +- } +- + /* + * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. + * For this search the graph is treated as being undirected. +@@ -1586,7 +1655,16 @@ struct graph_t + public: + // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. + hb_vector_t vertices_; +- hb_vector_t vertices_scratch_; ++ ++ // Specifies the current topological ordering of this graph ++ // ++ // ordering_[pos] = obj index ++ // ++ // specifies that the 'pos'th spot is filled by the object ++ // given by obj index. ++ hb_vector_t ordering_; ++ hb_vector_t ordering_scratch_; ++ + private: + bool parents_invalid; + bool distance_invalid; +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh +index b25d538fe3d..8969d007879 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh +@@ -41,6 +41,7 @@ struct gsubgpos_graph_context_t + unsigned lookup_list_index; + hb_hashmap_t lookups; + hb_hashmap_t subtable_to_extension; ++ hb_hashmap_t> split_subtables; + + HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_, + graph_t& graph_); +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh +index 7ad2ba430b7..ea6bcd239a0 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh +@@ -27,9 +27,11 @@ + #include "graph.hh" + #include "../hb-ot-layout-gsubgpos.hh" + #include "../OT/Layout/GSUB/ExtensionSubst.hh" ++#include "../OT/Layout/GSUB/SubstLookupSubTable.hh" + #include "gsubgpos-context.hh" + #include "pairpos-graph.hh" + #include "markbasepos-graph.hh" ++#include "ligature-graph.hh" + + #ifndef GRAPH_GSUBGPOS_GRAPH_HH + #define GRAPH_GSUBGPOS_GRAPH_HH +@@ -85,6 +87,12 @@ struct Lookup : public OT::Lookup + return lookupType == extension_type (table_tag); + } + ++ bool use_mark_filtering_set () const ++ { ++ unsigned flag = lookupFlag; ++ return flag & 0x0010u; ++ } ++ + bool make_extension (gsubgpos_graph_context_t& c, + unsigned this_index) + { +@@ -120,22 +128,18 @@ struct Lookup : public OT::Lookup + unsigned type = lookupType; + bool is_ext = is_extension (c.table_tag); + +- if (c.table_tag != HB_OT_TAG_GPOS) ++ if (c.table_tag != HB_OT_TAG_GPOS && c.table_tag != HB_OT_TAG_GSUB) + return true; + +- if (!is_ext && +- type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair && +- type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) ++ if (!is_ext && !is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) + return true; + + hb_vector_t>> all_new_subtables; + for (unsigned i = 0; i < subTable.len; i++) + { + unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); +- unsigned parent_index = this_index; + if (is_ext) { + unsigned ext_subtable_index = subtable_index; +- parent_index = ext_subtable_index; + ExtensionFormat1* extension = + (ExtensionFormat1*) + c.graph.object (ext_subtable_index).head; +@@ -144,26 +148,47 @@ struct Lookup : public OT::Lookup + + subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); + type = extension->get_lookup_type (); +- if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair +- && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) ++ if (!is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) + continue; + } + +- hb_vector_t new_sub_tables; +- switch (type) ++ hb_vector_t* split_result; ++ if (c.split_subtables.has (subtable_index, &split_result)) ++ { ++ if (split_result->length == 0) ++ continue; ++ all_new_subtables.push (hb_pair(i, *split_result)); ++ } ++ else + { +- case 2: +- new_sub_tables = split_subtable (c, parent_index, subtable_index); break; +- case 4: +- new_sub_tables = split_subtable (c, parent_index, subtable_index); break; +- default: +- break; ++ hb_vector_t new_sub_tables; ++ ++ if (c.table_tag == HB_OT_TAG_GPOS) { ++ switch (type) ++ { ++ case 2: ++ new_sub_tables = split_subtable (c, subtable_index); break; ++ case 4: ++ new_sub_tables = split_subtable (c, subtable_index); break; ++ default: ++ break; ++ } ++ } else if (c.table_tag == HB_OT_TAG_GSUB) { ++ switch (type) ++ { ++ case 4: ++ new_sub_tables = split_subtable (c, subtable_index); break; ++ default: ++ break; ++ } ++ } ++ ++ if (new_sub_tables.in_error ()) return false; ++ ++ c.split_subtables.set (subtable_index, new_sub_tables); ++ if (new_sub_tables) ++ all_new_subtables.push (hb_pair (i, std::move (new_sub_tables))); + } +- if (new_sub_tables.in_error ()) return false; +- if (!new_sub_tables) continue; +- hb_pair_t>* entry = all_new_subtables.push (); +- entry->first = i; +- entry->second = std::move (new_sub_tables); + } + + if (all_new_subtables) { +@@ -175,30 +200,29 @@ struct Lookup : public OT::Lookup + + template + hb_vector_t split_subtable (gsubgpos_graph_context_t& c, +- unsigned parent_idx, + unsigned objidx) + { + T* sub_table = (T*) c.graph.object (objidx).head; + if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx])) + return hb_vector_t (); + +- return sub_table->split_subtables (c, parent_idx, objidx); ++ return sub_table->split_subtables (c, objidx); + } + + bool add_sub_tables (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned type, +- hb_vector_t>>& subtable_ids) ++ const hb_vector_t>>& subtable_ids) + { + bool is_ext = is_extension (c.table_tag); +- auto& v = c.graph.vertices_[this_index]; ++ auto* v = &c.graph.vertices_[this_index]; + fix_existing_subtable_links (c, this_index, subtable_ids); + + unsigned new_subtable_count = 0; + for (const auto& p : subtable_ids) + new_subtable_count += p.second.length; + +- size_t new_size = v.table_size () ++ size_t new_size = v->table_size () + + new_subtable_count * OT::Offset16::static_size; + char* buffer = (char*) hb_calloc (1, new_size); + if (!buffer) return false; +@@ -207,10 +231,13 @@ struct Lookup : public OT::Lookup + hb_free (buffer); + return false; + } +- hb_memcpy (buffer, v.obj.head, v.table_size()); ++ hb_memcpy (buffer, v->obj.head, v->table_size()); + +- v.obj.head = buffer; +- v.obj.tail = buffer + new_size; ++ if (use_mark_filtering_set ()) ++ hb_memcpy (buffer + new_size - 2, v->obj.tail - 2, 2); ++ ++ v->obj.head = buffer; ++ v->obj.tail = buffer + new_size; + + Lookup* new_lookup = (Lookup*) buffer; + +@@ -226,21 +253,23 @@ struct Lookup : public OT::Lookup + if (is_ext) + { + unsigned ext_id = create_extension_subtable (c, subtable_id, type); +- c.graph.vertices_[subtable_id].add_parent (ext_id); ++ c.graph.vertices_[subtable_id].add_parent (ext_id, false); + subtable_id = ext_id; ++ // the reference to v may have changed on adding a node, so reassign it. ++ v = &c.graph.vertices_[this_index]; + } + +- auto* link = v.obj.real_links.push (); ++ auto* link = v->obj.real_links.push (); + link->width = 2; + link->objidx = subtable_id; + link->position = (char*) &new_lookup->subTable[offset_index++] - + (char*) new_lookup; +- c.graph.vertices_[subtable_id].add_parent (this_index); ++ c.graph.vertices_[subtable_id].add_parent (this_index, false); + } + } + + // Repacker sort order depends on link order, which we've messed up so resort it. +- v.obj.real_links.qsort (); ++ v->obj.real_links.qsort (); + + // The head location of the lookup has changed, invalidating the lookups map entry + // in the context. Update the map. +@@ -250,17 +279,15 @@ struct Lookup : public OT::Lookup + + void fix_existing_subtable_links (gsubgpos_graph_context_t& c, + unsigned this_index, +- hb_vector_t>>& subtable_ids) ++ const hb_vector_t>>& subtable_ids) + { + auto& v = c.graph.vertices_[this_index]; +- Lookup* lookup = (Lookup*) v.obj.head; +- + unsigned shift = 0; + for (const auto& p : subtable_ids) + { + unsigned insert_index = p.first + shift; + unsigned pos_offset = p.second.length * OT::Offset16::static_size; +- unsigned insert_offset = (char*) &lookup->subTable[insert_index] - (char*) lookup; ++ unsigned insert_offset = Lookup::min_size + insert_index * OT::Offset16::static_size; + shift += p.second.length; + + for (auto& l : v.obj.all_links_writer ()) +@@ -326,7 +353,7 @@ struct Lookup : public OT::Lookup + + // Make extension point at the subtable. + auto& ext_vertex = c.graph.vertices_[ext_index]; +- ext_vertex.add_parent (lookup_index); ++ ext_vertex.add_parent (lookup_index, false); + if (!existing_ext_index) + subtable_vertex.remap_parent (lookup_index, ext_index); + +@@ -334,6 +361,19 @@ struct Lookup : public OT::Lookup + } + + private: ++ bool is_supported_gsub_type(unsigned type, gsubgpos_graph_context_t& c) const { ++ return (c.table_tag == HB_OT_TAG_GSUB) && ( ++ type == OT::Layout::GSUB_impl::SubstLookupSubTable::Type::Ligature ++ ); ++ } ++ ++ bool is_supported_gpos_type(unsigned type, gsubgpos_graph_context_t& c) const { ++ return (c.table_tag == HB_OT_TAG_GPOS) && ( ++ type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair || ++ type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase ++ ); ++ } ++ + unsigned extension_type (hb_tag_t table_tag) const + { + switch (table_tag) +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh +index fb4166128a9..6d1a3d4ae4b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh +@@ -212,7 +212,6 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2 split_subtables (gsubgpos_graph_context_t& c, +- unsigned parent_index, + unsigned this_index) + { + hb_set_t visited; +@@ -265,7 +264,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2 split_subtables (gsubgpos_graph_context_t& c, +- unsigned parent_index, + unsigned this_index) + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: +- return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); ++ return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, this_index); + #ifndef HB_NO_BEYOND_64K + case 2: HB_FALLTHROUGH; + // Don't split 24bit MarkBasePos's. +@@ -496,10 +494,10 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; +- if (vertex_len < u.format.get_size ()) return false; ++ if (vertex_len < u.format.v.get_size ()) return false; + hb_barrier (); + +- switch (u.format) { ++ switch (u.format.v) { + case 1: + return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex); + #ifndef HB_NO_BEYOND_64K +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh +index fd46861de46..85950b63457 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh +@@ -49,7 +49,6 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 split_subtables (gsubgpos_graph_context_t& c, +- unsigned parent_index, + unsigned this_index) + { + hb_set_t visited; +@@ -84,7 +83,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 (split_context, split_points); +@@ -207,7 +206,6 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 split_subtables (gsubgpos_graph_context_t& c, +- unsigned parent_index, + unsigned this_index) + { + const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; +@@ -291,7 +289,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4width = SmallTypes::size; + class_def_link->objidx = class_def_2_id; + class_def_link->position = 10; +- graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id); ++ graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id, false); + graph.duplicate (pair_pos_prime_id, class_def_2_id); + + return pair_pos_prime_id; +@@ -607,14 +605,13 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 split_subtables (gsubgpos_graph_context_t& c, +- unsigned parent_index, + unsigned this_index) + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: +- return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); ++ return ((PairPosFormat1*)(&u.format1))->split_subtables (c, this_index); + case 2: +- return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index); ++ return ((PairPosFormat2*)(&u.format2))->split_subtables (c, this_index); + #ifndef HB_NO_BEYOND_64K + case 3: HB_FALLTHROUGH; + case 4: HB_FALLTHROUGH; +@@ -628,10 +625,10 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; +- if (vertex_len < u.format.get_size ()) return false; ++ if (vertex_len < u.format.v.get_size ()) return false; + hb_barrier (); + +- switch (u.format) { ++ switch (u.format.v) { + case 1: + return ((PairPosFormat1*)(&u.format1))->sanitize (vertex); + case 2: +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh b/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh +index 06e4bf44d8e..37fac8909e5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh +@@ -113,7 +113,7 @@ will_overflow (graph_t& graph, + + hb_hashmap_t record_set; + const auto& vertices = graph.vertices_; +- for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) ++ for (unsigned parent_idx : graph.ordering_) + { + // Don't need to check virtual links for overflow + for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links) +@@ -172,14 +172,16 @@ void print_overflows (graph_t& graph, + template inline void + serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, + char* head, ++ unsigned size, ++ const hb_vector_t& id_map, + hb_serialize_context_t* c) + { ++ assert(link.position + link.width <= size); ++ + OT::Offset* offset = reinterpret_cast*> (head + link.position); + *offset = 0; + c->add_link (*offset, +- // serializer has an extra nil object at the start of the +- // object array. So all id's are +1 of what our id's are. +- link.objidx + 1, ++ id_map[link.objidx], + (hb_serialize_context_t::whence_t) link.whence, + link.bias); + } +@@ -187,6 +189,8 @@ serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, + inline + void serialize_link (const hb_serialize_context_t::object_t::link_t& link, + char* head, ++ unsigned size, ++ const hb_vector_t& id_map, + hb_serialize_context_t* c) + { + switch (link.width) +@@ -197,21 +201,21 @@ void serialize_link (const hb_serialize_context_t::object_t::link_t& link, + case 4: + if (link.is_signed) + { +- serialize_link_of_type (link, head, c); ++ serialize_link_of_type (link, head, size, id_map, c); + } else { +- serialize_link_of_type (link, head, c); ++ serialize_link_of_type (link, head, size, id_map, c); + } + return; + case 2: + if (link.is_signed) + { +- serialize_link_of_type (link, head, c); ++ serialize_link_of_type (link, head, size, id_map, c); + } else { +- serialize_link_of_type (link, head, c); ++ serialize_link_of_type (link, head, size, id_map, c); + } + return; + case 3: +- serialize_link_of_type (link, head, c); ++ serialize_link_of_type (link, head, size, id_map, c); + return; + default: + // Unexpected link width. +@@ -237,25 +241,36 @@ inline hb_blob_t* serialize (const graph_t& graph) + + c.start_serialize (); + const auto& vertices = graph.vertices_; +- for (unsigned i = 0; i < vertices.length; i++) { ++ ++ // Objects are placed in the serializer in reverse order since children need ++ // to be inserted before their parents. ++ ++ // Maps from our obj id's to the id's used during this serialization. ++ hb_vector_t id_map; ++ id_map.resize(graph.ordering_.length); ++ for (int pos = graph.ordering_.length - 1; pos >= 0; pos--) { ++ unsigned i = graph.ordering_[pos]; + c.push (); + +- size_t size = vertices[i].obj.tail - vertices[i].obj.head; ++ auto& v = vertices[i]; ++ ++ size_t size = v.obj.tail - v.obj.head; ++ + char* start = c.allocate_size (size); + if (!start) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); + return nullptr; + } + +- hb_memcpy (start, vertices[i].obj.head, size); ++ hb_memcpy (start, v.obj.head, size); + + // Only real links needs to be serialized. +- for (const auto& link : vertices[i].obj.real_links) +- serialize_link (link, start, &c); ++ for (const auto& link : v.obj.real_links) ++ serialize_link (link, start, size, id_map, &c); + + // All duplications are already encoded in the graph, so don't + // enable sharing during packing. +- c.pop_pack (false); ++ id_map[i] = c.pop_pack (false); + } + c.end_serialize (); + +diff --git a/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh b/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh +index 61fd7c2d2ff..f1f86e332db 100644 +--- a/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh ++++ b/src/java.desktop/share/native/libharfbuzz/graph/split-helpers.hh +@@ -49,7 +49,7 @@ hb_vector_t actuate_subtable_split (Context& split_context, + if (id == (unsigned) -1) + { + new_objects.reset (); +- new_objects.allocated = -1; // mark error ++ new_objects.ensure_error (); + return new_objects; + } + new_objects.push (id); +@@ -58,7 +58,7 @@ hb_vector_t actuate_subtable_split (Context& split_context, + if (!split_context.shrink (split_points[0])) + { + new_objects.reset (); +- new_objects.allocated = -1; // mark error ++ new_objects.ensure_error (); + } + + return new_objects; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh +index d5a44bf473c..d2ce32616be 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh +@@ -47,8 +47,7 @@ using namespace OT; + + 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 + { +@@ -79,7 +78,10 @@ struct hb_aat_scratch_t + { + hb_bit_set_t *s = buffer_glyph_set.get_acquire (); + if (s && buffer_glyph_set.cmpexch (s, nullptr)) ++ { ++ s->clear (); + return s; ++ } + + s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t)); + if (unlikely (!s)) +@@ -124,13 +126,14 @@ struct hb_aat_apply_context_t : + const OT::GDEF &gdef; + bool has_glyph_classes; + const hb_sorted_vector_t *range_flags = nullptr; ++ hb_mask_t subtable_flags = 0; ++ bool buffer_is_reversed = false; ++ // Caches + bool using_buffer_glyph_set = false; + hb_bit_set_t *buffer_glyph_set = nullptr; +- const hb_bit_set_t *left_set = nullptr; +- const hb_bit_set_t *right_set = nullptr; +- const hb_bit_set_t *machine_glyph_set = nullptr; ++ const hb_bit_set_t *first_set = nullptr; ++ const hb_bit_set_t *second_set = nullptr; + hb_aat_class_cache_t *machine_class_cache = nullptr; +- hb_mask_t subtable_flags = 0; + + /* Unused. For debug tracing only. */ + unsigned int lookup_index; +@@ -146,6 +149,12 @@ struct hb_aat_apply_context_t : + + void set_lookup_index (unsigned int i) { lookup_index = i; } + ++ void reverse_buffer () ++ { ++ buffer->reverse (); ++ buffer_is_reversed = !buffer_is_reversed; ++ } ++ + void setup_buffer_glyph_set () + { + using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set; +@@ -156,11 +165,11 @@ struct hb_aat_apply_context_t : + bool buffer_intersects_machine () const + { + if (likely (using_buffer_glyph_set)) +- return buffer_glyph_set->intersects (*machine_glyph_set); ++ return buffer_glyph_set->intersects (*first_set); + + // Faster for shorter buffers. + for (unsigned i = 0; i < buffer->len; i++) +- if (machine_glyph_set->has (buffer->info[i].codepoint)) ++ if (first_set->has (buffer->info[i].codepoint)) + return true; + return false; + } +@@ -639,6 +648,23 @@ struct LookupFormat10 + glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); + } + ++ template ++ void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const ++ { ++ if (unlikely (!glyphCount)) return; ++ if (firstGlyph == DELETED_GLYPH) return; ++ const HBUINT8 *p = valueArrayZ.arrayZ; ++ for (unsigned i = 0; i < glyphCount; i++) ++ { ++ unsigned int v = 0; ++ unsigned int count = valueSize; ++ for (unsigned int j = 0; j < count; j++) ++ v = (v << 8) | *p++; ++ if (filter (v)) ++ glyphs.add (firstGlyph + i); ++ } ++ } ++ + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +@@ -666,7 +692,7 @@ struct Lookup + { + const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return u.format0.get_value (glyph_id, num_glyphs); + case 2: hb_barrier (); return u.format2.get_value (glyph_id); + case 4: hb_barrier (); return u.format4.get_value (glyph_id); +@@ -678,7 +704,7 @@ struct Lookup + + const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { +- switch (u.format) { ++ switch (u.format.v) { + /* Format 10 cannot return a pointer. */ + case 10: hb_barrier (); return u.format10.get_value_or_null (glyph_id); + default: +@@ -690,7 +716,7 @@ struct Lookup + template + void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); u.format0.collect_glyphs (glyphs, num_glyphs); return; + case 2: hb_barrier (); u.format2.collect_glyphs (glyphs); return; + case 4: hb_barrier (); u.format4.collect_glyphs (glyphs); return; +@@ -703,12 +729,13 @@ struct Lookup + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return; + case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return; + case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; + case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; + case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; ++ case 10: hb_barrier (); u.format10.collect_glyphs_filtered (glyphs, filter); return; + default:return; + } + } +@@ -724,9 +751,9 @@ struct Lookup + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); +@@ -739,9 +766,9 @@ struct Lookup + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, base)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c, base)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c, base)); +@@ -754,7 +781,7 @@ struct Lookup + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + LookupFormat0 format0; + LookupFormat2 format2; + LookupFormat4 format4; +@@ -763,7 +790,7 @@ struct Lookup + LookupFormat10 format10; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); + +@@ -838,11 +865,6 @@ struct StateTable + STATE_START_OF_LINE = 1, + }; + +- template +- void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const +- { +- (this+classTable).collect_glyphs (glyphs, num_glyphs); +- } + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const + { +@@ -1082,6 +1104,8 @@ struct SubtableGlyphCoverage + 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))) +@@ -1192,11 +1216,24 @@ struct StateTableDriver + int state = StateTableT::STATE_START_OF_TEXT; + // If there's only one range, we already checked the flag. + auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr; ++ const bool start_state_safe_to_break_eot = ++ !c->table->is_actionable (machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_END_OF_TEXT)); + for (buffer->idx = 0; buffer->successful;) + { +- /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ +- if (last_range) ++ unsigned int klass = likely (buffer->idx < buffer->len) ? ++ machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : ++ (unsigned) CLASS_END_OF_TEXT; ++ resume: ++ DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); ++ const EntryT &entry = machine.get_entry (state, klass); ++ const int next_state = machine.new_state (entry.newState); ++ ++ bool is_not_epsilon_transition = !(entry.flags & Flags::DontAdvance); ++ bool is_not_actionable = !c->table->is_actionable (entry); ++ ++ if (unlikely (last_range)) + { ++ /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ + auto *range = last_range; + if (buffer->idx < buffer->len) + { +@@ -1211,7 +1248,7 @@ struct StateTableDriver + } + if (!(range->flags & ac->subtable_flags)) + { +- if (buffer->idx == buffer->len || unlikely (!buffer->successful)) ++ if (buffer->idx == buffer->len) + break; + + state = StateTableT::STATE_START_OF_TEXT; +@@ -1219,13 +1256,42 @@ struct StateTableDriver + continue; + } + } ++ else ++ { ++ // Fast path for when transitioning from start-state to start-state with ++ // no action and advancing. Do so as long as the class remains the same. ++ // This is common with runs of non-actionable glyphs. ++ ++ bool is_null_transition = state == StateTableT::STATE_START_OF_TEXT && ++ next_state == StateTableT::STATE_START_OF_TEXT && ++ start_state_safe_to_break_eot && ++ is_not_actionable && ++ is_not_epsilon_transition && ++ !last_range; ++ ++ if (is_null_transition) ++ { ++ unsigned old_klass = klass; ++ do ++ { ++ c->transition (buffer, this, entry); + +- unsigned int klass = likely (buffer->idx < buffer->len) ? +- machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : +- (unsigned) CLASS_END_OF_TEXT; +- DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); +- const EntryT &entry = machine.get_entry (state, klass); +- const int next_state = machine.new_state (entry.newState); ++ if (buffer->idx == buffer->len || !buffer->successful) ++ break; ++ ++ (void) buffer->next_glyph (); ++ ++ klass = likely (buffer->idx < buffer->len) ? ++ machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : ++ (unsigned) CLASS_END_OF_TEXT; ++ } while (klass == old_klass); ++ ++ if (buffer->idx == buffer->len || !buffer->successful) ++ break; ++ ++ goto resume; ++ } ++ } + + /* Conditions under which it's guaranteed safe-to-break before current glyph: + * +@@ -1292,10 +1358,10 @@ struct StateTableDriver + state = next_state; + DEBUG_MSG (APPLY, nullptr, "s%d", state); + +- if (buffer->idx == buffer->len || unlikely (!buffer->successful)) ++ if (buffer->idx == buffer->len) + break; + +- if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0) ++ if (is_not_epsilon_transition || buffer->max_ops-- <= 0) + (void) buffer->next_glyph (); + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh +index ca4f2243346..2a6b813972f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh +@@ -120,12 +120,12 @@ struct KerxSubTableFormat0 + } + + template +- void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const ++ void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const + { + for (const KernPair& pair : pairs) + { +- left_set.add (pair.left); +- right_set.add (pair.right); ++ first_set.add (pair.left); ++ second_set.add (pair.right); + } + } + +@@ -140,7 +140,7 @@ struct KerxSubTableFormat0 + + int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { +- if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; ++ if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; + return table.get_kerning (left, right, c); + } + }; +@@ -396,10 +396,10 @@ struct KerxSubTableFormat1 + } + + template +- void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const ++ void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const + { +- machine.collect_initial_glyphs (left_set, num_glyphs, *this); +- //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning ++ machine.collect_initial_glyphs (first_set, num_glyphs, *this); ++ //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning + } + + protected: +@@ -451,10 +451,10 @@ struct KerxSubTableFormat2 + } + + template +- void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const ++ void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const + { +- (this+leftClassTable).collect_glyphs (left_set, num_glyphs); +- (this+rightClassTable).collect_glyphs (right_set, num_glyphs); ++ (this+leftClassTable).collect_glyphs (first_set, num_glyphs); ++ (this+rightClassTable).collect_glyphs (second_set, num_glyphs); + } + + struct accelerator_t +@@ -468,7 +468,7 @@ struct KerxSubTableFormat2 + + int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { +- if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; ++ if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; + return table.get_kerning (left, right, c); + } + }; +@@ -629,6 +629,8 @@ struct KerxSubTableFormat4 + } + o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_MARK; + o.attach_chain() = (int) mark - (int) buffer->idx; ++ if (c->buffer_is_reversed) ++ o.attach_chain() = -o.attach_chain(); + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + } + +@@ -671,10 +673,10 @@ struct KerxSubTableFormat4 + } + + template +- void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const ++ void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const + { +- machine.collect_initial_glyphs (left_set, num_glyphs, *this); +- //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning ++ machine.collect_initial_glyphs (first_set, num_glyphs, *this); ++ //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning + } + + protected: +@@ -762,19 +764,19 @@ struct KerxSubTableFormat6 + } + + template +- void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const ++ void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const + { + if (is_long ()) + { + const auto &t = u.l; +- (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); +- (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); ++ (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); ++ (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); + } + else + { + const auto &t = u.s; +- (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); +- (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); ++ (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); ++ (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); + } + } + +@@ -789,7 +791,7 @@ struct KerxSubTableFormat6 + + int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { +- if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; ++ if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; + return table.get_kerning (left, right, c); + } + }; +@@ -878,15 +880,15 @@ struct KerxSubTable + } + + template +- void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const ++ void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const + { + unsigned int subtable_type = get_type (); + switch (subtable_type) { +- case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; +- case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; +- case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; +- case 4: u.format4.collect_glyphs (left_set, right_set, num_glyphs); return; +- case 6: u.format6.collect_glyphs (left_set, right_set, num_glyphs); return; ++ case 0: u.format0.collect_glyphs (first_set, second_set, num_glyphs); return; ++ case 1: u.format1.collect_glyphs (first_set, second_set, num_glyphs); return; ++ case 2: u.format2.collect_glyphs (first_set, second_set, num_glyphs); return; ++ case 4: u.format4.collect_glyphs (first_set, second_set, num_glyphs); return; ++ case 6: u.format6.collect_glyphs (first_set, second_set, num_glyphs); return; + default: return; + } + } +@@ -923,8 +925,8 @@ struct KerxSubTable + + struct kern_subtable_accelerator_data_t + { +- hb_bit_set_t left_set; +- hb_bit_set_t right_set; ++ hb_bit_set_t first_set; ++ hb_bit_set_t second_set; + mutable hb_aat_class_cache_t class_cache; + }; + +@@ -1017,9 +1019,8 @@ struct KerxTable + if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) + goto skip; + +- c->left_set = &subtable_accel.left_set; +- c->right_set = &subtable_accel.right_set; +- c->machine_glyph_set = &subtable_accel.left_set; ++ c->first_set = &subtable_accel.first_set; ++ c->second_set = &subtable_accel.second_set; + c->machine_class_cache = &subtable_accel.class_cache; + + if (!c->buffer_intersects_machine ()) +@@ -1051,8 +1052,8 @@ struct KerxTable + } + } + +- if (reverse) +- c->buffer->reverse (); ++ if (reverse != c->buffer_is_reversed) ++ c->reverse_buffer (); + + { + /* See comment in sanitize() for conditional here. */ +@@ -1060,15 +1061,14 @@ struct KerxTable + ret |= st->dispatch (c); + } + +- if (reverse) +- c->buffer->reverse (); +- + (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index); + + skip: + st = &StructAfter (*st); + c->set_lookup_index (c->lookup_index + 1); + } ++ if (c->buffer_is_reversed) ++ c->reverse_buffer (); + + return ret; + } +@@ -1133,7 +1133,7 @@ struct KerxTable + if (unlikely (accel_data.subtable_accels.in_error ())) + return accel_data; + +- st->collect_glyphs (subtable_accel.left_set, subtable_accel.right_set, num_glyphs); ++ st->collect_glyphs (subtable_accel.first_set, subtable_accel.second_set, num_glyphs); + subtable_accel.class_cache.clear (); + + st = &StructAfter (*st); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh +index 92b07eec6e5..2cbb86c7566 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh +@@ -487,7 +487,7 @@ struct LigatureSubtable + if (entry.flags & LigatureEntryT::SetComponent) + { + /* Never mark same index twice, in case DontAdvance was used... */ +- if (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len) ++ if (unlikely (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len)) + match_length--; + + match_positions[match_length++ % ARRAY_LENGTH (match_positions)] = buffer->out_len; +@@ -640,7 +640,7 @@ struct NoncontextualSubtable + for (unsigned int i = 0; i < count; i++) + { + /* This block copied from StateTableDriver::drive. Keep in sync. */ +- if (last_range) ++ if (unlikely (last_range)) + { + auto *range = last_range; + { +@@ -1169,15 +1169,15 @@ struct Chain + hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) + goto skip; + +- c->subtable_flags = subtable_flags; +- c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); +- c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; +- + if (!(coverage & ChainSubtable::AllDirections) && + HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != + bool (coverage & ChainSubtable::Vertical)) + goto skip; + ++ c->subtable_flags = subtable_flags; ++ c->first_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); ++ c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; ++ + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index); +@@ -1219,22 +1219,21 @@ struct Chain + if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) + goto skip; + +- if (reverse) +- c->buffer->reverse (); ++ if (reverse != c->buffer_is_reversed) ++ c->reverse_buffer (); + + subtable->apply (c); + +- if (reverse) +- c->buffer->reverse (); +- + (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index); + +- if (unlikely (!c->buffer->successful)) return; ++ if (unlikely (!c->buffer->successful)) break; + + skip: + subtable = &StructAfter> (*subtable); + c->set_lookup_index (c->lookup_index + 1); + } ++ if (c->buffer_is_reversed) ++ c->reverse_buffer (); + } + + unsigned int get_size () const { return length; } +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh +index 6e250bfdef0..651ffcda01d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh +@@ -78,129 +78,246 @@ + + + /* +- * Big-endian integers. ++ * Fixed-endian integers / floats. + */ + ++ + /* Endian swap, used in Windows related backends */ + static inline constexpr uint16_t hb_uint16_swap (uint16_t v) + { return (v >> 8) | (v << 8); } + static inline constexpr uint32_t hb_uint32_swap (uint32_t v) + { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } + +-#ifndef HB_FAST_INT_ACCESS ++template ++struct __attribute__((packed)) hb_packed_t { Type v; }; ++ ++#ifndef HB_FAST_NUM_ACCESS ++ + #if defined(__OPTIMIZE__) && \ + defined(__BYTE_ORDER) && \ + (__BYTE_ORDER == __BIG_ENDIAN || \ + (__BYTE_ORDER == __LITTLE_ENDIAN && \ + hb_has_builtin(__builtin_bswap16) && \ +- hb_has_builtin(__builtin_bswap32))) +-#define HB_FAST_INT_ACCESS 1 ++ hb_has_builtin(__builtin_bswap32) && \ ++ hb_has_builtin(__builtin_bswap64))) ++#define HB_FAST_NUM_ACCESS 1 + #else +-#define HB_FAST_INT_ACCESS 0 ++#define HB_FAST_NUM_ACCESS 0 ++#endif ++ ++// https://github.com/harfbuzz/harfbuzz/issues/5456 ++#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 12) ++#undef HB_FAST_NUM_ACCESS ++#define HB_FAST_NUM_ACCESS 0 + #endif ++ + #endif + +-template +-struct BEInt; +-template +-struct BEInt ++template ++struct HBInt; ++template ++struct HBInt + { + public: +- BEInt () = default; +- constexpr BEInt (Type V) : v {uint8_t (V)} {} ++ HBInt () = default; ++ constexpr HBInt (Type V) : v {uint8_t (V)} {} + constexpr operator Type () const { return v; } + private: uint8_t v; + }; +-template +-struct BEInt ++template ++struct HBInt + { +- struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; +- + public: +- BEInt () = default; +- +- BEInt (Type V) +-#if HB_FAST_INT_ACCESS +-#if __BYTE_ORDER == __LITTLE_ENDIAN +- { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); } +-#else /* __BYTE_ORDER == __BIG_ENDIAN */ +- { ((packed_uint16_t *) v)->v = V; } +-#endif ++ HBInt () = default; ++ ++ HBInt (Type V) ++#if HB_FAST_NUM_ACCESS ++ { ++ if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ++ ((hb_packed_t *) v)->v = V; ++ else ++ ((hb_packed_t *) v)->v = __builtin_bswap16 (V); ++ } + #else +- : v {uint8_t ((V >> 8) & 0xFF), +- uint8_t ((V ) & 0xFF)} {} ++ : v {BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V ) & 0xFF), ++ BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 8) & 0xFF)} {} + #endif + +- constexpr operator Type () const { +-#if HB_FAST_INT_ACCESS +-#if __BYTE_ORDER == __LITTLE_ENDIAN +- return __builtin_bswap16 (((packed_uint16_t *) v)->v); +-#else /* __BYTE_ORDER == __BIG_ENDIAN */ +- return ((packed_uint16_t *) v)->v; +-#endif ++ constexpr operator Type () const ++ { ++#if HB_FAST_NUM_ACCESS ++ return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? ++ ((const hb_packed_t *) v)->v ++ : ++ __builtin_bswap16 (((const hb_packed_t *) v)->v) ++ ; + #else +- return (v[0] << 8) +- + (v[1] ); ++ return (BE ? (v[0] << 8) : (v[0] )) ++ + (BE ? (v[1] ) : (v[1] << 8)); + #endif + } + private: uint8_t v[2]; + }; +-template +-struct BEInt ++template ++struct HBInt + { + static_assert (!std::is_signed::value, ""); + public: +- BEInt () = default; +- constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), +- uint8_t ((V >> 8) & 0xFF), +- uint8_t ((V ) & 0xFF)} {} +- +- constexpr operator Type () const { return (v[0] << 16) +- + (v[1] << 8) +- + (v[2] ); } ++ HBInt () = default; ++ constexpr HBInt (Type V) : v {BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 16) & 0xFF), ++ BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 8) & 0xFF), ++ BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V ) & 0xFF)} {} ++ ++ constexpr operator Type () const { return (BE ? (v[0] << 16) : (v[0] )) ++ + (BE ? (v[1] << 8) : (v[1] << 8)) ++ + (BE ? (v[2] ) : (v[2] << 16)); } + private: uint8_t v[3]; + }; +-template +-struct BEInt ++template ++struct HBInt + { +- struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; ++ template ++ friend struct HBFloat; + + public: +- BEInt () = default; +- +- BEInt (Type V) +-#if HB_FAST_INT_ACCESS +-#if __BYTE_ORDER == __LITTLE_ENDIAN +- { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); } +-#else /* __BYTE_ORDER == __BIG_ENDIAN */ +- { ((packed_uint32_t *) v)->v = V; } +-#endif ++ HBInt () = default; ++ ++ HBInt (Type V) ++#if HB_FAST_NUM_ACCESS ++ { ++ if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ++ ((hb_packed_t *) v)->v = V; ++ else ++ ((hb_packed_t *) v)->v = __builtin_bswap32 (V); ++ } + #else +- : v {uint8_t ((V >> 24) & 0xFF), +- uint8_t ((V >> 16) & 0xFF), +- uint8_t ((V >> 8) & 0xFF), +- uint8_t ((V ) & 0xFF)} {} ++ : v {BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V ) & 0xFF), ++ BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 8) & 0xFF), ++ BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 16) & 0xFF), ++ BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 24) & 0xFF)} {} + #endif + + constexpr operator Type () const { +-#if HB_FAST_INT_ACCESS +-#if __BYTE_ORDER == __LITTLE_ENDIAN +- return __builtin_bswap32 (((packed_uint32_t *) v)->v); +-#else /* __BYTE_ORDER == __BIG_ENDIAN */ +- return ((packed_uint32_t *) v)->v; +-#endif ++#if HB_FAST_NUM_ACCESS ++ return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? ++ ((const hb_packed_t *) v)->v ++ : ++ __builtin_bswap32 (((const hb_packed_t *) v)->v) ++ ; + #else +- return (v[0] << 24) +- + (v[1] << 16) +- + (v[2] << 8) +- + (v[3] ); ++ return (BE ? (v[0] << 24) : (v[0] )) ++ + (BE ? (v[1] << 16) : (v[1] << 8)) ++ + (BE ? (v[2] << 8) : (v[2] << 16)) ++ + (BE ? (v[3] ) : (v[3] << 24)); + #endif + } + private: uint8_t v[4]; + }; ++template ++struct HBInt ++{ ++ template ++ friend struct HBFloat; ++ ++ public: ++ HBInt () = default; ++ ++ HBInt (Type V) ++#if HB_FAST_NUM_ACCESS ++ { ++ if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ++ ((hb_packed_t *) v)->v = V; ++ else ++ ((hb_packed_t *) v)->v = __builtin_bswap64 (V); ++ } ++#else ++ : v {BE ? uint8_t ((V >> 56) & 0xFF) : uint8_t ((V ) & 0xFF), ++ BE ? uint8_t ((V >> 48) & 0xFF) : uint8_t ((V >> 8) & 0xFF), ++ BE ? uint8_t ((V >> 40) & 0xFF) : uint8_t ((V >> 16) & 0xFF), ++ BE ? uint8_t ((V >> 32) & 0xFF) : uint8_t ((V >> 24) & 0xFF), ++ BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V >> 32) & 0xFF), ++ BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 40) & 0xFF), ++ BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 48) & 0xFF), ++ BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 56) & 0xFF)} {} ++#endif ++ ++ constexpr operator Type () const { ++#if HB_FAST_NUM_ACCESS ++ return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? ++ ((const hb_packed_t *) v)->v ++ : ++ __builtin_bswap64 (((const hb_packed_t *) v)->v) ++ ; ++#else ++ return (BE ? (uint64_t (v[0]) << 56) : (uint64_t (v[0]) )) ++ + (BE ? (uint64_t (v[1]) << 48) : (uint64_t (v[1]) << 8)) ++ + (BE ? (uint64_t (v[2]) << 40) : (uint64_t (v[2]) << 16)) ++ + (BE ? (uint64_t (v[3]) << 32) : (uint64_t (v[3]) << 24)) ++ + (BE ? (uint64_t (v[4]) << 24) : (uint64_t (v[4]) << 32)) ++ + (BE ? (uint64_t (v[5]) << 16) : (uint64_t (v[5]) << 40)) ++ + (BE ? (uint64_t (v[6]) << 8) : (uint64_t (v[6]) << 48)) ++ + (BE ? (uint64_t (v[7]) ) : (uint64_t (v[7]) << 56)); ++#endif ++ } ++ private: uint8_t v[8]; ++}; + + /* Floats. */ + ++template ++struct HBFloat ++{ ++ using IntType = typename std::conditional::type; ++ ++ public: ++ HBFloat () = default; ++ ++ HBFloat (Type V) ++ { ++#if HB_FAST_NUM_ACCESS ++ { ++ if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ++ { ++ ((hb_packed_t *) v)->v = V; ++ return; ++ } ++ } ++#endif ++ ++ union { ++ hb_packed_t f; ++ hb_packed_t i; ++ } u = {{V}}; ++ ++ const HBInt I = u.i.v; ++ for (unsigned i = 0; i < Bytes; i++) ++ v[i] = I.v[i]; ++ } ++ ++ /* c++14 constexpr */ operator Type () const ++ { ++#if HB_FAST_NUM_ACCESS ++ { ++ if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ++ return ((const hb_packed_t *) v)->v; ++ } ++#endif ++ ++ HBInt I; ++ for (unsigned i = 0; i < Bytes; i++) ++ I.v[i] = v[i]; ++ ++ union { ++ hb_packed_t i; ++ hb_packed_t f; ++ } u = {{I}}; ++ ++ return u.f.v; ++ } ++ private: uint8_t v[Bytes]; ++}; ++ ++ + /* We want our rounding towards +infinity. */ + static inline double + _hb_roundf (double x) { return floor (x + .5); } +@@ -210,6 +327,27 @@ _hb_roundf (float x) { return floorf (x + .5f); } + + #define roundf(x) _hb_roundf(x) + ++static inline void ++hb_sincos (float rotation, float &s, float &c) ++{ ++#ifdef HAVE_SINCOSF ++ sincosf (rotation, &s, &c); ++#else ++ c = cosf (rotation); ++ s = sinf (rotation); ++#endif ++} ++static inline void ++hb_sincos (double rotation, double &s, double &c) ++{ ++#ifdef HAVE_SINCOS ++ sincos (rotation, &s, &c); ++#else ++ c = cos (rotation); ++ s = sin (rotation); ++#endif ++} ++ + + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, + * values will be truncated / overlap, and might not decode exactly. */ +@@ -734,6 +872,17 @@ HB_FUNCOBJ (hb_clamp); + * Bithacks. + */ + ++/* Return the number of 1 bits in a uint8_t; faster than hb_popcount() */ ++static inline unsigned ++hb_popcount8 (uint8_t v) ++{ ++ static const uint8_t popcount4[16] = { ++ 0, 1, 1, 2, 1, 2, 2, 3, ++ 1, 2, 2, 3, 2, 3, 3, 4 ++ }; ++ return popcount4[v & 0xF] + popcount4[v >> 4]; ++} ++ + /* Return the number of 1 bits in v. */ + template + static inline unsigned int +@@ -1070,6 +1219,7 @@ _hb_cmp_operator (const void *pkey, const void *pval) + } + + template ++HB_HOT + static inline bool + hb_bsearch_impl (unsigned *pos, /* Out */ + const K& key, +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-alloc-pool.hh b/src/java.desktop/share/native/libharfbuzz/hb-alloc-pool.hh +new file mode 100644 +index 00000000000..cb0d7aa7acd +--- /dev/null ++++ b/src/java.desktop/share/native/libharfbuzz/hb-alloc-pool.hh +@@ -0,0 +1,105 @@ ++/* ++ * This is part of HarfBuzz, a text shaping library. ++ * ++ * Permission is hereby granted, without written agreement and without ++ * license or royalty fees, to use, copy, modify, and distribute this ++ * software and its documentation for any purpose, provided that the ++ * above copyright notice and the following two paragraphs appear in ++ * all copies of this software. ++ * ++ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR ++ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ++ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN ++ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH ++ * DAMAGE. ++ * ++ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, ++ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ++ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO ++ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ++ * ++ * Author(s): Behdad Esfahbod ++ */ ++ ++#ifndef HB_ALLOC_POOL_HH ++#define HB_ALLOC_POOL_HH ++ ++#include "hb-vector.hh" ++ ++/* Memory pool for persistent small- to medium-sized allocations. ++ * ++ * Some AI musings on this, not necessarily true: ++ * ++ * This is a very simple implementation, but it's good enough for our ++ * purposes. It's not thread-safe. It's not very fast. It's not ++ * very memory efficient. It's not very cache efficient. It's not ++ * very anything efficient. But it's simple and it works. And it's ++ * good enough for our purposes. If you need something more ++ * sophisticated, use a real allocator. Or use a real language. */ ++ ++struct hb_alloc_pool_t ++{ ++ unsigned ChunkSize = 65536 - 2 * sizeof (void *); ++ ++ void *alloc (size_t size, unsigned alignment = 2 * sizeof (void *)) ++ { ++ if (unlikely (chunks.in_error ())) return nullptr; ++ ++ assert (alignment > 0); ++ assert (alignment <= 2 * sizeof (void *)); ++ assert ((alignment & (alignment - 1)) == 0); /* power of two */ ++ ++ if (size > (ChunkSize) / 4) ++ { ++ /* Big chunk, allocate separately. */ ++ hb_vector_t chunk; ++ if (unlikely (!chunk.resize (size))) return nullptr; ++ void *ret = chunk.arrayZ; ++ chunks.push (std::move (chunk)); ++ if (chunks.in_error ()) return nullptr; ++ if (chunks.length > 1) ++ { ++ // Bring back the previous last chunk to the end, so that ++ // we can continue to allocate from it. ++ hb_swap (chunks.arrayZ[chunks.length - 1], chunks.arrayZ[chunks.length - 2]); ++ } ++ return ret; ++ } ++ ++ unsigned pad = (unsigned) ((alignment - ((uintptr_t) current_chunk.arrayZ & (alignment - 1))) & (alignment - 1)); ++ ++ // Small chunk, allocate from the last chunk. ++ if (current_chunk.length < pad + size) ++ { ++ chunks.push (); ++ if (unlikely (chunks.in_error ())) return nullptr; ++ hb_vector_t &chunk = chunks.arrayZ[chunks.length - 1]; ++ if (unlikely (!chunk.resize (ChunkSize))) return nullptr; ++ current_chunk = chunk; ++ pad = (unsigned) ((alignment - ((uintptr_t) current_chunk.arrayZ & (alignment - 1))) & (alignment - 1)); ++ } ++ ++ current_chunk += pad; ++ ++ assert (current_chunk.length >= size); ++ void *ret = current_chunk.arrayZ; ++ current_chunk += size; ++ return ret; ++ } ++ ++ void discard (void *p_, size_t size) ++ { ++ // Reclaim memory if we can. ++ char *p = (char *) p_; ++ if (current_chunk.arrayZ == p + size && current_chunk.backwards_length >= size) ++ current_chunk -= size; ++ } ++ ++ private: ++ hb_vector_t> chunks; ++ hb_array_t current_chunk; ++}; ++ ++ ++#endif /* HB_ALLOC_POOL_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-array.hh +index d65bbc5c711..71d3bcdf1ea 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-array.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-array.hh +@@ -291,6 +291,13 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> + && (unsigned int) (arrayZ + length - (const char *) p) >= size; + } + ++ template ++ bool check_end (const void *p) const ++ { ++ return (uintptr_t) (((const char *) p) - arrayZ) <= length; ++ } ++ + /* Only call if you allocated the underlying array using hb_malloc() or similar. */ + void fini () + { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; } +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh +index 80bd90e87dc..05aaf5a155e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh +@@ -40,7 +40,6 @@ + * Atomic integers and pointers. + */ + +- + /* We need external help for these */ + + #if defined(hb_atomic_int_impl_add) \ +@@ -80,27 +79,11 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) + + #include + ++#define HB_STL_ATOMIC_IMPL ++ + #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) + #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) + +-#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) +-#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) +-#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) +-#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) +-#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) +- +-#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) +-#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) +-#define hb_atomic_ptr_impl_get(P) (reinterpret_cast *> (P)->load (std::memory_order_acquire)) +-static inline bool +-_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) +-{ +- const void *O = O_; // Need lvalue +- return reinterpret_cast *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed); +-} +-#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) +- +- + #else /* defined(HB_NO_MT) */ + + #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) +@@ -159,6 +142,76 @@ inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrie + inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } + #endif + ++#ifdef HB_STL_ATOMIC_IMPL ++template ++struct hb_atomic_t ++{ ++ hb_atomic_t () = default; ++ constexpr hb_atomic_t (T v) : v (v) {} ++ constexpr hb_atomic_t (const hb_atomic_t& o) : v (o.get_relaxed ()) {} ++ constexpr hb_atomic_t (hb_atomic_t&& o) : v (o.get_relaxed ()) { o.set_relaxed ({}); } ++ ++ hb_atomic_t &operator= (const hb_atomic_t& o) { set_relaxed (o.get_relaxed ()); return *this; } ++ hb_atomic_t &operator= (hb_atomic_t&& o){ set_relaxed (o.get_relaxed ()); o.set_relaxed ({}); return *this; } ++ hb_atomic_t &operator= (T v_) ++ { ++ set_relaxed (v_); ++ return *this; ++ } ++ operator T () const { return get_relaxed (); } ++ ++ void set_relaxed (T v_) { v.store (v_, std::memory_order_relaxed); } ++ void set_release (T v_) { v.store (v_, std::memory_order_release); } ++ T get_relaxed () const { return v.load (std::memory_order_relaxed); } ++ T get_acquire () const { return v.load (std::memory_order_acquire); } ++ T inc () { return v.fetch_add (1, std::memory_order_acq_rel); } ++ T dec () { return v.fetch_add (-1, std::memory_order_acq_rel); } ++ ++ int operator++ (int) { return inc (); } ++ int operator-- (int) { return dec (); } ++ ++ friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept ++ { ++ T v = a.get_acquire (); ++ a.set_relaxed (b.get_acquire ()); ++ b.set_relaxed (v); ++ } ++ ++ std::atomic v = 0; ++}; ++ ++template ++struct hb_atomic_t ++{ ++ hb_atomic_t () = default; ++ constexpr hb_atomic_t (T *v) : v (v) {} ++ hb_atomic_t (const hb_atomic_t &other) = delete; ++ ++ void init (T *v_ = nullptr) { set_relaxed (v_); } ++ void set_relaxed (T *v_) { v.store (v_, std::memory_order_relaxed); } ++ T *get_relaxed () const { return v.load (std::memory_order_relaxed); } ++ T *get_acquire () const { return v.load (std::memory_order_acquire); } ++ bool cmpexch (T *old, T *new_) { return v.compare_exchange_weak (old, new_, std::memory_order_acq_rel, std::memory_order_relaxed); } ++ ++ operator bool () const { return get_acquire () != nullptr; } ++ T *operator->() const { return get_acquire (); } ++ template ++ operator C * () const ++ { ++ return get_acquire (); ++ } ++ ++ friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept ++ { ++ T *p = a.get_acquire (); ++ a.set_relaxed (b.get_acquire ()); ++ b.set_relaxed (p); ++ } ++ ++ std::atomic v = nullptr; ++}; ++ ++#else + + template + struct hb_atomic_t +@@ -178,7 +231,6 @@ struct hb_atomic_t + + int operator ++ (int) { return inc (); } + int operator -- (int) { return dec (); } +- long operator |= (long v_) { set_relaxed (get_relaxed () | v_); return *this; } + + T v = 0; + }; +@@ -194,7 +246,7 @@ struct hb_atomic_t + void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } + T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } + T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } +- bool cmpexch (const T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } ++ bool cmpexch (T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + + operator bool () const { return get_acquire () != nullptr; } + T * operator -> () const { return get_acquire (); } +@@ -203,6 +255,8 @@ struct hb_atomic_t + T *v = nullptr; + }; + ++#endif ++ + static inline bool hb_barrier () + { + _hb_compiler_memory_r_barrier (); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh b/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh +index f541472544a..f9c0e8870ff 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh +@@ -176,7 +176,7 @@ struct hb_inc_bimap_t + { + hb_codepoint_t count = get_population (); + hb_vector_t work; +- if (unlikely (!work.resize (count, false))) return; ++ if (unlikely (!work.resize_dirty (count))) return; + + for (hb_codepoint_t rhs = 0; rhs < count; rhs++) + work.arrayZ[rhs] = back_map[rhs]; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh +index 9562a9674a5..902db195507 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh +@@ -142,6 +142,7 @@ struct hb_bit_page_t + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } ++ bool has (hb_codepoint_t g) const { return get (g); } + + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { +@@ -290,7 +291,7 @@ struct hb_bit_page_t + unsigned int j = m & ELT_MASK; + + const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); +- for (const elt_t *p = &vv; i < len (); p = &v[++i]) ++ for (const elt_t *p = &vv; i < len (); p = ((const elt_t *) &v[0]) + (++i)) + if (*p) + { + *codepoint = i * ELT_BITS + elt_get_min (*p); +@@ -346,6 +347,36 @@ struct hb_bit_page_t + return 0; + } + ++ /* ++ * Iterator implementation. ++ */ ++ struct iter_t : hb_iter_with_fallback_t ++ { ++ static constexpr bool is_sorted_iterator = true; ++ iter_t (const hb_bit_page_t &s_ = Null (hb_bit_page_t), bool init = true) : s (&s_), v (INVALID) ++ { ++ if (init) ++ v = s->get_min (); ++ } ++ ++ typedef hb_codepoint_t __item_t__; ++ hb_codepoint_t __item__ () const { return v; } ++ bool __more__ () const { return v != INVALID; } ++ void __next__ () { ++ s->next (&v); ++ } ++ void __prev__ () { s->previous (&v); } ++ iter_t end () const { return iter_t (*s, false); } ++ bool operator != (const iter_t& o) const ++ { return v != o.v; } ++ ++ protected: ++ const hb_bit_page_t *s; ++ hb_codepoint_t v; ++ }; ++ iter_t iter () const { return iter_t (*this); } ++ operator iter_t () const { return iter (); } ++ + static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; + + typedef unsigned long long elt_t; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh +index 740a2437671..4028dd63531 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh +@@ -368,7 +368,7 @@ struct hb_bit_set_invertible_t + unsigned __len__ () const { return l; } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const +- { return v != o.v || s != o.s; } ++ { return v != o.v; } + + protected: + const hb_bit_set_invertible_t *s; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh +index 799c3607599..f86d5750854 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh +@@ -91,10 +91,10 @@ struct hb_bit_set_t + if (pages.length < count && (unsigned) pages.allocated < count && count <= 2) + exact_size = true; // Most sets are small and local + +- if (unlikely (!pages.resize (count, clear, exact_size) || +- !page_map.resize (count, clear))) ++ if (unlikely (!pages.resize_full (count, clear, exact_size) || ++ !page_map.resize_full (count, clear, false))) + { +- pages.resize (page_map.length, clear, exact_size); ++ pages.resize_full (page_map.length, clear, exact_size); + successful = false; + return false; + } +@@ -108,10 +108,11 @@ struct hb_bit_set_t + page_map.alloc (sz); + } + +- void reset () ++ hb_bit_set_t& reset () + { + successful = true; + clear (); ++ return *this; + } + + void clear () +@@ -394,7 +395,7 @@ struct hb_bit_set_t + { + if (unlikely (!successful)) return; + unsigned int count = other.pages.length; +- if (unlikely (!resize (count, false, exact_size))) ++ if (unlikely (!resize (count, false, exact_size))) + return; + population = other.population; + +@@ -922,7 +923,7 @@ struct hb_bit_set_t + unsigned __len__ () const { return l; } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const +- { return s != o.s || v != o.v; } ++ { return v != o.v; } + + protected: + const hb_bit_set_t *s; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh +index 9e21beebd34..87c1524df6f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh +@@ -32,7 +32,7 @@ + #include "hb.hh" + + +-#line 36 "hb-buffer-deserialize-text-unicode.hh" ++#line 33 "hb-buffer-deserialize-text-unicode.hh" + static const unsigned char _deserialize_text_unicode_trans_keys[] = { + 0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u, + 85u, 117u, 85u, 117u, 0 +@@ -150,12 +150,12 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, + hb_glyph_info_t info = {0}; + const hb_glyph_position_t pos = {0}; + +-#line 154 "hb-buffer-deserialize-text-unicode.hh" ++#line 147 "hb-buffer-deserialize-text-unicode.hh" + { + cs = deserialize_text_unicode_start; + } + +-#line 159 "hb-buffer-deserialize-text-unicode.hh" ++#line 150 "hb-buffer-deserialize-text-unicode.hh" + { + int _slen; + int _trans; +@@ -215,7 +215,7 @@ _resume: + hb_memset (&info, 0, sizeof (info)); + } + break; +-#line 219 "hb-buffer-deserialize-text-unicode.hh" ++#line 203 "hb-buffer-deserialize-text-unicode.hh" + } + + _again: +@@ -238,7 +238,7 @@ _again: + *end_ptr = p; + } + break; +-#line 242 "hb-buffer-deserialize-text-unicode.hh" ++#line 224 "hb-buffer-deserialize-text-unicode.hh" + } + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc +index 763172818c4..6787da6f65f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc +@@ -427,7 +427,7 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, + * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then, + * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster. + * - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format: +- * - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then, ++ * - If #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not both 0, `@x_offset,y_offset`. Then, + * - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then, + * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `` + * +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc +index 56299d9b7e0..0c9190bf6f8 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc +@@ -163,7 +163,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, + + 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 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, + * 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) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc +index c0600fd839b..8f6da312cdd 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc +@@ -158,14 +158,15 @@ hb_segment_properties_overlay (hb_segment_properties_t *p, + bool + hb_buffer_t::enlarge (unsigned int size) + { +- if (unlikely (!successful)) +- return false; + if (unlikely (size > max_len)) + { + successful = false; + 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; +@@ -226,6 +227,13 @@ hb_buffer_t::shift_forward (unsigned int count) + assert (have_output); + if (unlikely (!ensure (len + count))) return false; + ++ max_ops -= len - idx; ++ if (unlikely (max_ops < 0)) ++ { ++ successful = false; ++ return false; ++ } ++ + memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0])); + if (idx + count > len) + { +@@ -297,7 +305,6 @@ hb_buffer_t::clear () + props = default_props; + + successful = true; +- shaping_failed = false; + have_output = false; + have_positions = false; + +@@ -320,7 +327,6 @@ hb_buffer_t::enter () + { + 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 +345,6 @@ hb_buffer_t::leave () + max_ops = HB_BUFFER_MAX_OPS_DEFAULT; + deallocate_var_all (); + serial = 0; +- // Intentionally not reseting shaping_failed, such that it can be inspected. + } + + +@@ -520,7 +525,19 @@ hb_buffer_t::set_masks (hb_mask_t value, + hb_mask_t not_mask = ~mask; + value &= mask; + ++ max_ops -= len; ++ if (unlikely (max_ops < 0)) ++ successful = false; ++ + unsigned int count = len; ++ ++ if (cluster_start == 0 && cluster_end == (unsigned int) -1) ++ { ++ for (unsigned int i = 0; i < count; i++) ++ info[i].mask = (info[i].mask & not_mask) | value; ++ return; ++ } ++ + for (unsigned int i = 0; i < count; i++) + if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) + info[i].mask = (info[i].mask & not_mask) | value; +@@ -536,6 +553,10 @@ hb_buffer_t::merge_clusters_impl (unsigned int start, + return; + } + ++ max_ops -= end - start; ++ if (unlikely (max_ops < 0)) ++ successful = false; ++ + unsigned int cluster = info[start].cluster; + + for (unsigned int i = start + 1; i < end; i++) +@@ -569,6 +590,10 @@ hb_buffer_t::merge_out_clusters (unsigned int start, + if (unlikely (end - start < 2)) + return; + ++ max_ops -= end - start; ++ if (unlikely (max_ops < 0)) ++ successful = false; ++ + unsigned int cluster = out_info[start].cluster; + + for (unsigned int i = start + 1; i < end; i++) +@@ -726,7 +751,6 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = + HB_SEGMENT_PROPERTIES_DEFAULT, + + false, /* successful */ +- true, /* shaping_failed */ + false, /* have_output */ + true /* have_positions */ + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh +index 81c0f4a72e3..1c46981cc9c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh +@@ -32,6 +32,7 @@ + + #include "hb.hh" + #include "hb-unicode.hh" ++#include "hb-set-digest.hh" + + + static_assert ((sizeof (hb_glyph_info_t) == 20), ""); +@@ -44,14 +45,14 @@ HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); + + enum hb_buffer_scratch_flags_t { + HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, +- HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, ++ HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH = 0x00000001u, + HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, + HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, + HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, + HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, +- HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, +- HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, +- HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000080u, ++ HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000020u, ++ HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000040u, ++ HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS = 0x00000080u, + + /* Reserved for shapers' internal use. */ + HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, +@@ -90,7 +91,6 @@ struct hb_buffer_t + 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 */ + +@@ -110,6 +110,7 @@ struct hb_buffer_t + hb_codepoint_t context[2][CONTEXT_LENGTH]; + unsigned int context_len[2]; + ++ hb_set_digest_t digest; /* Manually updated sometimes */ + + /* + * Managed by enter / leave +@@ -200,6 +201,12 @@ struct hb_buffer_t + void collect_codepoints (set_t &d) const + { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } + ++ void update_digest () ++ { ++ digest = hb_set_digest_t (); ++ collect_codepoints (digest); ++ } ++ + HB_INTERNAL void similar (const hb_buffer_t &src); + HB_INTERNAL void reset (); + HB_INTERNAL void clear (); +@@ -346,7 +353,7 @@ struct hb_buffer_t + { + 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++; +@@ -363,7 +370,7 @@ struct hb_buffer_t + { + if (out_info != info || out_len != idx) + { +- if (unlikely (!make_room_for (n, n))) return false; ++ if (unlikely (!ensure (out_len + n))) return false; + memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); + } + out_len += n; +@@ -404,22 +411,12 @@ struct hb_buffer_t + /* Adds glyph flags in mask to infos with clusters between start and end. + * The start index will be from out-buffer if from_out_buffer is true. + * If interior is true, then the cluster having the minimum value is skipped. */ +- void _set_glyph_flags (hb_mask_t mask, +- unsigned start = 0, +- unsigned end = (unsigned) -1, +- bool interior = false, +- bool from_out_buffer = false) ++ void _set_glyph_flags_impl (hb_mask_t mask, ++ unsigned start, ++ unsigned end, ++ bool interior, ++ bool from_out_buffer) + { +- end = hb_min (end, len); +- +- if (unlikely (end - start > 255)) +- return; +- +- if (interior && !from_out_buffer && end - start < 2) +- return; +- +- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; +- + if (!from_out_buffer || !have_output) + { + if (!interior) +@@ -456,6 +453,25 @@ struct hb_buffer_t + } + } + ++ HB_ALWAYS_INLINE ++ void _set_glyph_flags (hb_mask_t mask, ++ unsigned start = 0, ++ unsigned end = (unsigned) -1, ++ bool interior = false, ++ bool from_out_buffer = false) ++ { ++ if (unlikely (end != (unsigned) -1 && end - start > 255)) ++ return; ++ ++ end = hb_min (end, len); ++ ++ if (interior && !from_out_buffer && end - start < 2) ++ return; ++ ++ _set_glyph_flags_impl (mask, start, end, interior, from_out_buffer); ++ } ++ ++ + void unsafe_to_break (unsigned int start = 0, unsigned int end = -1) + { + _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, +@@ -606,6 +622,10 @@ struct hb_buffer_t + if (unlikely (start == end)) + return; + ++ max_ops -= end - start; ++ if (unlikely (max_ops < 0)) ++ successful = false; ++ + unsigned cluster_first = infos[start].cluster; + unsigned cluster_last = infos[end - 1].cluster; + +@@ -614,10 +634,7 @@ struct hb_buffer_t + { + for (unsigned int i = start; i < end; i++) + if (cluster != infos[i].cluster) +- { +- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; + infos[i].mask |= mask; +- } + return; + } + +@@ -626,18 +643,12 @@ struct hb_buffer_t + if (cluster == cluster_first) + { + for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--) +- { +- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; + infos[i - 1].mask |= mask; +- } + } + else /* cluster == cluster_last */ + { + for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++) +- { +- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; + infos[i].mask |= mask; +- } + } + } + unsigned +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh +index 7d09ca89d7f..3609ccecc71 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh +@@ -64,17 +64,23 @@ template , +- hb_atomic_t>::type, +- typename std::conditional::type ++ typename std::conditional, ++ typename std::conditional, ++ hb_atomic_t>::type>::type, ++ typename std::conditional::type>::type + >::type; + + static_assert ((key_bits >= cache_bits), ""); + static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); + ++ static constexpr unsigned MAX_VALUE = (1u << value_bits) - 1; ++ + hb_cache_t () { clear (); } + + void clear () +@@ -83,25 +89,32 @@ struct hb_cache_t + v = -1; + } + ++ HB_HOT + bool get (unsigned int key, unsigned int *value) const + { + unsigned int k = key & ((1u<> value_bits) != (key >> cache_bits)) + return false; + *value = v & ((1u<> key_bits) || (value >> value_bits))) +- return false; /* Overflows */ ++ return; /* Overflows */ ++ set_unchecked (key, value); ++ } ++ ++ HB_HOT ++ void set_unchecked (unsigned int key, unsigned int value) ++ { + unsigned int k = key & ((1u<>cache_bits)< + cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, + const int *coords_=nullptr, unsigned int num_coords_=0) + : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs), +- cached_scalars_vector (&acc.cached_scalars_vector) ++ region_count (0), cached_scalars_vector (&acc.cached_scalars_vector) + { + coords = coords_; + num_coords = num_coords_; + varStore = acc.varStore; +- do_blend = num_coords && coords && varStore->size; ++ do_blend = num_coords && varStore->size; + set_ivs (acc.privateDicts[fd].ivs); + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-common.cc +index 5c8546a378c..9eeae358a75 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-common.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-common.cc +@@ -40,43 +40,6 @@ + **/ + + +-/* hb_options_t */ +- +-hb_atomic_t _hb_options; +- +-void +-_hb_options_init () +-{ +- hb_options_union_t u; +- u.i = 0; +- u.opts.initialized = true; +- +- const char *c = getenv ("HB_OPTIONS"); +- if (c) +- { +- while (*c) +- { +- const char *p = strchr (c, ':'); +- if (!p) +- p = c + strlen (c); +- +-#define OPTION(name, symbol) \ +- if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast(p - c)) do { u.opts.symbol = true; } while (0) +- +- OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible); +- +-#undef OPTION +- +- c = *p ? p + 1 : p; +- } +- +- } +- +- /* This is idempotent and threadsafe. */ +- _hb_options = u.i; +-} +- +- + /* hb_tag_t */ + + /** +@@ -545,8 +508,11 @@ hb_script_to_iso15924_tag (hb_script_t script) + * Fetches the #hb_direction_t of a script when it is + * set horizontally. All right-to-left scripts will return + * #HB_DIRECTION_RTL. All left-to-right scripts will return +- * #HB_DIRECTION_LTR. Scripts that can be written either +- * horizontally or vertically will return #HB_DIRECTION_INVALID. ++ * #HB_DIRECTION_LTR. ++ * ++ * Scripts that can be written either right-to-left or ++ * left-to-right will return #HB_DIRECTION_INVALID. ++ * + * Unknown scripts will return #HB_DIRECTION_LTR. + * + * Return value: The horizontal #hb_direction_t of @script +@@ -628,6 +594,9 @@ hb_script_get_horizontal_direction (hb_script_t script) + /* Unicode-16.0 additions */ + case HB_SCRIPT_GARAY: + ++ /* Unicode-17.0 additions */ ++ case HB_SCRIPT_SIDETIC: ++ + return HB_DIRECTION_RTL; + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-config.hh b/src/java.desktop/share/native/libharfbuzz/hb-config.hh +index 3956690da35..c522eeea2ea 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-config.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-config.hh +@@ -38,7 +38,6 @@ + #ifndef HB_EXPERIMENTAL_API + #define HB_NO_BEYOND_64K + #define HB_NO_CUBIC_GLYF +-#define HB_NO_VAR_COMPOSITES + #endif + + #ifdef HB_TINY +@@ -91,7 +90,10 @@ + #ifdef HB_MINI + #define HB_NO_AAT + #define HB_NO_LEGACY +-#define HB_NO_BORING_EXPANSION ++#define HB_NO_BEYOND_64K ++#define HB_NO_CUBIC_GLYF ++#define HB_NO_VAR_COMPOSITES ++#define HB_NO_VAR_HVF + #endif + + #ifdef __OPTIMIZE_SIZE__ +@@ -109,12 +111,6 @@ + + /* Closure of options. */ + +-#ifdef HB_NO_BORING_EXPANSION +-#define HB_NO_BEYOND_64K +-#define HB_NO_CUBIC_GLYF +-#define HB_NO_VAR_COMPOSITES +-#endif +- + #ifdef HB_NO_VAR + #define HB_NO_VAR_COMPOSITES + #endif +@@ -149,10 +145,6 @@ + #define HB_NO_PAINT + #endif + +-#ifdef HB_NO_GETENV +-#define HB_NO_UNISCRIBE_BUG_COMPATIBLE +-#endif +- + #ifdef HB_NO_LEGACY + #define HB_NO_CMAP_LEGACY_SUBTABLES + #define HB_NO_FALLBACK_SHAPE +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh +index 1e9a18b9326..87d30d9ded1 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh +@@ -37,48 +37,6 @@ + #endif + + +-/* +- * Global runtime options. +- */ +- +-struct hb_options_t +-{ +- bool unused : 1; /* In-case sign bit is here. */ +- bool initialized : 1; +- bool uniscribe_bug_compatible : 1; +-}; +- +-union hb_options_union_t { +- unsigned i; +- hb_options_t opts; +-}; +-static_assert ((sizeof (hb_atomic_t) >= sizeof (hb_options_union_t)), ""); +- +-HB_INTERNAL void +-_hb_options_init (); +- +-extern HB_INTERNAL hb_atomic_t _hb_options; +- +-static inline hb_options_t +-hb_options () +-{ +-#ifdef HB_NO_GETENV +- return hb_options_t (); +-#endif +- /* Make a local copy, so we can access bitfield threadsafely. */ +- hb_options_union_t u; +- u.i = _hb_options; +- +- if (unlikely (!u.i)) +- { +- _hb_options_init (); +- u.i = _hb_options; +- } +- +- return u.opts; +-} +- +- + /* + * Debug output (needs enabling at compile time.) + */ +@@ -394,6 +352,10 @@ struct hb_no_trace_t { + #define HB_DEBUG_WASM (HB_DEBUG+0) + #endif + ++#ifndef HB_DEBUG_KBTS ++#define HB_DEBUG_KBTS (HB_DEBUG+0) ++#endif ++ + /* + * With tracing. + */ +@@ -484,7 +446,7 @@ struct hb_no_trace_t { + + + #ifndef HB_BUFFER_MESSAGE_MORE +-#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1) ++#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+0) + #endif + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h +index 927563c4c40..a87a53d0e30 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h ++++ b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h +@@ -287,7 +287,7 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 7.0.0 +- * XDeprecated: REPLACEME: Use hb_font_draw_glyph_func_or_fail_t instead. ++ * Deprecated: 11.2.0: Use hb_font_draw_glyph_func_or_fail_t instead. + **/ + typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, +@@ -308,7 +308,7 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 7.0.0 +- * XDeprecated: REPLACEME: Use hb_font_paint_glyph_or_fail_func_t instead. ++ * Deprecated: 11.2.0: Use hb_font_paint_glyph_or_fail_func_t instead. + */ + typedef hb_bool_t (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, +@@ -346,7 +346,7 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, + * Sets the implementation function for #hb_font_draw_glyph_func_t. + * + * Since: 7.0.0 +- * XDeprecated: REPLACEME: Use hb_font_funcs_set_draw_glyph_or_fail_func instead. ++ * Deprecated: 11.2.0: Use hb_font_funcs_set_draw_glyph_or_fail_func instead. + **/ + HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_or_fail_func) + HB_EXTERN void +@@ -364,7 +364,7 @@ hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + * Sets the implementation function for #hb_font_paint_glyph_func_t. + * + * Since: 7.0.0 +- * XDeprecated: REPLACEME: Use hb_font_funcs_set_paint_glyph_or_fail_func() instead. ++ * Deprecated: 11.2.0: Use hb_font_funcs_set_paint_glyph_or_fail_func() instead. + */ + HB_DEPRECATED_FOR (hb_font_funcs_set_paint_glyph_or_fail_func) + HB_EXTERN void +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.cc b/src/java.desktop/share/native/libharfbuzz/hb-draw.cc +index 8764ffe7129..c243d12f7ae 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-draw.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.cc +@@ -63,14 +63,14 @@ hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data, + float to_x, float to_y, + void *user_data HB_UNUSED) + { +-#define HB_ONE_THIRD 0.33333333f ++#define HB_TWO_THIRD 0.66666666666666666666666667f + dfuncs->emit_cubic_to (draw_data, *st, +- (st->current_x + 2.f * control_x) * HB_ONE_THIRD, +- (st->current_y + 2.f * control_y) * HB_ONE_THIRD, +- (to_x + 2.f * control_x) * HB_ONE_THIRD, +- (to_y + 2.f * control_y) * HB_ONE_THIRD, ++ st->current_x + (control_x - st->current_x) * HB_TWO_THIRD, ++ st->current_y + (control_y - st->current_y) * HB_TWO_THIRD, ++ to_x + (control_x - to_x) * HB_TWO_THIRD, ++ to_y + (control_y - to_y) * HB_TWO_THIRD, + to_x, to_y); +-#undef HB_ONE_THIRD ++#undef HB_TWO_THIRD + } + + static void +@@ -467,7 +467,7 @@ hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + float to_x, float to_y, + void *user_data HB_UNUSED) + { +- hb_extents_t *extents = (hb_extents_t *) data; ++ hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (to_x, to_y); + } +@@ -479,7 +479,7 @@ hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + float to_x, float to_y, + void *user_data HB_UNUSED) + { +- hb_extents_t *extents = (hb_extents_t *) data; ++ hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (to_x, to_y); + } +@@ -492,7 +492,7 @@ hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + float to_x, float to_y, + void *user_data HB_UNUSED) + { +- hb_extents_t *extents = (hb_extents_t *) data; ++ hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (control_x, control_y); + extents->add_point (to_x, to_y); +@@ -507,7 +507,7 @@ hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + float to_x, float to_y, + void *user_data HB_UNUSED) + { +- hb_extents_t *extents = (hb_extents_t *) data; ++ hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (control1_x, control1_y); + extents->add_point (control2_x, control2_y); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc +index 6b7e1913024..c1feaac6280 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc +@@ -169,8 +169,7 @@ _hb_face_builder_get_table_tags (const hb_face_t *face HB_UNUSED, + + if (unlikely (start_offset >= population)) + { +- if (table_count) +- *table_count = 0; ++ *table_count = 0; + return population; + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-face.cc +index 9d59d7c9468..a0f497eea7f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-face.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-face.cc +@@ -84,8 +84,7 @@ hb_face_count (hb_blob_t *blob) + + hb_sanitize_context_t c (blob); + +- const char *start = hb_blob_get_data (blob, nullptr); +- auto *ot = reinterpret_cast (const_cast (start)); ++ auto *ot = blob->as (); + if (unlikely (!ot->sanitize (&c))) + return 0; + +@@ -329,7 +328,7 @@ hb_face_create_from_file_or_fail (const char *file_name, + return face; + } + +-static struct supported_face_loaders_t { ++static const struct supported_face_loaders_t { + char name[16]; + hb_face_t * (*from_file) (const char *font_file, unsigned face_index); + hb_face_t * (*from_blob) (hb_blob_t *blob, unsigned face_index); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-font.cc +index 849855e2c22..6c636e23567 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-font.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-font.cc +@@ -246,7 +246,6 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font, + hb_codepoint_t glyph HB_UNUSED, + void *user_data HB_UNUSED) + { +- /* TODO use font_extents.ascender+descender */ + return -font->y_scale; + } + +@@ -352,6 +351,10 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font, + hb_position_t *y, + void *user_data HB_UNUSED) + { ++ if (font->has_glyph_h_origins_func_set ()) ++ { ++ return font->get_glyph_h_origins (1, &glyph, 0, x, 0, y, 0, false); ++ } + hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); + if (ret) + font->parent_scale_position (x, y); +@@ -366,7 +369,6 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, + hb_position_t *y, + void *user_data HB_UNUSED) + { +- *x = *y = 0; + return false; + } + +@@ -378,12 +380,100 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, + hb_position_t *y, + void *user_data HB_UNUSED) + { ++ if (font->has_glyph_v_origins_func_set ()) ++ { ++ return font->get_glyph_v_origins (1, &glyph, 0, x, 0, y, 0, false); ++ } + hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); + if (ret) + font->parent_scale_position (x, y); + return ret; + } + ++#define hb_font_get_glyph_h_origins_nil hb_font_get_glyph_h_origins_default ++ ++static hb_bool_t ++hb_font_get_glyph_h_origins_default (hb_font_t *font HB_UNUSED, ++ void *font_data HB_UNUSED, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph HB_UNUSED, ++ unsigned glyph_stride HB_UNUSED, ++ hb_position_t *first_x, ++ unsigned x_stride, ++ hb_position_t *first_y, ++ unsigned y_stride, ++ void *user_data HB_UNUSED) ++{ ++ if (font->has_glyph_h_origin_func_set ()) ++ { ++ for (unsigned int i = 0; i < count; i++) ++ { ++ font->get_glyph_h_origin (*first_glyph, first_x, first_y, false); ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ return true; ++ } ++ ++ hb_bool_t ret = font->parent->get_glyph_h_origins (count, ++ first_glyph, glyph_stride, ++ first_x, x_stride, ++ first_y, y_stride); ++ if (ret) ++ { ++ for (unsigned i = 0; i < count; i++) ++ { ++ font->parent_scale_position (first_x, first_y); ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ } ++ return ret; ++} ++ ++#define hb_font_get_glyph_v_origins_nil hb_font_get_glyph_v_origins_default ++ ++static hb_bool_t ++hb_font_get_glyph_v_origins_default (hb_font_t *font HB_UNUSED, ++ void *font_data HB_UNUSED, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph HB_UNUSED, ++ unsigned glyph_stride HB_UNUSED, ++ hb_position_t *first_x, ++ unsigned x_stride, ++ hb_position_t *first_y, ++ unsigned y_stride, ++ void *user_data HB_UNUSED) ++{ ++ if (font->has_glyph_v_origin_func_set ()) ++ { ++ for (unsigned int i = 0; i < count; i++) ++ { ++ font->get_glyph_v_origin (*first_glyph, first_x, first_y, false); ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ return true; ++ } ++ ++ hb_bool_t ret = font->parent->get_glyph_v_origins (count, ++ first_glyph, glyph_stride, ++ first_x, x_stride, ++ first_y, y_stride); ++ if (ret) ++ { ++ for (unsigned i = 0; i < count; i++) ++ { ++ font->parent_scale_position (first_x, first_y); ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ } ++ return ret; ++} ++ + static hb_position_t + hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, +@@ -1256,6 +1346,77 @@ hb_font_get_glyph_v_origin (hb_font_t *font, + return font->get_glyph_v_origin (glyph, x, y); + } + ++/** ++ * hb_font_get_glyph_h_origins: ++ * @font: #hb_font_t to work upon ++ * @count: The number of glyph IDs in the sequence queried ++ * @first_glyph: The first glyph ID to query ++ * @glyph_stride: The stride between successive glyph IDs ++ * @first_x: (out): The first X coordinate of the origin retrieved ++ * @x_stride: The stride between successive X coordinates ++ * @first_y: (out): The first Y coordinate of the origin retrieved ++ * @y_stride: The stride between successive Y coordinates ++ * ++ * Fetches the (X,Y) coordinates of the origin for requested glyph IDs ++ * in the specified font, for horizontal text segments. ++ * ++ * Return value: `true` if data found, `false` otherwise ++ * ++ * Since: 11.3.0 ++ **/ ++hb_bool_t ++hb_font_get_glyph_h_origins (hb_font_t *font, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned int glyph_stride, ++ hb_position_t *first_x, ++ unsigned int x_stride, ++ hb_position_t *first_y, ++ unsigned int y_stride) ++ ++{ ++ return font->get_glyph_h_origins (count, ++ first_glyph, glyph_stride, ++ first_x, x_stride, ++ first_y, y_stride); ++} ++ ++/** ++ * hb_font_get_glyph_v_origins: ++ * @font: #hb_font_t to work upon ++ * @count: The number of glyph IDs in the sequence queried ++ * @first_glyph: The first glyph ID to query ++ * @glyph_stride: The stride between successive glyph IDs ++ * @first_x: (out): The first X coordinate of the origin retrieved ++ * @x_stride: The stride between successive X coordinates ++ * @first_y: (out): The first Y coordinate of the origin retrieved ++ * @y_stride: The stride between successive Y coordinates ++ * ++ * Fetches the (X,Y) coordinates of the origin for requested glyph IDs ++ * in the specified font, for vertical text segments. ++ * ++ * Return value: `true` if data found, `false` otherwise ++ * ++ * Since: 11.3.0 ++ **/ ++hb_bool_t ++hb_font_get_glyph_v_origins (hb_font_t *font, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned int glyph_stride, ++ hb_position_t *first_x, ++ unsigned int x_stride, ++ hb_position_t *first_y, ++ unsigned int y_stride) ++ ++{ ++ return font->get_glyph_v_origins (count, ++ first_glyph, glyph_stride, ++ first_x, x_stride, ++ first_y, y_stride); ++} ++ ++ + /** + * hb_font_get_glyph_h_kerning: + * @font: #hb_font_t to work upon +@@ -1443,7 +1604,7 @@ hb_font_get_glyph_shape (hb_font_t *font, + * + * Return value: `true` if glyph was drawn, `false` otherwise + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + **/ + hb_bool_t + hb_font_draw_glyph_or_fail (hb_font_t *font, +@@ -1480,7 +1641,7 @@ hb_font_draw_glyph_or_fail (hb_font_t *font, + * + * Return value: `true` if glyph was painted, `false` otherwise + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + */ + hb_bool_t + hb_font_paint_glyph_or_fail (hb_font_t *font, +@@ -1883,6 +2044,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = + + 1000, /* x_scale */ + 1000, /* y_scale */ ++ false, /* is_synthetic */ + 0.f, /* x_embolden */ + 0.f, /* y_embolden */ + true, /* embolden_in_place */ +@@ -1900,6 +2062,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = + 0, /* ptem */ + + HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */ ++ false, /* has_nonzero_coords */ + 0, /* num_coords */ + nullptr, /* coords */ + nullptr, /* design_coords */ +@@ -1960,8 +2123,14 @@ hb_font_create (hb_face_t *face) + hb_font_set_funcs_using (font, nullptr); + + #ifndef HB_NO_VAR +- if (face && face->index >> 16) +- hb_font_set_var_named_instance (font, (face->index >> 16) - 1); ++ // Initialize variations. ++ if (likely (face)) ++ { ++ if (face->index >> 16) ++ hb_font_set_var_named_instance (font, (face->index >> 16) - 1); ++ else ++ hb_font_set_variations (font, nullptr, 0); ++ } + #endif + + return font; +@@ -1979,6 +2148,7 @@ _hb_font_adopt_var_coords (hb_font_t *font, + font->coords = coords; + font->design_coords = design_coords; + font->num_coords = coords_length; ++ font->has_nonzero_coords = hb_any (hb_array (coords, coords_length)); + + font->changed (); + font->serial_coords = font->serial; +@@ -2393,7 +2563,7 @@ hb_font_set_funcs_data (hb_font_t *font, + font->changed (); + } + +-static struct supported_font_funcs_t { ++static const struct supported_font_funcs_t { + char name[16]; + void (*func) (hb_font_t *); + } supported_font_funcs[] = +@@ -2450,6 +2620,9 @@ hb_bool_t + hb_font_set_funcs_using (hb_font_t *font, + const char *name) + { ++ if (unlikely (hb_object_is_immutable (font))) ++ return false; ++ + bool retry = false; + + if (!name || !*name) +@@ -2704,12 +2877,12 @@ hb_font_get_ptem (hb_font_t *font) + * + * Return value: `true` if the font is synthetic, `false` otherwise. + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + */ + hb_bool_t + hb_font_is_synthetic (hb_font_t *font) + { +- return font->is_synthetic (); ++ return font->is_synthetic; + } + + /** +@@ -2858,12 +3031,6 @@ hb_font_set_variations (hb_font_t *font, + if (hb_object_is_immutable (font)) + return; + +- if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) +- { +- hb_font_set_var_coords_normalized (font, nullptr, 0); +- return; +- } +- + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; +@@ -2970,7 +3137,6 @@ hb_font_set_variation (hb_font_t *font, + + hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); + _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); +- + } + + /** +@@ -2991,11 +3157,16 @@ hb_font_set_variation (hb_font_t *font, + void + hb_font_set_var_coords_design (hb_font_t *font, + const float *coords, +- unsigned int coords_length) ++ unsigned int input_coords_length) + { + if (hb_object_is_immutable (font)) + return; + ++ const OT::fvar &fvar = *font->face->table.fvar; ++ auto axes = fvar.get_axes (); ++ const unsigned coords_length = axes.length; ++ ++ input_coords_length = hb_min (input_coords_length, coords_length); + int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; + float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; + +@@ -3006,8 +3177,11 @@ hb_font_set_var_coords_design (hb_font_t *font, + return; + } + +- if (coords_length) +- hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); ++ if (input_coords_length) ++ hb_memcpy (design_coords, coords, input_coords_length * sizeof (font->design_coords[0])); ++ // Fill in the rest with default values ++ for (unsigned int i = input_coords_length; i < coords_length; i++) ++ design_coords[i] = axes[i].get_default (); + + hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); + _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); +@@ -3072,34 +3246,31 @@ hb_font_get_var_named_instance (hb_font_t *font) + void + hb_font_set_var_coords_normalized (hb_font_t *font, + const int *coords, /* 2.14 normalized */ +- unsigned int coords_length) ++ unsigned int input_coords_length) + { + if (hb_object_is_immutable (font)) + return; + ++ const OT::fvar &fvar = *font->face->table.fvar; ++ auto axes = fvar.get_axes (); ++ unsigned coords_length = axes.length; ++ ++ input_coords_length = hb_min (input_coords_length, coords_length); + int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; +- int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; + float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; + +- if (unlikely (coords_length && !(copy && unmapped && design_coords))) ++ if (unlikely (coords_length && !(copy && design_coords))) + { + hb_free (copy); +- hb_free (unmapped); + hb_free (design_coords); + return; + } + +- if (coords_length) +- { +- hb_memcpy (copy, coords, coords_length * sizeof (coords[0])); +- hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0])); +- } ++ if (input_coords_length) ++ hb_memcpy (copy, coords, input_coords_length * sizeof (coords[0])); + +- /* Best effort design coords simulation */ +- font->face->table.avar->unmap_coords (unmapped, coords_length); + for (unsigned int i = 0; i < coords_length; ++i) +- design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]); +- hb_free (unmapped); ++ design_coords[i] = NAN; + + _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); + } +@@ -3112,8 +3283,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font, + * Fetches the list of normalized variation coordinates currently + * set on a font. + * +- * Note that this returned array may only contain values for some +- * (or none) of the axes; omitted axes effectively have zero values. ++ * Note that if no variation coordinates are set, this function may ++ * return %NULL. + * + * Return value is valid as long as variation coordinates of the font + * are not modified. +@@ -3140,9 +3311,12 @@ hb_font_get_var_coords_normalized (hb_font_t *font, + * Fetches the list of variation coordinates (in design-space units) currently + * set on a font. + * +- * Note that this returned array may only contain values for some +- * (or none) of the axes; omitted axes effectively have their default +- * values. ++ * Note that if no variation coordinates are set, this function may ++ * return %NULL. ++ * ++ * If variations have been set on the font using normalized coordinates ++ * (i.e. via hb_font_set_var_coords_normalized()), the design coordinates will ++ * have NaN (Not a Number) values. + * + * Return value is valid as long as variation coordinates of the font + * are not modified. +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.h b/src/java.desktop/share/native/libharfbuzz/hb-font.h +index 4e267ba6a80..2d06b659278 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-font.h ++++ b/src/java.desktop/share/native/libharfbuzz/hb-font.h +@@ -97,7 +97,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); + * @descender: The depth of typographic descenders. + * @line_gap: The suggested line-spacing gap. + * +- * Font-wide extent values, measured in font units. ++ * Font-wide extent values, measured in scaled units. + * + * Note that typically @ascender is positive and @descender + * negative, in coordinate systems that grow up. +@@ -332,7 +332,7 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * +- * This method should retrieve the (X,Y) coordinates (in font units) of the ++ * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for a glyph. Each coordinate must be returned in an #hb_position_t + * output parameter. + * +@@ -349,7 +349,7 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * +- * This method should retrieve the (X,Y) coordinates (in font units) of the ++ * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for a glyph, for horizontal-direction text segments. Each + * coordinate must be returned in an #hb_position_t output parameter. + * +@@ -361,13 +361,72 @@ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * +- * This method should retrieve the (X,Y) coordinates (in font units) of the ++ * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for a glyph, for vertical-direction text segments. Each coordinate + * must be returned in an #hb_position_t output parameter. + * + **/ + typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; + ++/** ++ * hb_font_get_glyph_origins_func_t: ++ * @font: #hb_font_t to work upon ++ * @font_data: @font user data pointer ++ * @first_glyph: The first glyph ID to query ++ * @count: number of glyphs to query ++ * @glyph_stride: The stride between successive glyph IDs ++ * @first_x: (out): The first origin X coordinate retrieved ++ * @x_stride: The stride between successive origin X coordinates ++ * @first_y: (out): The first origin Y coordinate retrieved ++ * @y_stride: The stride between successive origin Y coordinates ++ * @user_data: User data pointer passed by the caller ++ * ++ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. ++ * ++ * This method should retrieve the (X,Y) coordinates (in scaled units) of the ++ * origin for each requested glyph. Each coordinate value must be returned in ++ * an #hb_position_t in the two output parameters. ++ * ++ * Return value: `true` if data found, `false` otherwise ++ * ++ * Since: 11.3.0 ++ **/ ++typedef hb_bool_t (*hb_font_get_glyph_origins_func_t) (hb_font_t *font, void *font_data, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned glyph_stride, ++ hb_position_t *first_x, ++ unsigned x_stride, ++ hb_position_t *first_y, ++ unsigned y_stride, ++ void *user_data); ++ ++/** ++ * hb_font_get_glyph_h_origins_func_t: ++ * ++ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. ++ * ++ * This method should retrieve the (X,Y) coordinates (in scaled units) of the ++ * origin for requested glyph, for horizontal-direction text segments. Each ++ * coordinate must be returned in a the x/y #hb_position_t output parameters. ++ * ++ * Since: 11.3.0 ++ **/ ++typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_h_origins_func_t; ++ ++/** ++ * hb_font_get_glyph_v_origins_func_t: ++ * ++ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. ++ * ++ * This method should retrieve the (X,Y) coordinates (in scaled units) of the ++ * origin for requested glyph, for vertical-direction text segments. Each ++ * coordinate must be returned in a the x/y #hb_position_t output parameters. ++ * ++ * Since: 11.3.0 ++ **/ ++typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_v_origins_func_t; ++ + /** + * hb_font_get_glyph_kerning_func_t: + * @font: #hb_font_t to work upon +@@ -428,7 +487,7 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * +- * This method should retrieve the (X,Y) coordinates (in font units) for a ++ * This method should retrieve the (X,Y) coordinates (in scaled units) for a + * specified contour point in a glyph. Each coordinate must be returned as + * an #hb_position_t output parameter. + * +@@ -498,7 +557,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * + * + * Return value: `true` if glyph was drawn, `false` otherwise + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + **/ + typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, +@@ -520,7 +579,7 @@ typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *f + * + * Return value: `true` if glyph was painted, `false` otherwise + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + */ + typedef hb_bool_t (*hb_font_paint_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, +@@ -707,6 +766,38 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_v_origin_func_t func, + void *user_data, hb_destroy_func_t destroy); + ++/** ++ * hb_font_funcs_set_glyph_h_origins_func: ++ * @ffuncs: A font-function structure ++ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign ++ * @user_data: Data to pass to @func ++ * @destroy: (nullable): The function to call when @user_data is not needed anymore ++ * ++ * Sets the implementation function for #hb_font_get_glyph_h_origins_func_t. ++ * ++ * Since: 11.3.0 ++ **/ ++HB_EXTERN void ++hb_font_funcs_set_glyph_h_origins_func (hb_font_funcs_t *ffuncs, ++ hb_font_get_glyph_h_origins_func_t func, ++ void *user_data, hb_destroy_func_t destroy); ++ ++/** ++ * hb_font_funcs_set_glyph_v_origins_func: ++ * @ffuncs: A font-function structure ++ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign ++ * @user_data: Data to pass to @func ++ * @destroy: (nullable): The function to call when @user_data is not needed anymore ++ * ++ * Sets the implementation function for #hb_font_get_glyph_v_origins_func_t. ++ * ++ * Since: 11.3.0 ++ **/ ++HB_EXTERN void ++hb_font_funcs_set_glyph_v_origins_func (hb_font_funcs_t *ffuncs, ++ hb_font_get_glyph_v_origins_func_t func, ++ void *user_data, hb_destroy_func_t destroy); ++ + /** + * hb_font_funcs_set_glyph_h_kerning_func: + * @ffuncs: A font-function structure +@@ -796,7 +887,7 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, + * + * Sets the implementation function for #hb_font_draw_glyph_or_fail_func_t. + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + **/ + HB_EXTERN void + hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, +@@ -812,7 +903,7 @@ hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, + * + * Sets the implementation function for #hb_font_paint_glyph_or_fail_func_t. + * +- * XSince: REPLACEME ++ * Since: 11.2.0 + */ + HB_EXTERN void + hb_font_funcs_set_paint_glyph_or_fail_func (hb_font_funcs_t *ffuncs, +@@ -876,6 +967,26 @@ hb_font_get_glyph_v_origin (hb_font_t *font, + hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y); + ++HB_EXTERN hb_bool_t ++hb_font_get_glyph_h_origins (hb_font_t *font, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned glyph_stride, ++ hb_position_t *first_x, ++ unsigned x_stride, ++ hb_position_t *first_y, ++ unsigned y_stride); ++ ++HB_EXTERN hb_bool_t ++hb_font_get_glyph_v_origins (hb_font_t *font, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned glyph_stride, ++ hb_position_t *first_x, ++ unsigned x_stride, ++ hb_position_t *first_y, ++ unsigned y_stride); ++ + HB_EXTERN hb_position_t + hb_font_get_glyph_h_kerning (hb_font_t *font, + hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.hh b/src/java.desktop/share/native/libharfbuzz/hb-font.hh +index 69d8d4b09df..9dd54466d7f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-font.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-font.hh +@@ -55,6 +55,8 @@ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \ ++ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origins) \ ++ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origins) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \ + HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \ +@@ -118,6 +120,8 @@ struct hb_font_t + int32_t x_scale; + int32_t y_scale; + ++ bool is_synthetic; ++ + float x_embolden; + float y_embolden; + bool embolden_in_place; +@@ -139,6 +143,7 @@ struct hb_font_t + + /* Font variation coordinates. */ + unsigned int instance_index; ++ bool has_nonzero_coords; + unsigned int num_coords; + int *coords; + float *design_coords; +@@ -430,21 +435,127 @@ struct hb_font_t + } + + hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, +- hb_position_t *x, hb_position_t *y) ++ hb_position_t *x, hb_position_t *y, ++ bool synthetic = true) + { + *x = *y = 0; +- return klass->get.f.glyph_h_origin (this, user_data, +- glyph, x, y, +- !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); ++ bool ret = klass->get.f.glyph_h_origin (this, user_data, ++ glyph, x, y, ++ !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); ++ ++ if (synthetic && ret) ++ { ++ /* Slant is ignored as it does not affect glyph origin */ ++ ++ /* Embolden */ ++ if (!embolden_in_place) ++ { ++ *x += x_scale < 0 ? -x_strength : x_strength; ++ *y += y_scale < 0 ? -y_strength : y_strength; ++ } ++ } ++ ++ return ret; + } + + hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, +- hb_position_t *x, hb_position_t *y) ++ hb_position_t *x, hb_position_t *y, ++ bool synthetic = true) + { + *x = *y = 0; +- return klass->get.f.glyph_v_origin (this, user_data, +- glyph, x, y, +- !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); ++ bool ret = klass->get.f.glyph_v_origin (this, user_data, ++ glyph, x, y, ++ !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); ++ ++ if (synthetic && ret) ++ { ++ /* Slant is ignored as it does not affect glyph origin */ ++ ++ /* Embolden */ ++ if (!embolden_in_place) ++ { ++ *x += x_scale < 0 ? -x_strength : x_strength; ++ *y += y_scale < 0 ? -y_strength : y_strength; ++ } ++ } ++ ++ return ret; ++ } ++ ++ hb_bool_t get_glyph_h_origins (unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned int glyph_stride, ++ hb_position_t *first_x, ++ unsigned int x_stride, ++ hb_position_t *first_y, ++ unsigned int y_stride, ++ bool synthetic = true) ++ ++ { ++ bool ret = klass->get.f.glyph_h_origins (this, user_data, ++ count, ++ first_glyph, glyph_stride, ++ first_x, x_stride, first_y, y_stride, ++ !klass->user_data ? nullptr : klass->user_data->glyph_h_origins); ++ ++ if (synthetic && ret) ++ { ++ hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; ++ hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; ++ for (unsigned i = 0; i < count; i++) ++ { ++ /* Slant is ignored as it does not affect glyph origin */ ++ ++ /* Embolden */ ++ if (!embolden_in_place) ++ { ++ *first_x += x_shift; ++ *first_y += y_shift; ++ } ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ } ++ ++ return ret; ++ } ++ ++ hb_bool_t get_glyph_v_origins (unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned int glyph_stride, ++ hb_position_t *first_x, ++ unsigned int x_stride, ++ hb_position_t *first_y, ++ unsigned int y_stride, ++ bool synthetic = true) ++ ++ { ++ bool ret = klass->get.f.glyph_v_origins (this, user_data, ++ count, ++ first_glyph, glyph_stride, ++ first_x, x_stride, first_y, y_stride, ++ !klass->user_data ? nullptr : klass->user_data->glyph_v_origins); ++ ++ if (synthetic && is_synthetic && ret) ++ { ++ hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; ++ hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; ++ for (unsigned i = 0; i < count; i++) ++ { ++ /* Slant is ignored as it does not affect glyph origin */ ++ ++ /* Embolden */ ++ if (!embolden_in_place) ++ { ++ *first_x += x_shift; ++ *first_y += y_shift; ++ } ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ } ++ ++ return ret; + } + + hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, +@@ -486,7 +597,7 @@ struct hb_font_t + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents); + } +- if (!is_synthetic () && ++ if (!is_synthetic && + klass->get.f.glyph_extents (this, user_data, + glyph, + extents, +@@ -496,6 +607,7 @@ struct hb_font_t + /* Try getting extents from paint(), then draw(), *then* get_extents() + * and apply synthetic settings in the last case. */ + ++#ifndef HB_NO_PAINT + hb_paint_extents_context_t paint_extents; + if (paint_glyph_or_fail (glyph, + hb_paint_extents_get_funcs (), &paint_extents, +@@ -504,14 +616,17 @@ struct hb_font_t + *extents = paint_extents.get_extents ().to_glyph_extents (); + return true; + } ++#endif + +- hb_extents_t draw_extents; ++#ifndef HB_NO_DRAW ++ hb_extents_t<> draw_extents; + if (draw_glyph_or_fail (glyph, + hb_draw_extents_get_funcs (), &draw_extents)) + { + *extents = draw_extents.to_glyph_extents (); + return true; + } ++#endif + + bool ret = klass->get.f.glyph_extents (this, user_data, + glyph, +@@ -575,6 +690,7 @@ struct hb_font_t + hb_draw_funcs_t *draw_funcs, void *draw_data, + bool synthetic = true) + { ++#ifndef HB_NO_DRAW + #ifndef HB_NO_OUTLINE + bool embolden = x_strength || y_strength; + bool slanted = slant_xy; +@@ -603,7 +719,13 @@ struct hb_font_t + // Slant before embolden; produces nicer results. + + if (slanted) ++ { ++ hb_position_t xo = 0, yo = 0; ++ get_glyph_h_origin (glyph, &xo, &yo, false); ++ outline.translate (-xo, -yo); + outline.slant (slant_xy); ++ outline.translate (xo, yo); ++ } + + if (embolden) + { +@@ -618,6 +740,8 @@ struct hb_font_t + + return true; + #endif ++#endif ++ return false; + } + + bool paint_glyph_or_fail (hb_codepoint_t glyph, +@@ -626,6 +750,7 @@ struct hb_font_t + hb_color_t foreground, + bool synthetic = true) + { ++#ifndef HB_NO_PAINT + /* Slant */ + if (synthetic && slant_xy) + hb_paint_push_transform (paint_funcs, paint_data, +@@ -643,6 +768,8 @@ struct hb_font_t + hb_paint_pop_transform (paint_funcs, paint_data); + + return ret; ++#endif ++ return false; + } + + /* A bit higher-level, and with fallback */ +@@ -704,6 +831,28 @@ struct hb_font_t + get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); + } + ++ void apply_offset (hb_position_t *x, hb_position_t *y, ++ hb_position_t dx, hb_position_t dy, ++ signed mult) ++ { ++ assert (mult == -1 || mult == +1); ++ ++ *x += dx * mult; ++ *y += dy * mult; ++ } ++ void add_offset (hb_position_t *x, hb_position_t *y, ++ hb_position_t dx, hb_position_t dy) ++ { ++ *x += dx; ++ *y += dy; ++ } ++ void subtract_offset (hb_position_t *x, hb_position_t *y, ++ hb_position_t dx, hb_position_t dy) ++ { ++ *x -= dx; ++ *y -= dy; ++ } ++ + void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { +@@ -714,6 +863,141 @@ struct hb_font_t + *y = extents.ascender; + } + ++ void apply_glyph_h_origins_with_fallback (hb_buffer_t *buf, int mult) ++ { ++ bool has_ascender = false; ++ hb_position_t ascender = 0; ++ ++ struct { hb_position_t x, y; } origins[32]; ++ ++ unsigned int offset = 0; ++ unsigned int count = buf->len; ++ while (offset < count) ++ { ++ unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); ++ if (!get_glyph_h_origins (n, ++ &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), ++ &origins[0].x, sizeof (origins[0]), ++ &origins[0].y, sizeof (origins[0]))) ++ { ++ if (get_glyph_v_origins (n, ++ &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), ++ &origins[0].x, sizeof (origins[0]), ++ &origins[0].y, sizeof (origins[0]))) ++ { ++ if (!has_ascender) ++ { ++ hb_font_extents_t extents; ++ get_h_extents_with_fallback (&extents); ++ ascender = extents.ascender; ++ has_ascender = true; ++ } ++ ++ /* We got the v_origins, adjust them to h_origins. */ ++ for (unsigned j = 0; j < n; j++) ++ { ++ hb_codepoint_t glyph = buf->info[offset + j].codepoint; ++ origins[j].x -= get_glyph_h_advance (glyph) / 2; ++ origins[j].y -= ascender; ++ } ++ } ++ else ++ { ++ for (unsigned j = 0; j < n; j++) ++ { ++ origins[j].x = 0; ++ origins[j].y = 0; ++ } ++ } ++ } ++ ++ assert (mult == -1 || mult == +1); ++ if (mult == +1) ++ for (unsigned j = 0; j < n; j++) ++ { ++ hb_glyph_position_t *pos = &buf->pos[offset + j]; ++ add_offset (&pos->x_offset, &pos->y_offset, ++ origins[j].x, origins[j].y); ++ } ++ else /* mult == -1 */ ++ for (unsigned j = 0; j < n; j++) ++ { ++ hb_glyph_position_t *pos = &buf->pos[offset + j]; ++ subtract_offset (&pos->x_offset, &pos->y_offset, ++ origins[j].x, origins[j].y); ++ } ++ ++ offset += n; ++ } ++ } ++ void apply_glyph_v_origins_with_fallback (hb_buffer_t *buf, int mult) ++ { ++ bool has_ascender = false; ++ hb_position_t ascender = 0; ++ ++ struct { hb_position_t x, y; } origins[32]; ++ ++ unsigned int offset = 0; ++ unsigned int count = buf->len; ++ while (offset < count) ++ { ++ unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); ++ if (!get_glyph_v_origins (n, ++ &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), ++ &origins[0].x, sizeof (origins[0]), ++ &origins[0].y, sizeof (origins[0]))) ++ { ++ if (get_glyph_h_origins (n, ++ &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), ++ &origins[0].x, sizeof (origins[0]), ++ &origins[0].y, sizeof (origins[0]))) ++ { ++ if (!has_ascender) ++ { ++ hb_font_extents_t extents; ++ get_h_extents_with_fallback (&extents); ++ ascender = extents.ascender; ++ has_ascender = true; ++ } ++ ++ /* We got the h_origins, adjust them to v_origins. */ ++ for (unsigned j = 0; j < n; j++) ++ { ++ hb_codepoint_t glyph = buf->info[offset + j].codepoint; ++ origins[j].x += get_glyph_h_advance (glyph) / 2; ++ origins[j].y += ascender; ++ } ++ } ++ else ++ { ++ for (unsigned j = 0; j < n; j++) ++ { ++ origins[j].x = 0; ++ origins[j].y = 0; ++ } ++ } ++ } ++ ++ assert (mult == -1 || mult == +1); ++ if (mult == +1) ++ for (unsigned j = 0; j < n; j++) ++ { ++ hb_glyph_position_t *pos = &buf->pos[offset + j]; ++ add_offset (&pos->x_offset, &pos->y_offset, ++ origins[j].x, origins[j].y); ++ } ++ else /* mult == -1 */ ++ for (unsigned j = 0; j < n; j++) ++ { ++ hb_glyph_position_t *pos = &buf->pos[offset + j]; ++ subtract_offset (&pos->x_offset, &pos->y_offset, ++ origins[j].x, origins[j].y); ++ } ++ ++ offset += n; ++ } ++ } ++ + void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { +@@ -722,7 +1006,7 @@ struct hb_font_t + { + hb_position_t dx, dy; + guess_v_origin_minus_h_origin (glyph, &dx, &dy); +- *x -= dx; *y -= dy; ++ subtract_offset (x, y, dx, dy); + } + } + void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph, +@@ -733,7 +1017,7 @@ struct hb_font_t + { + hb_position_t dx, dy; + guess_v_origin_minus_h_origin (glyph, &dx, &dy); +- *x += dx; *y += dy; ++ add_offset (x, y, dx, dy); + } + } + +@@ -747,68 +1031,38 @@ struct hb_font_t + get_glyph_v_origin_with_fallback (glyph, x, y); + } + +- void add_glyph_h_origin (hb_codepoint_t glyph, +- hb_position_t *x, hb_position_t *y) ++ void add_glyph_h_origins (hb_buffer_t *buf) + { +- hb_position_t origin_x, origin_y; +- +- get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); +- +- *x += origin_x; +- *y += origin_y; ++ apply_glyph_h_origins_with_fallback (buf, +1); + } +- void add_glyph_v_origin (hb_codepoint_t glyph, +- hb_position_t *x, hb_position_t *y) ++ void add_glyph_v_origins (hb_buffer_t *buf) + { +- hb_position_t origin_x, origin_y; +- +- get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); +- +- *x += origin_x; +- *y += origin_y; ++ apply_glyph_v_origins_with_fallback (buf, +1); + } + void add_glyph_origin_for_direction (hb_codepoint_t glyph, + hb_direction_t direction, + hb_position_t *x, hb_position_t *y) + { + hb_position_t origin_x, origin_y; +- + get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); +- +- *x += origin_x; +- *y += origin_y; ++ add_offset (x, y, origin_x, origin_y); + } + +- void subtract_glyph_h_origin (hb_codepoint_t glyph, +- hb_position_t *x, hb_position_t *y) ++ void subtract_glyph_h_origins (hb_buffer_t *buf) + { +- hb_position_t origin_x, origin_y; +- +- get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); +- +- *x -= origin_x; +- *y -= origin_y; ++ apply_glyph_h_origins_with_fallback (buf, -1); + } +- void subtract_glyph_v_origin (hb_codepoint_t glyph, +- hb_position_t *x, hb_position_t *y) ++ void subtract_glyph_v_origins (hb_buffer_t *buf) + { +- hb_position_t origin_x, origin_y; +- +- get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); +- +- *x -= origin_x; +- *y -= origin_y; ++ apply_glyph_v_origins_with_fallback (buf, -1); + } + void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, + hb_direction_t direction, + hb_position_t *x, hb_position_t *y) + { + hb_position_t origin_x, origin_y; +- + get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); +- +- *x -= origin_x; +- *y -= origin_y; ++ subtract_offset (x, y, origin_x, origin_y); + } + + void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, +@@ -890,11 +1144,6 @@ struct hb_font_t + return false; + } + +- bool is_synthetic () const +- { +- return x_embolden || y_embolden || slant; +- } +- + void changed () + { + float upem = face->get_upem (); +@@ -906,6 +1155,8 @@ struct hb_font_t + bool y_neg = y_scale < 0; + y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; + ++ is_synthetic = x_embolden || y_embolden || slant; ++ + x_strength = roundf (abs (x_scale) * x_embolden); + y_strength = roundf (abs (y_scale) * y_embolden); + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-pool.hh b/src/java.desktop/share/native/libharfbuzz/hb-free-pool.hh +similarity index 92% +rename from src/java.desktop/share/native/libharfbuzz/hb-pool.hh +rename to src/java.desktop/share/native/libharfbuzz/hb-free-pool.hh +index 613c78d1973..3acd144a857 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-pool.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-free-pool.hh +@@ -24,12 +24,12 @@ + * Facebook Author(s): Behdad Esfahbod + */ + +-#ifndef HB_POOL_HH +-#define HB_POOL_HH ++#ifndef HB_FREE_POOL_HH ++#define HB_FREE_POOL_HH + + #include "hb.hh" + +-/* Memory pool for persistent allocation of small objects. ++/* Memory pool for persistent alloc/free of small objects. + * + * Some AI musings on this, not necessarily true: + * +@@ -41,10 +41,10 @@ + * sophisticated, use a real allocator. Or use a real language. */ + + template +-struct hb_pool_t ++struct hb_free_pool_t + { +- hb_pool_t () : next (nullptr) {} +- ~hb_pool_t () ++ hb_free_pool_t () : next (nullptr) {} ++ ~hb_free_pool_t () + { + next = nullptr; + +@@ -104,4 +104,4 @@ struct hb_pool_t + }; + + +-#endif /* HB_POOL_HH */ ++#endif /* HB_FREE_POOL_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc +index e9c0e734a53..b90f966c57c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc +@@ -143,6 +143,9 @@ _hb_ft_font_destroy (void *data) + /* hb_font changed, update FT_Face. */ + static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) + { ++ if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) ++ return; ++ + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; + + float x_mult = 1.f, y_mult = 1.f; +@@ -184,12 +187,14 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) + FT_Set_Transform (ft_face, &matrix, nullptr); + ft_font->transform = true; + } ++ else ++ FT_Set_Transform (ft_face, nullptr, nullptr); + + #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) +- unsigned int num_coords; +- const float *coords = hb_font_get_var_coords_design (font, &num_coords); +- if (num_coords) ++ if (font->has_nonzero_coords) + { ++ unsigned int num_coords; ++ const float *coords = hb_font_get_var_coords_design (font, &num_coords); + FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); + if (ft_coords) + { +@@ -199,6 +204,12 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) + hb_free (ft_coords); + } + } ++ else if (font->num_coords) ++ { ++ // Some old versions of FreeType crash if we ++ // call this function on non-variable fonts. ++ FT_Set_Var_Design_Coordinates (ft_face, 0, nullptr); ++ } + #endif + } + +@@ -1093,6 +1104,10 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data + FT_ULong length = 0; + FT_Error error; + ++ /* In new FreeType, a tag value of 1 loads the SFNT table directory. Reject it. */ ++ if (tag == 1) ++ return nullptr; ++ + /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ + + error = FT_Load_Sfnt_Table (ft_face, tag, 0, nullptr, &length); +@@ -1366,7 +1381,7 @@ hb_ft_font_changed (hb_font_t *font) + + for (unsigned int i = 0; i < mm_var->num_axis; ++i) + { +- coords[i] = ft_coords[i] >>= 2; ++ coords[i] = (ft_coords[i] + 2) >> 2; + nonzero = nonzero || coords[i]; + } + +@@ -1717,7 +1732,12 @@ hb_ft_font_set_funcs (hb_font_t *font) + ft_face->generic.finalizer = _release_blob; + + // And the FT_Library to the blob +- hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true); ++ if (unlikely (!hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true))) ++ { ++ DEBUG_MSG (FT, font, "hb_blob_set_user_data() failed"); ++ FT_Done_Face (ft_face); ++ return; ++ } + + _hb_ft_font_set_funcs (font, ft_face, true); + hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh +index 795f29f6ab0..0de062df68e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh +@@ -26,7 +26,10 @@ + + #include "hb.hh" + ++#include "hb-algs.hh" + ++ ++template + struct hb_extents_t + { + hb_extents_t () {} +@@ -35,7 +38,7 @@ struct hb_extents_t + ymin (hb_min (extents.y_bearing, extents.y_bearing + extents.height)), + xmax (hb_max (extents.x_bearing, extents.x_bearing + extents.width)), + ymax (hb_max (extents.y_bearing, extents.y_bearing + extents.height)) {} +- hb_extents_t (float xmin, float ymin, float xmax, float ymax) : ++ hb_extents_t (Float xmin, Float ymin, Float xmax, Float ymax) : + xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} + + bool is_empty () const { return xmin >= xmax || ymin >= ymax; } +@@ -69,7 +72,7 @@ struct hb_extents_t + } + + void +- add_point (float x, float y) ++ add_point (Float x, Float y) + { + if (unlikely (is_void ())) + { +@@ -97,62 +100,69 @@ struct hb_extents_t + yneg ? y1 - y0 : y0 - y1}; + } + +- float xmin = 0.f; +- float ymin = 0.f; +- float xmax = -1.f; +- float ymax = -1.f; ++ Float xmin = 0; ++ Float ymin = 0; ++ Float xmax = -1; ++ Float ymax = -1; + }; + ++template + struct hb_transform_t + { + hb_transform_t () {} +- hb_transform_t (float xx, float yx, +- float xy, float yy, +- float x0, float y0) : ++ hb_transform_t (Float xx, Float yx, ++ Float xy, Float yy, ++ Float x0, Float y0) : + xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} + + bool is_identity () const + { +- return xx == 1.f && yx == 0.f && +- xy == 0.f && yy == 1.f && +- x0 == 0.f && y0 == 0.f; ++ return xx == 1 && yx == 0 && ++ xy == 0 && yy == 1 && ++ x0 == 0 && y0 == 0; + } +- +- void multiply (const hb_transform_t &o) ++ bool is_translation () const + { +- /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ +- hb_transform_t r; +- +- r.xx = o.xx * xx + o.yx * xy; +- r.yx = o.xx * yx + o.yx * yy; +- +- r.xy = o.xy * xx + o.yy * xy; +- r.yy = o.xy * yx + o.yy * yy; +- +- r.x0 = o.x0 * xx + o.y0 * xy + x0; +- r.y0 = o.x0 * yx + o.y0 * yy + y0; ++ return xx == 1 && yx == 0 && ++ xy == 0 && yy == 1; ++ } + +- *this = r; ++ void multiply (const hb_transform_t &o, bool before=false) ++ { ++ // Copied from cairo-matrix.c ++ const hb_transform_t &a = before ? o : *this; ++ const hb_transform_t &b = before ? *this : o; ++ *this = { ++ a.xx * b.xx + a.xy * b.yx, ++ a.yx * b.xx + a.yy * b.yx, ++ a.xx * b.xy + a.xy * b.yy, ++ a.yx * b.xy + a.yy * b.yy, ++ a.xx * b.x0 + a.xy * b.y0 + a.x0, ++ a.yx * b.x0 + a.yy * b.y0 + a.y0 ++ }; + } + +- void transform_distance (float &dx, float &dy) const ++ HB_ALWAYS_INLINE ++ void transform_distance (Float &dx, Float &dy) const + { +- float new_x = xx * dx + xy * dy; +- float new_y = yx * dx + yy * dy; ++ Float new_x = xx * dx + xy * dy; ++ Float new_y = yx * dx + yy * dy; + dx = new_x; + dy = new_y; + } + +- void transform_point (float &x, float &y) const ++ HB_ALWAYS_INLINE ++ void transform_point (Float &x, Float &y) const + { +- transform_distance (x, y); +- x += x0; +- y += y0; ++ Float new_x = x0 + xx * x + xy * y; ++ Float new_y = y0 + yx * x + yy * y; ++ x = new_x; ++ y = new_y; + } + +- void transform_extents (hb_extents_t &extents) const ++ void transform_extents (hb_extents_t &extents) const + { +- float quad_x[4], quad_y[4]; ++ Float quad_x[4], quad_y[4]; + + quad_x[0] = extents.xmin; + quad_y[0] = extents.ymin; +@@ -163,7 +173,7 @@ struct hb_transform_t + quad_x[3] = extents.xmax; + quad_y[3] = extents.ymax; + +- extents = hb_extents_t {}; ++ extents = hb_extents_t {}; + for (unsigned i = 0; i < 4; i++) + { + transform_point (quad_x[i], quad_y[i]); +@@ -171,20 +181,36 @@ struct hb_transform_t + } + } + +- void transform (const hb_transform_t &o) { multiply (o); } ++ void transform (const hb_transform_t &o, bool before=false) { multiply (o, before); } + +- void translate (float x, float y) ++ static hb_transform_t translation (Float x, Float y) + { +- if (x == 0.f && y == 0.f) +- return; ++ return {1, 0, 0, 1, x, y}; ++ } ++ void translate (Float x, Float y, bool before=false) ++ { ++ if (before) ++ { ++ x0 += x; ++ y0 += y; ++ } ++ else ++ { ++ if (x == 0 && y == 0) ++ return; + +- x0 += xx * x + xy * y; +- y0 += yx * x + yy * y; ++ x0 += xx * x + xy * y; ++ y0 += yx * x + yy * y; ++ } + } + +- void scale (float scaleX, float scaleY) ++ static hb_transform_t scaling (Float scaleX, Float scaleY) ++ { ++ return {scaleX, 0, 0, scaleY, 0, 0}; ++ } ++ void scale (Float scaleX, Float scaleY) + { +- if (scaleX == 1.f && scaleY == 1.f) ++ if (scaleX == 1 && scaleY == 1) + return; + + xx *= scaleX; +@@ -192,52 +218,94 @@ struct hb_transform_t + xy *= scaleY; + yy *= scaleY; + } +- +- void rotate (float rotation) ++ static hb_transform_t scaling_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) + { +- if (rotation == 0.f) ++ return {scaleX, 0, 0, scaleY, ++ center_x ? (1 - scaleX) * center_x : 0, ++ center_y ? (1 - scaleY) * center_y : 0}; ++ } ++ void scale_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) ++ { ++ if (scaleX == 1 && scaleY == 1) + return; + ++ transform (scaling_around_center (scaleX, scaleY, center_x, center_y)); ++ } ++ ++ static hb_transform_t rotation (Float radians) ++ { + // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 +- rotation = rotation * HB_PI; +- float c; +- float s; +-#ifdef HAVE_SINCOSF +- sincosf (rotation, &s, &c); +-#else +- c = cosf (rotation); +- s = sinf (rotation); +-#endif +- auto other = hb_transform_t{c, s, -s, c, 0.f, 0.f}; +- transform (other); ++ Float c; ++ Float s; ++ hb_sincos (radians, s, c); ++ return {c, s, -s, c, 0, 0}; ++ } ++ void rotate (Float radians, bool before=false) ++ { ++ if (radians == 0) ++ return; ++ ++ transform (rotation (radians), before); ++ } ++ ++ static hb_transform_t rotation_around_center (Float radians, Float center_x, Float center_y) ++ { ++ Float s, c; ++ hb_sincos (radians, s, c); ++ return { ++ c, s, -s, c, ++ (1 - c) * center_x + s * center_y, ++ -s * center_x + (1 - c) * center_y ++ }; ++ } ++ void rotate_around_center (Float radians, Float center_x, Float center_y, bool before=false) ++ { ++ if (radians == 0) ++ return; ++ ++ transform (rotation_around_center (radians, center_x, center_y), before); + } + +- void skew (float skewX, float skewY) ++ static hb_transform_t skewing (Float skewX, Float skewY) ++ { ++ return {1, skewY ? tanf (skewY) : 0, skewX ? tanf (skewX) : 0, 1, 0, 0}; ++ } ++ void skew (Float skewX, Float skewY) + { +- if (skewX == 0.f && skewY == 0.f) ++ if (skewX == 0 && skewY == 0) + return; + +- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 +- skewX = skewX * HB_PI; +- skewY = skewY * HB_PI; +- auto other = hb_transform_t{1.f, +- skewY ? tanf (skewY) : 0.f, +- skewX ? tanf (skewX) : 0.f, +- 1.f, +- 0.f, 0.f}; +- transform (other); ++ transform (skewing (skewX, skewY)); ++ } ++ static hb_transform_t skewing_around_center (Float skewX, Float skewY, Float center_x, Float center_y) ++ { ++ skewX = skewX ? tanf (skewX) : 0; ++ skewY = skewY ? tanf (skewY) : 0; ++ return { ++ 1, skewY, skewX, 1, ++ center_y ? -skewX * center_y : 0, ++ center_x ? -skewY * center_x : 0 ++ }; ++ } ++ void skew_around_center (Float skewX, Float skewY, Float center_x, Float center_y) ++ { ++ if (skewX == 0 && skewY == 0) ++ return; ++ ++ transform (skewing_around_center (skewX, skewY, center_x, center_y)); + } + +- float xx = 1.f; +- float yx = 0.f; +- float xy = 0.f; +- float yy = 1.f; +- float x0 = 0.f; +- float y0 = 0.f; ++ Float xx = 1; ++ Float yx = 0; ++ Float xy = 0; ++ Float yy = 1; ++ Float x0 = 0; ++ Float y0 = 0; + }; + +-#define HB_TRANSFORM_IDENTITY hb_transform_t{1.f, 0.f, 0.f, 1.f, 0.f, 0.f} ++#define HB_TRANSFORM_IDENTITY {1, 0, 0, 1, 0, 0} + ++template + struct hb_bounds_t + { + enum status_t { +@@ -247,7 +315,7 @@ struct hb_bounds_t + }; + + hb_bounds_t (status_t status = UNBOUNDED) : status (status) {} +- hb_bounds_t (const hb_extents_t &extents) : ++ hb_bounds_t (const hb_extents_t &extents) : + status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} + + void union_ (const hb_bounds_t &o) +@@ -281,20 +349,21 @@ struct hb_bounds_t + } + + status_t status; +- hb_extents_t extents; ++ hb_extents_t extents; + }; + ++template + struct hb_transform_decomposed_t + { +- float translateX = 0; +- float translateY = 0; +- float rotation = 0; // in degrees, counter-clockwise +- float scaleX = 1; +- float scaleY = 1; +- float skewX = 0; // in degrees, counter-clockwise +- float skewY = 0; // in degrees, counter-clockwise +- float tCenterX = 0; +- float tCenterY = 0; ++ Float translateX = 0; ++ Float translateY = 0; ++ Float rotation = 0; // in radians, counter-clockwise ++ Float scaleX = 1; ++ Float scaleY = 1; ++ Float skewX = 0; // in radians, counter-clockwise ++ Float skewY = 0; // in radians, counter-clockwise ++ Float tCenterX = 0; ++ Float tCenterY = 0; + + operator bool () const + { +@@ -305,9 +374,9 @@ struct hb_transform_decomposed_t + tCenterX || tCenterY; + } + +- hb_transform_t to_transform () const ++ hb_transform_t to_transform () const + { +- hb_transform_t t; ++ hb_transform_t t; + t.translate (translateX + tCenterX, translateY + tCenterY); + t.rotate (rotation); + t.scale (scaleX, scaleY); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh +index 21d9544a74b..661e6771a4a 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh +@@ -772,8 +772,9 @@ struct hb_iota_iter_t : + template + auto + inc (hb_type_identity s, hb_priority<1>) +- -> hb_void_t (s), hb_declval ()))> +- { v = hb_invoke (std::forward (s), v); } ++ -> hb_void_t> (s), ++ hb_declval ()))> ++ { v = hb_invoke (std::forward> (s), v); } + + void + inc (S s, hb_priority<0>) +@@ -972,7 +973,7 @@ struct + Proj&& f = hb_identity) const + { + for (auto it = hb_iter (c); it; ++it) +- if (!hb_match (std::forward (p), hb_get (std::forward (f), *it))) ++ if (!hb_match (p, hb_get (f, *it))) + return false; + return true; + } +@@ -989,7 +990,7 @@ struct + Proj&& f = hb_identity) const + { + for (auto it = hb_iter (c); it; ++it) +- if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) ++ if (hb_match (p, hb_get (f, *it))) + return true; + return false; + } +@@ -1006,7 +1007,7 @@ struct + Proj&& f = hb_identity) const + { + for (auto it = hb_iter (c); it; ++it) +- if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) ++ if (hb_match (p, hb_get (f, *it))) + return false; + return true; + } +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-kern.hh b/src/java.desktop/share/native/libharfbuzz/hb-kern.hh +index 1f2c8d5811b..cf08c16689f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-kern.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-kern.hh +@@ -70,7 +70,7 @@ struct hb_kern_machine_t + continue; + } + +- skippy_iter.reset (idx); ++ skippy_iter.reset_fast (idx); + unsigned unsafe_to; + if (!skippy_iter.next (&unsafe_to)) + { +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-limits.hh b/src/java.desktop/share/native/libharfbuzz/hb-limits.hh +index fbc7bbe764e..857e183737f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-limits.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-limits.hh +@@ -29,20 +29,20 @@ + + + #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! */ + #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! */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh +index ffbb8f3d301..8fa32ea8eaa 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh +@@ -66,13 +66,22 @@ static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset) + } + + /* StructAfter(X) returns the struct T& that is placed after X. +- * Works with X of variable size also. X must implement get_size() */ +-template +-static inline const Type& StructAfter(const TObject &X) +-{ return StructAtOffset(&X, X.get_size()); } +-template +-static inline Type& StructAfter(TObject &X) +-{ return StructAtOffset(&X, X.get_size()); } ++ * Works with X of variable size also. X must implement get_size(). ++ * Any extra arguments are forwarded to get_size, so for example ++ * it can work with UnsizedArrayOf<> as well. */ ++template ++static inline auto StructAfter(const TObject &X, Ts... args) HB_AUTO_RETURN(( ++ StructAtOffset(&X, X.get_size(std::forward (args)...)) ++)) ++/* The is_const shenanigans is to avoid ambiguous overload with gcc-8. ++ * It disables this path when TObject is const. ++ * See: https://github.com/harfbuzz/harfbuzz/issues/5429 */ ++template ++static inline auto StructAfter(TObject &X, Ts... args) HB_AUTO_RETURN(( ++ sizeof(int[std::is_const::value ? -1 : +1]) > 0 ? ++ StructAtOffset(&X, X.get_size(std::forward (args)...)) ++ : *reinterpret_cast (0) ++)) + + + /* +@@ -132,7 +141,6 @@ static inline Type& StructAfter(TObject &X) + DEFINE_SIZE_ARRAY(size, array) + + +- + /* + * Lazy loaders. + * +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-map.hh b/src/java.desktop/share/native/libharfbuzz/hb-map.hh +index 76206342f57..4c76622df7a 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-map.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-map.hh +@@ -47,11 +47,11 @@ struct hb_hashmap_t + hb_hashmap_t () { init (); } + ~hb_hashmap_t () { fini (); } + +- hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () ++ void _copy (const hb_hashmap_t& o) + { + if (unlikely (!o.mask)) return; + +- if (item_t::is_trivial) ++ if (hb_is_trivially_copy_assignable (item_t)) + { + items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); + if (unlikely (!items)) +@@ -70,8 +70,16 @@ struct hb_hashmap_t + + alloc (o.population); hb_copy (o, *this); + } ++ ++ hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { _copy (o); } ++ hb_hashmap_t& operator= (const hb_hashmap_t& o) ++ { ++ reset (); ++ if (!items) { _copy (o); return *this; } ++ alloc (o.population); hb_copy (o, *this); return *this; ++ } ++ + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } +- hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } + hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } + + hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () +@@ -130,10 +138,7 @@ struct hb_hashmap_t + uint32_t total_hash () const + { return (hash * 31u) + hb_hash (value); } + +- static constexpr bool is_trivial = hb_is_trivially_constructible(K) && +- hb_is_trivially_destructible(K) && +- hb_is_trivially_constructible(V) && +- hb_is_trivially_destructible(V); ++ static constexpr bool is_trivially_constructible = (hb_is_trivially_constructible(K) && hb_is_trivially_constructible(V)); + }; + + hb_object_header_t header; +@@ -174,19 +179,19 @@ struct hb_hashmap_t + if (likely (items)) + { + unsigned size = mask + 1; +- if (!item_t::is_trivial) +- for (unsigned i = 0; i < size; i++) +- items[i].~item_t (); ++ for (unsigned i = 0; i < size; i++) ++ items[i].~item_t (); + hb_free (items); + items = nullptr; + } + population = occupancy = 0; + } + +- void reset () ++ hb_hashmap_t& reset () + { + successful = true; + clear (); ++ return *this; + } + + bool in_error () const { return !successful; } +@@ -197,7 +202,7 @@ struct hb_hashmap_t + + if (new_population != 0 && (new_population + new_population / 2) < mask) return true; + +- unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8); ++ unsigned int power = hb_bit_storage (hb_max (hb_max ((unsigned) population, new_population) * 2, 4u)); + unsigned int new_size = 1u << power; + item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); + if (unlikely (!new_items)) +@@ -205,7 +210,7 @@ struct hb_hashmap_t + successful = false; + return false; + } +- if (!item_t::is_trivial) ++ if (!item_t::is_trivially_constructible) + for (auto &_ : hb_iter (new_items, new_size)) + new (&_) item_t (); + else +@@ -231,9 +236,8 @@ struct hb_hashmap_t + std::move (old_items[i].value)); + } + } +- if (!item_t::is_trivial) +- for (unsigned int i = 0; i < old_size; i++) +- old_items[i].~item_t (); ++ for (unsigned int i = 0; i < old_size; i++) ++ old_items[i].~item_t (); + + hb_free (old_items); + +@@ -335,7 +339,13 @@ struct hb_hashmap_t + bool has (const K &key, VV **vp = nullptr) const + { + if (!items) return false; +- auto *item = fetch_item (key, hb_hash (key)); ++ return has_with_hash (key, hb_hash (key), vp); ++ } ++ template ++ bool has_with_hash (const K &key, uint32_t hash, VV **vp = nullptr) const ++ { ++ if (!items) return false; ++ auto *item = fetch_item (key, hash); + if (item) + { + if (vp) *vp = std::addressof (item->value); +@@ -481,10 +491,17 @@ struct hb_hashmap_t + /* Sink interface. */ + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (v.first, v.second); return *this; } ++ template + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (v.first, std::move (v.second)); return *this; } ++ template + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (std::move (v.first), v.second); return *this; } ++ template + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (std::move (v.first), std::move (v.second)); return *this; } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh b/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh +index 9d2867e4835..07f3ebe0c7d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh +@@ -31,7 +31,7 @@ + #include "hb.hh" + + +-#line 35 "hb-number-parser.hh" ++#line 32 "hb-number-parser.hh" + static const unsigned char _double_parser_trans_keys[] = { + 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, + 46u, 101u, 0 +@@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) + + int cs; + +-#line 139 "hb-number-parser.hh" ++#line 132 "hb-number-parser.hh" + { + cs = double_parser_start; + } + +-#line 144 "hb-number-parser.hh" ++#line 135 "hb-number-parser.hh" + { + int _slen; + int _trans; +@@ -198,7 +198,7 @@ _resume: + exp_overflow = true; + } + break; +-#line 202 "hb-number-parser.hh" ++#line 187 "hb-number-parser.hh" + } + + _again: +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh +index 382ee2ddaf2..538240b6416 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh +@@ -465,11 +465,11 @@ struct OpenTypeFontFile + Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */ + }; + +- hb_tag_t get_tag () const { return u.tag; } ++ hb_tag_t get_tag () const { return u.tag.v; } + + unsigned int get_face_count () const + { +- switch (u.tag) { ++ switch (u.tag.v) { + case CFFTag: /* All the non-collection tags */ + case TrueTag: + case Typ1Tag: +@@ -483,7 +483,7 @@ struct OpenTypeFontFile + { + if (base_offset) + *base_offset = 0; +- switch (u.tag) { ++ switch (u.tag.v) { + /* Note: for non-collection SFNT data we ignore index. This is because + * Apple dfont container is a container of SFNT's. So each SFNT is a + * non-TTC, but the index is more than zero. */ +@@ -512,9 +512,9 @@ struct OpenTypeFontFile + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (unlikely (!u.tag.sanitize (c))) return_trace (false); ++ if (unlikely (!u.tag.v.sanitize (c))) return_trace (false); + hb_barrier (); +- switch (u.tag) { ++ switch (u.tag.v) { + case CFFTag: /* All the non-collection tags */ + case TrueTag: + case Typ1Tag: +@@ -527,13 +527,13 @@ struct OpenTypeFontFile + + protected: + union { +- Tag tag; /* 4-byte identifier. */ ++ struct { Tag v; } tag; /* 4-byte identifier. */ + OpenTypeFontFace fontFace; + TTCHeader ttcHeader; + ResourceForkHeader rfHeader; + } u; + public: +- DEFINE_SIZE_UNION (4, tag); ++ DEFINE_SIZE_UNION (4, tag.v); + }; + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh +index 75d87f11ea5..ad831b66d56 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh +@@ -54,35 +54,41 @@ namespace OT { + */ + + /* Integer types in big-endian order and no alignment requirement */ +-template +-struct IntType ++struct NumType + { + typedef Type type; +- +- IntType () = default; +- explicit constexpr IntType (Type V) : v {V} {} +- IntType& operator = (Type i) { v = i; return *this; } + /* For reason we define cast out operator for signed/unsigned, instead of Type, see: + * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ +- operator typename std::conditional::value, signed, unsigned>::type () const { return v; } ++ typedef typename std::conditional::value && sizeof (Type) <= sizeof(int), ++ typename std::conditional::value, signed, unsigned>::type, ++ Type>::type WideType; ++ ++ NumType () = default; ++ explicit constexpr NumType (Type V) : v {V} {} ++ NumType& operator = (Type V) { v = V; return *this; } ++ ++ operator WideType () const { return v; } + +- bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } +- bool operator != (const IntType &o) const { return !(*this == o); } ++ bool operator == (const NumType &o) const { return (Type) v == (Type) o.v; } ++ bool operator != (const NumType &o) const { return !(*this == o); } + +- IntType& operator += (unsigned count) { *this = *this + count; return *this; } +- IntType& operator -= (unsigned count) { *this = *this - count; return *this; } +- IntType& operator ++ () { *this += 1; return *this; } +- IntType& operator -- () { *this -= 1; return *this; } +- IntType operator ++ (int) { IntType c (*this); ++*this; return c; } +- IntType operator -- (int) { IntType c (*this); --*this; return c; } ++ NumType& operator += (WideType count) { *this = *this + count; return *this; } ++ NumType& operator -= (WideType count) { *this = *this - count; return *this; } ++ NumType& operator ++ () { *this += 1; return *this; } ++ NumType& operator -- () { *this -= 1; return *this; } ++ NumType operator ++ (int) { NumType c (*this); ++*this; return c; } ++ NumType operator -- (int) { NumType c (*this); --*this; return c; } + +- HB_INTERNAL static int cmp (const IntType *a, const IntType *b) ++ uint32_t hash () const { return hb_array ((const char *) &v, sizeof (v)).hash (); } ++ HB_INTERNAL static int cmp (const NumType *a, const NumType *b) + { return b->cmp (*a); } + HB_INTERNAL static int cmp (const void *a, const void *b) + { +- IntType *pa = (IntType *) a; +- IntType *pb = (IntType *) b; ++ NumType *pa = (NumType *) a; ++ NumType *pb = (NumType *) b; + + return pb->cmp (*pa); + } +@@ -99,20 +105,36 @@ struct IntType + return_trace (c->check_struct (this)); + } + protected: +- BEInt v; ++ typename std::conditional::value, ++ HBInt, ++ HBFloat>::type v; + public: + DEFINE_SIZE_STATIC (Size); + }; + +-typedef IntType HBUINT8; /* 8-bit unsigned integer. */ +-typedef IntType HBINT8; /* 8-bit signed integer. */ +-typedef IntType HBUINT16; /* 16-bit unsigned integer. */ +-typedef IntType HBINT16; /* 16-bit signed integer. */ +-typedef IntType HBUINT32; /* 32-bit unsigned integer. */ +-typedef IntType HBINT32; /* 32-bit signed integer. */ ++typedef NumType HBUINT8; /* 8-bit big-endian unsigned integer. */ ++typedef NumType HBINT8; /* 8-bit big-endian signed integer. */ ++typedef NumType HBUINT16; /* 16-bit big-endian unsigned integer. */ ++typedef NumType HBINT16; /* 16-bit big-endian signed integer. */ ++typedef NumType HBUINT32; /* 32-bit big-endian unsigned integer. */ ++typedef NumType HBINT32; /* 32-bit big-endian signed integer. */ ++typedef NumType HBUINT64; /* 64-bit big-endian unsigned integer. */ ++typedef NumType HBINT64; /* 64-bit big-endian signed integer. */ + /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. + * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ +-typedef IntType HBUINT24; /* 24-bit unsigned integer. */ ++typedef NumType HBUINT24; /* 24-bit big-endian unsigned integer. */ ++ ++typedef NumType HBUINT16LE; /* 16-bit little-endian unsigned integer. */ ++typedef NumType HBINT16LE; /* 16-bit little-endian signed integer. */ ++typedef NumType HBUINT32LE; /* 32-bit little-endian unsigned integer. */ ++typedef NumType HBINT32LE; /* 32-bit little-endian signed integer. */ ++typedef NumType HBUINT64LE; /* 64-bit little-endian unsigned integer. */ ++typedef NumType HBINT64LE; /* 64-bit little-endian signed integer. */ ++ ++typedef NumType HBFLOAT32BE; /* 32-bit little-endian floating point number. */ ++typedef NumType HBFLOAT64BE; /* 64-bit little-endian floating point number. */ ++typedef NumType HBFLOAT32LE; /* 32-bit little-endian floating point number. */ ++typedef NumType HBFLOAT64LE; /* 64-bit little-endian floating point number. */ + + /* 15-bit unsigned number; top bit used for extension. */ + struct HBUINT15 : HBUINT16 +@@ -218,7 +240,7 @@ typedef HBUINT16 UFWORD; + template + struct HBFixed : Type + { +- static constexpr float shift = (float) (1 << fraction_bits); ++ static constexpr float mult = 1.f / (1 << fraction_bits); + static_assert (Type::static_size * 8 > fraction_bits, ""); + + operator signed () const = delete; +@@ -226,8 +248,8 @@ struct HBFixed : Type + explicit operator float () const { return to_float (); } + typename Type::type to_int () const { return Type::v; } + void set_int (typename Type::type i ) { Type::v = i; } +- float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } +- void set_float (float f) { Type::v = roundf (f * shift); } ++ float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) * mult; } ++ void set_float (float f) { Type::v = roundf (f / mult); } + public: + DEFINE_SIZE_STATIC (Type::static_size); + }; +@@ -504,16 +526,9 @@ struct OffsetTo : Offset + return_trace (sanitize_shallow (c, base) && + hb_barrier () && + (this->is_null () || +- c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || +- neuter (c))); ++ c->dispatch (StructAtOffset (base, *this), std::forward (ds)...))); + } + +- /* Set the offset to Null */ +- bool neuter (hb_sanitize_context_t *c) const +- { +- if (!has_null) return false; +- return c->try_set (this, 0); +- } + DEFINE_SIZE_STATIC (sizeof (OffsetType)); + }; + /* Partial specializations. */ +@@ -1481,8 +1496,8 @@ struct TupleValues + VALUE_RUN_COUNT_MASK = 0x3F + }; + +- static unsigned compile (hb_array_t values, /* IN */ +- hb_array_t encoded_bytes /* OUT */) ++ static unsigned compile_unsafe (hb_array_t values, /* IN */ ++ unsigned char *encoded_bytes /* OUT */) + { + unsigned num_values = values.length; + unsigned encoded_len = 0; +@@ -1491,24 +1506,23 @@ struct TupleValues + { + int val = values.arrayZ[i]; + if (val == 0) +- encoded_len += encode_value_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), values); +- else if (val >= -128 && val <= 127) +- encoded_len += encode_value_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), values); +- else if (val >= -32768 && val <= 32767) +- encoded_len += encode_value_run_as_words (i, encoded_bytes.sub_array (encoded_len), values); ++ encoded_len += encode_value_run_as_zeroes (i, encoded_bytes + encoded_len, values); ++ else if ((int8_t) val == val) ++ encoded_len += encode_value_run_as_bytes (i, encoded_bytes + encoded_len, values); ++ else if ((int16_t) val == val) ++ encoded_len += encode_value_run_as_words (i, encoded_bytes + encoded_len, values); + else +- encoded_len += encode_value_run_as_longs (i, encoded_bytes.sub_array (encoded_len), values); ++ encoded_len += encode_value_run_as_longs (i, encoded_bytes + encoded_len, values); + } + return encoded_len; + } + + static unsigned encode_value_run_as_zeroes (unsigned& i, +- hb_array_t encoded_bytes, ++ unsigned char *it, + hb_array_t values) + { + unsigned num_values = values.length; + unsigned run_length = 0; +- auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (i < num_values && values.arrayZ[i] == 0) + { +@@ -1532,7 +1546,7 @@ struct TupleValues + } + + static unsigned encode_value_run_as_bytes (unsigned &i, +- hb_array_t encoded_bytes, ++ unsigned char *it, + hb_array_t values) + { + unsigned start = i; +@@ -1540,7 +1554,7 @@ struct TupleValues + while (i < num_values) + { + int val = values.arrayZ[i]; +- if (val > 127 || val < -128) ++ if ((int8_t) val != val) + break; + + /* from fonttools: if there're 2 or more zeros in a sequence, +@@ -1553,7 +1567,6 @@ struct TupleValues + unsigned run_length = i - start; + + unsigned encoded_len = 0; +- auto it = encoded_bytes.iter (); + + while (run_length >= 64) + { +@@ -1561,10 +1574,9 @@ struct TupleValues + encoded_len++; + + for (unsigned j = 0; j < 64; j++) +- { +- *it++ = static_cast (values.arrayZ[start + j]); +- encoded_len++; +- } ++ it[j] = static_cast (values.arrayZ[start + j]); ++ it += 64; ++ encoded_len += 64; + + start += 64; + run_length -= 64; +@@ -1575,18 +1587,16 @@ struct TupleValues + *it++ = (VALUES_ARE_BYTES | (run_length - 1)); + encoded_len++; + +- while (start < i) +- { +- *it++ = static_cast (values.arrayZ[start++]); +- encoded_len++; +- } ++ for (unsigned j = 0; j < run_length; j++) ++ it[j] = static_cast (values.arrayZ[start + j]); ++ encoded_len += run_length; + } + + return encoded_len; + } + + static unsigned encode_value_run_as_words (unsigned &i, +- hb_array_t encoded_bytes, ++ unsigned char *it, + hb_array_t values) + { + unsigned start = i; +@@ -1595,22 +1605,24 @@ struct TupleValues + { + int val = values.arrayZ[i]; + +- /* start a new run for a single zero value*/ ++ if ((int16_t) val != val) ++ break; ++ ++ /* start a new run for a single zero value. */ + if (val == 0) break; + +- /* from fonttools: continue word-encoded run if there's only one ++ /* From fonttools: continue word-encoded run if there's only one + * single value in the range [-128, 127] because it is more compact. + * Only start a new run when there're 2 continuous such values. */ +- if (val >= -128 && val <= 127 && ++ if ((int8_t) val == val && + i + 1 < num_values && +- values.arrayZ[i+1] >= -128 && values.arrayZ[i+1] <= 127) ++ (int8_t) values.arrayZ[i+1] == values.arrayZ[i+1]) + break; + + i++; + } + + unsigned run_length = i - start; +- auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { +@@ -1647,7 +1659,7 @@ struct TupleValues + } + + static unsigned encode_value_run_as_longs (unsigned &i, +- hb_array_t encoded_bytes, ++ unsigned char *it, + hb_array_t values) + { + unsigned start = i; +@@ -1656,14 +1668,13 @@ struct TupleValues + { + int val = values.arrayZ[i]; + +- if (val >= -32768 && val <= 32767) ++ if ((int16_t) val == val) + break; + + i++; + } + + unsigned run_length = i - start; +- auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { +@@ -1704,10 +1715,14 @@ struct TupleValues + } + + template ++#ifndef HB_OPTIMIZE_SIZE ++ HB_ALWAYS_INLINE ++#endif + static bool decompile (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &values /* IN/OUT */, + const HBUINT8 *end, +- bool consume_all = false) ++ bool consume_all = false, ++ unsigned start = 0) + { + unsigned i = 0; + unsigned count = consume_all ? UINT_MAX : values.length; +@@ -1720,19 +1735,24 @@ struct TupleValues + unsigned run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + if (consume_all) + { +- if (unlikely (!values.resize (values.length + run_count, false))) ++ if (unlikely (!values.resize_dirty (values.length + run_count))) + return false; + } + unsigned stop = i + run_count; + if (unlikely (stop > count)) return false; ++ ++ unsigned skip = i < start ? hb_min (start - i, run_count) : 0; ++ i += skip; ++ + if ((control & VALUES_SIZE_MASK) == VALUES_ARE_ZEROS) + { +- for (; i < stop; i++) +- values.arrayZ[i] = 0; ++ hb_memset (&values.arrayZ[i], 0, (stop - i) * sizeof (T)); ++ i = stop; + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) + { + if (unlikely (p + run_count * HBINT16::static_size > end)) return false; ++ p += skip * HBINT16::static_size; + #ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { +@@ -1755,6 +1775,7 @@ struct TupleValues + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_LONGS) + { + if (unlikely (p + run_count * HBINT32::static_size > end)) return false; ++ p += skip * HBINT32::static_size; + for (; i < stop; i++) + { + values.arrayZ[i] = * (const HBINT32 *) p; +@@ -1764,6 +1785,7 @@ struct TupleValues + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) + { + if (unlikely (p + run_count > end)) return false; ++ p += skip * HBINT8::static_size; + #ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { +@@ -1784,7 +1806,7 @@ struct TupleValues + { + iter_t (const unsigned char *p_, unsigned len_) + : p (p_), endp (p_ + len_) +- { if (ensure_run ()) read_value (); } ++ { if (likely (ensure_run ())) read_value (); } + + private: + const unsigned char *p; +@@ -1793,10 +1815,14 @@ struct TupleValues + signed run_count = 0; + unsigned width = 0; + ++ HB_ALWAYS_INLINE + bool ensure_run () + { + if (likely (run_count > 0)) return true; +- ++ return _ensure_run (); ++ } ++ bool _ensure_run () ++ { + if (unlikely (p >= endp)) + { + run_count = 0; +@@ -1886,10 +1912,15 @@ struct TupleValues + signed run_count = 0; + unsigned width = 0; + ++ HB_ALWAYS_INLINE + bool ensure_run () + { +- if (run_count > 0) return true; ++ if (likely (run_count > 0)) return true; ++ return _ensure_run (); ++ } + ++ bool _ensure_run () ++ { + if (unlikely (p >= end)) + { + run_count = 0; +@@ -2013,7 +2044,10 @@ struct TupleValues + } + + #ifndef HB_OPTIMIZE_SIZE +- if (scale == 1.0f) ++ // The following branch is supposed to speed things up by avoiding ++ // the multiplication in _add_to<> if scale is 1.0f. ++ // But in practice it seems to bloat the code and slow things down. ++ if (false && scale == 1.0f) + _add_to (out); + else + #endif +@@ -2038,6 +2072,23 @@ struct TupleList : CFF2Index + }; + + ++// Alignment ++ ++template ++struct Align ++{ ++ unsigned get_size (const void *base) const ++ { ++ unsigned offset = (const char *) this - (const char *) base; ++ return (alignment - offset) & (alignment - 1); ++ } ++ ++ public: ++ DEFINE_SIZE_MIN (0); ++}; ++ ++ ++ + } /* namespace OT */ + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh +index 1e3e0be5106..ec018efe645 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh +@@ -79,7 +79,7 @@ struct Dict : UnsizedByteStr + { + TRACE_SERIALIZE (this); + for (unsigned int i = 0; i < dictval.get_count (); i++) +- if (unlikely (!opszr.serialize (c, dictval[i], std::forward (ds)...))) ++ if (unlikely (!opszr.serialize (c, dictval[i], ds...))) + return_trace (false); + + return_trace (true); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh +index 65d56ae18b5..bf56abb975c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-std-str.hh +@@ -30,396 +30,396 @@ + #include "hb.hh" + #endif + +-_S(".notdef") +-_S("space") +-_S("exclam") +-_S("quotedbl") +-_S("numbersign") +-_S("dollar") +-_S("percent") +-_S("ampersand") +-_S("quoteright") +-_S("parenleft") +-_S("parenright") +-_S("asterisk") +-_S("plus") +-_S("comma") +-_S("hyphen") +-_S("period") +-_S("slash") +-_S("zero") +-_S("one") +-_S("two") +-_S("three") +-_S("four") +-_S("five") +-_S("six") +-_S("seven") +-_S("eight") +-_S("nine") +-_S("colon") +-_S("semicolon") +-_S("less") +-_S("equal") +-_S("greater") +-_S("question") +-_S("at") +-_S("A") +-_S("B") +-_S("C") +-_S("D") +-_S("E") +-_S("F") +-_S("G") +-_S("H") +-_S("I") +-_S("J") +-_S("K") +-_S("L") +-_S("M") +-_S("N") +-_S("O") +-_S("P") +-_S("Q") +-_S("R") +-_S("S") +-_S("T") +-_S("U") +-_S("V") +-_S("W") +-_S("X") +-_S("Y") +-_S("Z") +-_S("bracketleft") +-_S("backslash") +-_S("bracketright") +-_S("asciicircum") +-_S("underscore") +-_S("quoteleft") +-_S("a") +-_S("b") +-_S("c") +-_S("d") +-_S("e") +-_S("f") +-_S("g") +-_S("h") +-_S("i") +-_S("j") +-_S("k") +-_S("l") +-_S("m") +-_S("n") +-_S("o") +-_S("p") +-_S("q") +-_S("r") +-_S("s") +-_S("t") +-_S("u") +-_S("v") +-_S("w") +-_S("x") +-_S("y") +-_S("z") +-_S("braceleft") +-_S("bar") +-_S("braceright") +-_S("asciitilde") +-_S("exclamdown") +-_S("cent") +-_S("sterling") +-_S("fraction") +-_S("yen") +-_S("florin") +-_S("section") +-_S("currency") +-_S("quotesingle") +-_S("quotedblleft") +-_S("guillemotleft") +-_S("guilsinglleft") +-_S("guilsinglright") +-_S("fi") +-_S("fl") +-_S("endash") +-_S("dagger") +-_S("daggerdbl") +-_S("periodcentered") +-_S("paragraph") +-_S("bullet") +-_S("quotesinglbase") +-_S("quotedblbase") +-_S("quotedblright") +-_S("guillemotright") +-_S("ellipsis") +-_S("perthousand") +-_S("questiondown") +-_S("grave") +-_S("acute") +-_S("circumflex") +-_S("tilde") +-_S("macron") +-_S("breve") +-_S("dotaccent") +-_S("dieresis") +-_S("ring") +-_S("cedilla") +-_S("hungarumlaut") +-_S("ogonek") +-_S("caron") +-_S("emdash") +-_S("AE") +-_S("ordfeminine") +-_S("Lslash") +-_S("Oslash") +-_S("OE") +-_S("ordmasculine") +-_S("ae") +-_S("dotlessi") +-_S("lslash") +-_S("oslash") +-_S("oe") +-_S("germandbls") +-_S("onesuperior") +-_S("logicalnot") +-_S("mu") +-_S("trademark") +-_S("Eth") +-_S("onehalf") +-_S("plusminus") +-_S("Thorn") +-_S("onequarter") +-_S("divide") +-_S("brokenbar") +-_S("degree") +-_S("thorn") +-_S("threequarters") +-_S("twosuperior") +-_S("registered") +-_S("minus") +-_S("eth") +-_S("multiply") +-_S("threesuperior") +-_S("copyright") +-_S("Aacute") +-_S("Acircumflex") +-_S("Adieresis") +-_S("Agrave") +-_S("Aring") +-_S("Atilde") +-_S("Ccedilla") +-_S("Eacute") +-_S("Ecircumflex") +-_S("Edieresis") +-_S("Egrave") +-_S("Iacute") +-_S("Icircumflex") +-_S("Idieresis") +-_S("Igrave") +-_S("Ntilde") +-_S("Oacute") +-_S("Ocircumflex") +-_S("Odieresis") +-_S("Ograve") +-_S("Otilde") +-_S("Scaron") +-_S("Uacute") +-_S("Ucircumflex") +-_S("Udieresis") +-_S("Ugrave") +-_S("Yacute") +-_S("Ydieresis") +-_S("Zcaron") +-_S("aacute") +-_S("acircumflex") +-_S("adieresis") +-_S("agrave") +-_S("aring") +-_S("atilde") +-_S("ccedilla") +-_S("eacute") +-_S("ecircumflex") +-_S("edieresis") +-_S("egrave") +-_S("iacute") +-_S("icircumflex") +-_S("idieresis") +-_S("igrave") +-_S("ntilde") +-_S("oacute") +-_S("ocircumflex") +-_S("odieresis") +-_S("ograve") +-_S("otilde") +-_S("scaron") +-_S("uacute") +-_S("ucircumflex") +-_S("udieresis") +-_S("ugrave") +-_S("yacute") +-_S("ydieresis") +-_S("zcaron") +-_S("exclamsmall") +-_S("Hungarumlautsmall") +-_S("dollaroldstyle") +-_S("dollarsuperior") +-_S("ampersandsmall") +-_S("Acutesmall") +-_S("parenleftsuperior") +-_S("parenrightsuperior") +-_S("twodotenleader") +-_S("onedotenleader") +-_S("zerooldstyle") +-_S("oneoldstyle") +-_S("twooldstyle") +-_S("threeoldstyle") +-_S("fouroldstyle") +-_S("fiveoldstyle") +-_S("sixoldstyle") +-_S("sevenoldstyle") +-_S("eightoldstyle") +-_S("nineoldstyle") +-_S("commasuperior") +-_S("threequartersemdash") +-_S("periodsuperior") +-_S("questionsmall") +-_S("asuperior") +-_S("bsuperior") +-_S("centsuperior") +-_S("dsuperior") +-_S("esuperior") +-_S("isuperior") +-_S("lsuperior") +-_S("msuperior") +-_S("nsuperior") +-_S("osuperior") +-_S("rsuperior") +-_S("ssuperior") +-_S("tsuperior") +-_S("ff") +-_S("ffi") +-_S("ffl") +-_S("parenleftinferior") +-_S("parenrightinferior") +-_S("Circumflexsmall") +-_S("hyphensuperior") +-_S("Gravesmall") +-_S("Asmall") +-_S("Bsmall") +-_S("Csmall") +-_S("Dsmall") +-_S("Esmall") +-_S("Fsmall") +-_S("Gsmall") +-_S("Hsmall") +-_S("Ismall") +-_S("Jsmall") +-_S("Ksmall") +-_S("Lsmall") +-_S("Msmall") +-_S("Nsmall") +-_S("Osmall") +-_S("Psmall") +-_S("Qsmall") +-_S("Rsmall") +-_S("Ssmall") +-_S("Tsmall") +-_S("Usmall") +-_S("Vsmall") +-_S("Wsmall") +-_S("Xsmall") +-_S("Ysmall") +-_S("Zsmall") +-_S("colonmonetary") +-_S("onefitted") +-_S("rupiah") +-_S("Tildesmall") +-_S("exclamdownsmall") +-_S("centoldstyle") +-_S("Lslashsmall") +-_S("Scaronsmall") +-_S("Zcaronsmall") +-_S("Dieresissmall") +-_S("Brevesmall") +-_S("Caronsmall") +-_S("Dotaccentsmall") +-_S("Macronsmall") +-_S("figuredash") +-_S("hypheninferior") +-_S("Ogoneksmall") +-_S("Ringsmall") +-_S("Cedillasmall") +-_S("questiondownsmall") +-_S("oneeighth") +-_S("threeeighths") +-_S("fiveeighths") +-_S("seveneighths") +-_S("onethird") +-_S("twothirds") +-_S("zerosuperior") +-_S("foursuperior") +-_S("fivesuperior") +-_S("sixsuperior") +-_S("sevensuperior") +-_S("eightsuperior") +-_S("ninesuperior") +-_S("zeroinferior") +-_S("oneinferior") +-_S("twoinferior") +-_S("threeinferior") +-_S("fourinferior") +-_S("fiveinferior") +-_S("sixinferior") +-_S("seveninferior") +-_S("eightinferior") +-_S("nineinferior") +-_S("centinferior") +-_S("dollarinferior") +-_S("periodinferior") +-_S("commainferior") +-_S("Agravesmall") +-_S("Aacutesmall") +-_S("Acircumflexsmall") +-_S("Atildesmall") +-_S("Adieresissmall") +-_S("Aringsmall") +-_S("AEsmall") +-_S("Ccedillasmall") +-_S("Egravesmall") +-_S("Eacutesmall") +-_S("Ecircumflexsmall") +-_S("Edieresissmall") +-_S("Igravesmall") +-_S("Iacutesmall") +-_S("Icircumflexsmall") +-_S("Idieresissmall") +-_S("Ethsmall") +-_S("Ntildesmall") +-_S("Ogravesmall") +-_S("Oacutesmall") +-_S("Ocircumflexsmall") +-_S("Otildesmall") +-_S("Odieresissmall") +-_S("OEsmall") +-_S("Oslashsmall") +-_S("Ugravesmall") +-_S("Uacutesmall") +-_S("Ucircumflexsmall") +-_S("Udieresissmall") +-_S("Yacutesmall") +-_S("Thornsmall") +-_S("Ydieresissmall") +-_S("001.000") +-_S("001.001") +-_S("001.002") +-_S("001.003") +-_S("Black") +-_S("Bold") +-_S("Book") +-_S("Light") +-_S("Medium") +-_S("Regular") +-_S("Roman") +-_S("Semibold") ++HB_STR(".notdef") ++HB_STR("space") ++HB_STR("exclam") ++HB_STR("quotedbl") ++HB_STR("numbersign") ++HB_STR("dollar") ++HB_STR("percent") ++HB_STR("ampersand") ++HB_STR("quoteright") ++HB_STR("parenleft") ++HB_STR("parenright") ++HB_STR("asterisk") ++HB_STR("plus") ++HB_STR("comma") ++HB_STR("hyphen") ++HB_STR("period") ++HB_STR("slash") ++HB_STR("zero") ++HB_STR("one") ++HB_STR("two") ++HB_STR("three") ++HB_STR("four") ++HB_STR("five") ++HB_STR("six") ++HB_STR("seven") ++HB_STR("eight") ++HB_STR("nine") ++HB_STR("colon") ++HB_STR("semicolon") ++HB_STR("less") ++HB_STR("equal") ++HB_STR("greater") ++HB_STR("question") ++HB_STR("at") ++HB_STR("A") ++HB_STR("B") ++HB_STR("C") ++HB_STR("D") ++HB_STR("E") ++HB_STR("F") ++HB_STR("G") ++HB_STR("H") ++HB_STR("I") ++HB_STR("J") ++HB_STR("K") ++HB_STR("L") ++HB_STR("M") ++HB_STR("N") ++HB_STR("O") ++HB_STR("P") ++HB_STR("Q") ++HB_STR("R") ++HB_STR("S") ++HB_STR("T") ++HB_STR("U") ++HB_STR("V") ++HB_STR("W") ++HB_STR("X") ++HB_STR("Y") ++HB_STR("Z") ++HB_STR("bracketleft") ++HB_STR("backslash") ++HB_STR("bracketright") ++HB_STR("asciicircum") ++HB_STR("underscore") ++HB_STR("quoteleft") ++HB_STR("a") ++HB_STR("b") ++HB_STR("c") ++HB_STR("d") ++HB_STR("e") ++HB_STR("f") ++HB_STR("g") ++HB_STR("h") ++HB_STR("i") ++HB_STR("j") ++HB_STR("k") ++HB_STR("l") ++HB_STR("m") ++HB_STR("n") ++HB_STR("o") ++HB_STR("p") ++HB_STR("q") ++HB_STR("r") ++HB_STR("s") ++HB_STR("t") ++HB_STR("u") ++HB_STR("v") ++HB_STR("w") ++HB_STR("x") ++HB_STR("y") ++HB_STR("z") ++HB_STR("braceleft") ++HB_STR("bar") ++HB_STR("braceright") ++HB_STR("asciitilde") ++HB_STR("exclamdown") ++HB_STR("cent") ++HB_STR("sterling") ++HB_STR("fraction") ++HB_STR("yen") ++HB_STR("florin") ++HB_STR("section") ++HB_STR("currency") ++HB_STR("quotesingle") ++HB_STR("quotedblleft") ++HB_STR("guillemotleft") ++HB_STR("guilsinglleft") ++HB_STR("guilsinglright") ++HB_STR("fi") ++HB_STR("fl") ++HB_STR("endash") ++HB_STR("dagger") ++HB_STR("daggerdbl") ++HB_STR("periodcentered") ++HB_STR("paragraph") ++HB_STR("bullet") ++HB_STR("quotesinglbase") ++HB_STR("quotedblbase") ++HB_STR("quotedblright") ++HB_STR("guillemotright") ++HB_STR("ellipsis") ++HB_STR("perthousand") ++HB_STR("questiondown") ++HB_STR("grave") ++HB_STR("acute") ++HB_STR("circumflex") ++HB_STR("tilde") ++HB_STR("macron") ++HB_STR("breve") ++HB_STR("dotaccent") ++HB_STR("dieresis") ++HB_STR("ring") ++HB_STR("cedilla") ++HB_STR("hungarumlaut") ++HB_STR("ogonek") ++HB_STR("caron") ++HB_STR("emdash") ++HB_STR("AE") ++HB_STR("ordfeminine") ++HB_STR("Lslash") ++HB_STR("Oslash") ++HB_STR("OE") ++HB_STR("ordmasculine") ++HB_STR("ae") ++HB_STR("dotlessi") ++HB_STR("lslash") ++HB_STR("oslash") ++HB_STR("oe") ++HB_STR("germandbls") ++HB_STR("onesuperior") ++HB_STR("logicalnot") ++HB_STR("mu") ++HB_STR("trademark") ++HB_STR("Eth") ++HB_STR("onehalf") ++HB_STR("plusminus") ++HB_STR("Thorn") ++HB_STR("onequarter") ++HB_STR("divide") ++HB_STR("brokenbar") ++HB_STR("degree") ++HB_STR("thorn") ++HB_STR("threequarters") ++HB_STR("twosuperior") ++HB_STR("registered") ++HB_STR("minus") ++HB_STR("eth") ++HB_STR("multiply") ++HB_STR("threesuperior") ++HB_STR("copyright") ++HB_STR("Aacute") ++HB_STR("Acircumflex") ++HB_STR("Adieresis") ++HB_STR("Agrave") ++HB_STR("Aring") ++HB_STR("Atilde") ++HB_STR("Ccedilla") ++HB_STR("Eacute") ++HB_STR("Ecircumflex") ++HB_STR("Edieresis") ++HB_STR("Egrave") ++HB_STR("Iacute") ++HB_STR("Icircumflex") ++HB_STR("Idieresis") ++HB_STR("Igrave") ++HB_STR("Ntilde") ++HB_STR("Oacute") ++HB_STR("Ocircumflex") ++HB_STR("Odieresis") ++HB_STR("Ograve") ++HB_STR("Otilde") ++HB_STR("Scaron") ++HB_STR("Uacute") ++HB_STR("Ucircumflex") ++HB_STR("Udieresis") ++HB_STR("Ugrave") ++HB_STR("Yacute") ++HB_STR("Ydieresis") ++HB_STR("Zcaron") ++HB_STR("aacute") ++HB_STR("acircumflex") ++HB_STR("adieresis") ++HB_STR("agrave") ++HB_STR("aring") ++HB_STR("atilde") ++HB_STR("ccedilla") ++HB_STR("eacute") ++HB_STR("ecircumflex") ++HB_STR("edieresis") ++HB_STR("egrave") ++HB_STR("iacute") ++HB_STR("icircumflex") ++HB_STR("idieresis") ++HB_STR("igrave") ++HB_STR("ntilde") ++HB_STR("oacute") ++HB_STR("ocircumflex") ++HB_STR("odieresis") ++HB_STR("ograve") ++HB_STR("otilde") ++HB_STR("scaron") ++HB_STR("uacute") ++HB_STR("ucircumflex") ++HB_STR("udieresis") ++HB_STR("ugrave") ++HB_STR("yacute") ++HB_STR("ydieresis") ++HB_STR("zcaron") ++HB_STR("exclamsmall") ++HB_STR("Hungarumlautsmall") ++HB_STR("dollaroldstyle") ++HB_STR("dollarsuperior") ++HB_STR("ampersandsmall") ++HB_STR("Acutesmall") ++HB_STR("parenleftsuperior") ++HB_STR("parenrightsuperior") ++HB_STR("twodotenleader") ++HB_STR("onedotenleader") ++HB_STR("zerooldstyle") ++HB_STR("oneoldstyle") ++HB_STR("twooldstyle") ++HB_STR("threeoldstyle") ++HB_STR("fouroldstyle") ++HB_STR("fiveoldstyle") ++HB_STR("sixoldstyle") ++HB_STR("sevenoldstyle") ++HB_STR("eightoldstyle") ++HB_STR("nineoldstyle") ++HB_STR("commasuperior") ++HB_STR("threequartersemdash") ++HB_STR("periodsuperior") ++HB_STR("questionsmall") ++HB_STR("asuperior") ++HB_STR("bsuperior") ++HB_STR("centsuperior") ++HB_STR("dsuperior") ++HB_STR("esuperior") ++HB_STR("isuperior") ++HB_STR("lsuperior") ++HB_STR("msuperior") ++HB_STR("nsuperior") ++HB_STR("osuperior") ++HB_STR("rsuperior") ++HB_STR("ssuperior") ++HB_STR("tsuperior") ++HB_STR("ff") ++HB_STR("ffi") ++HB_STR("ffl") ++HB_STR("parenleftinferior") ++HB_STR("parenrightinferior") ++HB_STR("Circumflexsmall") ++HB_STR("hyphensuperior") ++HB_STR("Gravesmall") ++HB_STR("Asmall") ++HB_STR("Bsmall") ++HB_STR("Csmall") ++HB_STR("Dsmall") ++HB_STR("Esmall") ++HB_STR("Fsmall") ++HB_STR("Gsmall") ++HB_STR("Hsmall") ++HB_STR("Ismall") ++HB_STR("Jsmall") ++HB_STR("Ksmall") ++HB_STR("Lsmall") ++HB_STR("Msmall") ++HB_STR("Nsmall") ++HB_STR("Osmall") ++HB_STR("Psmall") ++HB_STR("Qsmall") ++HB_STR("Rsmall") ++HB_STR("Ssmall") ++HB_STR("Tsmall") ++HB_STR("Usmall") ++HB_STR("Vsmall") ++HB_STR("Wsmall") ++HB_STR("Xsmall") ++HB_STR("Ysmall") ++HB_STR("Zsmall") ++HB_STR("colonmonetary") ++HB_STR("onefitted") ++HB_STR("rupiah") ++HB_STR("Tildesmall") ++HB_STR("exclamdownsmall") ++HB_STR("centoldstyle") ++HB_STR("Lslashsmall") ++HB_STR("Scaronsmall") ++HB_STR("Zcaronsmall") ++HB_STR("Dieresissmall") ++HB_STR("Brevesmall") ++HB_STR("Caronsmall") ++HB_STR("Dotaccentsmall") ++HB_STR("Macronsmall") ++HB_STR("figuredash") ++HB_STR("hypheninferior") ++HB_STR("Ogoneksmall") ++HB_STR("Ringsmall") ++HB_STR("Cedillasmall") ++HB_STR("questiondownsmall") ++HB_STR("oneeighth") ++HB_STR("threeeighths") ++HB_STR("fiveeighths") ++HB_STR("seveneighths") ++HB_STR("onethird") ++HB_STR("twothirds") ++HB_STR("zerosuperior") ++HB_STR("foursuperior") ++HB_STR("fivesuperior") ++HB_STR("sixsuperior") ++HB_STR("sevensuperior") ++HB_STR("eightsuperior") ++HB_STR("ninesuperior") ++HB_STR("zeroinferior") ++HB_STR("oneinferior") ++HB_STR("twoinferior") ++HB_STR("threeinferior") ++HB_STR("fourinferior") ++HB_STR("fiveinferior") ++HB_STR("sixinferior") ++HB_STR("seveninferior") ++HB_STR("eightinferior") ++HB_STR("nineinferior") ++HB_STR("centinferior") ++HB_STR("dollarinferior") ++HB_STR("periodinferior") ++HB_STR("commainferior") ++HB_STR("Agravesmall") ++HB_STR("Aacutesmall") ++HB_STR("Acircumflexsmall") ++HB_STR("Atildesmall") ++HB_STR("Adieresissmall") ++HB_STR("Aringsmall") ++HB_STR("AEsmall") ++HB_STR("Ccedillasmall") ++HB_STR("Egravesmall") ++HB_STR("Eacutesmall") ++HB_STR("Ecircumflexsmall") ++HB_STR("Edieresissmall") ++HB_STR("Igravesmall") ++HB_STR("Iacutesmall") ++HB_STR("Icircumflexsmall") ++HB_STR("Idieresissmall") ++HB_STR("Ethsmall") ++HB_STR("Ntildesmall") ++HB_STR("Ogravesmall") ++HB_STR("Oacutesmall") ++HB_STR("Ocircumflexsmall") ++HB_STR("Otildesmall") ++HB_STR("Odieresissmall") ++HB_STR("OEsmall") ++HB_STR("Oslashsmall") ++HB_STR("Ugravesmall") ++HB_STR("Uacutesmall") ++HB_STR("Ucircumflexsmall") ++HB_STR("Udieresissmall") ++HB_STR("Yacutesmall") ++HB_STR("Thornsmall") ++HB_STR("Ydieresissmall") ++HB_STR("001.000") ++HB_STR("001.001") ++HB_STR("001.002") ++HB_STR("001.003") ++HB_STR("Black") ++HB_STR("Bold") ++HB_STR("Book") ++HB_STR("Light") ++HB_STR("Medium") ++HB_STR("Regular") ++HB_STR("Roman") ++HB_STR("Semibold") + + #endif /* HB_OT_CFF1_STD_STR_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh +index 27c4d31b9ce..778167eeb23 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh +@@ -326,7 +326,7 @@ struct Charset0 + + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const + { +- mapping->resize (num_glyphs, false); ++ mapping->resize_dirty (num_glyphs); + for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++) + mapping->arrayZ[gid] = {sids[gid - 1], gid}; + } +@@ -426,7 +426,7 @@ struct Charset1_2 { + + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const + { +- mapping->resize (num_glyphs, false); ++ mapping->resize_dirty (num_glyphs); + hb_codepoint_t gid = 1; + if (gid >= num_glyphs) + return; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc +index b2702106ecc..499bd942cde 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc +@@ -202,7 +202,11 @@ struct cff2_cs_opset_path_t : cff2_cs_opset_tcoords, font->num_coords)); ++ return get_path_at (font, ++ glyph, ++ draw_session, ++ hb_array (font->coords, ++ font->has_nonzero_coords ? font->num_coords : 0)); + } + + bool OT::cff2::accelerator_t::get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh +index 6bf37c062fc..93e9c0a2697 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh +@@ -501,10 +501,6 @@ struct CmapSubtableFormat4 + this->length = c->length () - table_initpos; + if ((long long) this->length != (long long) c->length () - table_initpos) + { +- // Length overflowed. Discard the current object before setting the error condition, otherwise +- // discard is a noop which prevents the higher level code from reverting the serializer to the +- // pre-error state in cmap4 overflow handling code. +- c->pop_discard (); + c->err (HB_SERIALIZE_ERROR_INT_OVERFLOW); + return; + } +@@ -701,16 +697,7 @@ struct CmapSubtableFormat4 + hb_barrier (); + + if (unlikely (!c->check_range (this, length))) +- { +- /* Some broken fonts have too long of a "length" value. +- * If that is the case, just change the value to truncate +- * the subtable at the end of the blob. */ +- uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535, +- (uintptr_t) (c->end - +- (char *) this)); +- if (!c->try_set (&length, new_length)) +- return_trace (false); +- } ++ return_trace (false); + + return_trace (16 + 4 * (unsigned int) segCountX2 <= length); + } +@@ -1500,7 +1487,7 @@ struct CmapSubtable + bool get_glyph (hb_codepoint_t codepoint, + hb_codepoint_t *glyph) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return u.format0 .get_glyph (codepoint, glyph); + case 4: hb_barrier (); return u.format4 .get_glyph (codepoint, glyph); + case 6: hb_barrier (); return u.format6 .get_glyph (codepoint, glyph); +@@ -1513,7 +1500,7 @@ struct CmapSubtable + } + void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); u.format0 .collect_unicodes (out); return; + case 4: hb_barrier (); u.format4 .collect_unicodes (out); return; + case 6: hb_barrier (); u.format6 .collect_unicodes (out); return; +@@ -1529,7 +1516,7 @@ struct CmapSubtable + hb_map_t *mapping, /* OUT */ + unsigned num_glyphs = UINT_MAX) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); u.format0 .collect_mapping (unicodes, mapping); return; + case 4: hb_barrier (); u.format4 .collect_mapping (unicodes, mapping); return; + case 6: hb_barrier (); u.format6 .collect_mapping (unicodes, mapping); return; +@@ -1543,7 +1530,7 @@ struct CmapSubtable + + unsigned get_language () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return u.format0 .get_language (); + case 4: hb_barrier (); return u.format4 .get_language (); + case 6: hb_barrier (); return u.format6 .get_language (); +@@ -1574,9 +1561,9 @@ struct CmapSubtable + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return_trace (u.format0 .sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4 .sanitize (c)); + case 6: hb_barrier (); return_trace (u.format6 .sanitize (c)); +@@ -1590,7 +1577,7 @@ struct CmapSubtable + + public: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + CmapSubtableFormat0 format0; + CmapSubtableFormat4 format4; + CmapSubtableFormat6 format6; +@@ -1600,7 +1587,7 @@ struct CmapSubtable + CmapSubtableFormat14 format14; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + +@@ -1646,7 +1633,7 @@ struct EncodingRecord + CmapSubtable *cmapsubtable = c->push (); + unsigned origin_length = c->length (); + cmapsubtable->serialize (c, it, format, plan, &(base+subtable)); +- if (c->length () - origin_length > 0) *objidx = c->pop_pack (); ++ if (c->length () - origin_length > 0 && !c->in_error()) *objidx = c->pop_pack (); + else c->pop_discard (); + } + +@@ -1683,6 +1670,10 @@ struct SubtableUnicodesCache { + { + SubtableUnicodesCache* cache = + (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache)); ++ ++ if (unlikely (!cache)) ++ return nullptr; ++ + new (cache) SubtableUnicodesCache (source_table); + return cache; + } +@@ -1776,6 +1767,10 @@ struct cmap + ; + + SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table); ++ ++ if (unlikely (!cache)) ++ return nullptr; ++ + for (const EncodingRecord& _ : it) + cache->set_for(&_); // populate the cache for this encoding record. + +@@ -1810,7 +1805,7 @@ struct cmap + if (c->in_error ()) + return false; + +- unsigned format = (base+_.subtable).u.format; ++ unsigned format = (base+_.subtable).u.format.v; + if (format != 4 && format != 12 && format != 14) continue; + + const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache); +@@ -1912,7 +1907,7 @@ struct cmap + + hb_iter (encodingRecord) + | hb_map (&EncodingRecord::subtable) + | hb_map (hb_add (this)) +- | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == 14; }) ++ | hb_filter ([&] (const CmapSubtable& _) { return _.u.format.v == 14; }) + | hb_apply ([=] (const CmapSubtable& _) { _.u.format14.closure_glyphs (unicodes, glyphset); }) + ; + } +@@ -1937,7 +1932,7 @@ struct cmap + + for (const EncodingRecord& _ : encodingrec_iter) + { +- unsigned format = (this + _.subtable).u.format; ++ unsigned format = (this + _.subtable).u.format.v; + if (format == 12) has_format12 = true; + + const EncodingRecord *table = std::addressof (_); +@@ -2025,7 +2020,7 @@ struct cmap + this->subtable_uvs = &Null (CmapSubtableFormat14); + { + const CmapSubtable *st = table->find_subtable (0, 5); +- if (st && st->u.format == 14) ++ if (st && st->u.format.v == 14) + subtable_uvs = &st->u.format14; + } + +@@ -2069,7 +2064,7 @@ struct cmap + else + #endif + { +- switch (subtable->u.format) { ++ switch (subtable->u.format.v) { + /* Accelerate format 4 and format 12. */ + default: + this->get_glyph_funcZ = get_glyph_from; +@@ -2276,7 +2271,7 @@ struct cmap + (_.platformID == 0 && _.encodingID == 4) || + (_.platformID == 3 && _.encodingID == 1) || + (_.platformID == 3 && _.encodingID == 10) || +- (cmap + _.subtable).u.format == 14; ++ (cmap + _.subtable).u.format.v == 14; + } + + protected: +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc +index 0238bb346a9..8add9209f37 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc +@@ -37,6 +37,7 @@ + + #include "hb-ot-cmap-table.hh" + #include "hb-ot-glyf-table.hh" ++#include "hb-ot-var-gvar-table.hh" + #include "hb-ot-cff2-table.hh" + #include "hb-ot-cff1-table.hh" + #include "hb-ot-hmtx-table.hh" +@@ -64,18 +65,22 @@ + using hb_ot_font_advance_cache_t = hb_cache_t<24, 16>; + static_assert (sizeof (hb_ot_font_advance_cache_t) == 1024, ""); + ++using hb_ot_font_origin_cache_t = hb_cache_t<20, 20>; ++static_assert (sizeof (hb_ot_font_origin_cache_t) == 1024, ""); ++ + struct hb_ot_font_t + { + const hb_ot_face_t *ot_face; + +- /* h_advance caching */ ++ mutable hb_atomic_t cached_serial; + mutable hb_atomic_t cached_coords_serial; +- struct advance_cache_t ++ ++ struct direction_cache_t + { + mutable hb_atomic_t advance_cache; +- mutable hb_atomic_t varStore_cache; ++ mutable hb_atomic_t varStore_cache; + +- ~advance_cache_t () ++ ~direction_cache_t () + { + clear (); + } +@@ -116,7 +121,7 @@ struct hb_ot_font_t + goto retry; + } + +- OT::ItemVariationStore::cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const ++ OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + { + retry: + auto *cache = varStore_cache.get_acquire (); +@@ -127,7 +132,7 @@ struct hb_ot_font_t + else + goto retry; + } +- void release_varStore_cache (OT::ItemVariationStore::cache_t *cache) const ++ void release_varStore_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; +@@ -154,17 +159,157 @@ struct hb_ot_font_t + + } h, v; + ++ struct origin_cache_t ++ { ++ mutable hb_atomic_t origin_cache; ++ mutable hb_atomic_t varStore_cache; ++ ++ ~origin_cache_t () ++ { ++ clear (); ++ } ++ ++ hb_ot_font_origin_cache_t *acquire_origin_cache () const ++ { ++ retry: ++ auto *cache = origin_cache.get_acquire (); ++ if (!cache) ++ { ++ cache = (hb_ot_font_origin_cache_t *) hb_malloc (sizeof (hb_ot_font_origin_cache_t)); ++ if (!cache) ++ return nullptr; ++ new (cache) hb_ot_font_origin_cache_t; ++ return cache; ++ } ++ if (origin_cache.cmpexch (cache, nullptr)) ++ return cache; ++ else ++ goto retry; ++ } ++ void release_origin_cache (hb_ot_font_origin_cache_t *cache) const ++ { ++ if (!cache) ++ return; ++ if (!origin_cache.cmpexch (nullptr, cache)) ++ hb_free (cache); ++ } ++ void clear_origin_cache () const ++ { ++ retry: ++ auto *cache = origin_cache.get_acquire (); ++ if (!cache) ++ return; ++ if (origin_cache.cmpexch (cache, nullptr)) ++ hb_free (cache); ++ else ++ goto retry; ++ } ++ ++ OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const ++ { ++ retry: ++ auto *cache = varStore_cache.get_acquire (); ++ if (!cache) ++ return varStore.create_cache (); ++ if (varStore_cache.cmpexch (cache, nullptr)) ++ return cache; ++ else ++ goto retry; ++ } ++ void release_varStore_cache (OT::hb_scalar_cache_t *cache) const ++ { ++ if (!cache) ++ return; ++ if (!varStore_cache.cmpexch (nullptr, cache)) ++ OT::ItemVariationStore::destroy_cache (cache); ++ } ++ void clear_varStore_cache () const ++ { ++ retry: ++ auto *cache = varStore_cache.get_acquire (); ++ if (!cache) ++ return; ++ if (varStore_cache.cmpexch (cache, nullptr)) ++ OT::ItemVariationStore::destroy_cache (cache); ++ else ++ goto retry; ++ } ++ ++ void clear () const ++ { ++ clear_origin_cache (); ++ clear_varStore_cache (); ++ } ++ } v_origin; ++ ++ struct draw_cache_t ++ { ++ mutable hb_atomic_t gvar_cache; ++ ++ ~draw_cache_t () ++ { ++ clear (); ++ } ++ ++ OT::hb_scalar_cache_t *acquire_gvar_cache (const OT::gvar_accelerator_t &gvar) const ++ { ++ retry: ++ auto *cache = gvar_cache.get_acquire (); ++ if (!cache) ++ return gvar.create_cache (); ++ if (gvar_cache.cmpexch (cache, nullptr)) ++ return cache; ++ else ++ goto retry; ++ } ++ void release_gvar_cache (OT::hb_scalar_cache_t *cache) const ++ { ++ if (!cache) ++ return; ++ if (!gvar_cache.cmpexch (nullptr, cache)) ++ OT::gvar_accelerator_t::destroy_cache (cache); ++ } ++ void clear_gvar_cache () const ++ { ++ retry: ++ auto *cache = gvar_cache.get_acquire (); ++ if (!cache) ++ return; ++ if (gvar_cache.cmpexch (cache, nullptr)) ++ OT::gvar_accelerator_t::destroy_cache (cache); ++ else ++ goto retry; ++ } ++ ++ void clear () const ++ { ++ clear_gvar_cache (); ++ } ++ } draw; ++ + void check_serial (hb_font_t *font) const + { + int font_serial = font->serial_coords.get_acquire (); ++ if (cached_serial.get_acquire () != font_serial) ++ { ++ /* These caches are dependent on scale and synthetic settings. ++ * Any change to the font invalidates them. */ ++ v_origin.clear (); + +- if (cached_coords_serial.get_acquire () == font_serial) +- return; ++ cached_serial.set_release (font_serial); ++ } + +- h.clear (); +- v.clear (); ++ int font_serial_coords = font->serial_coords.get_acquire (); ++ if (cached_coords_serial.get_acquire () != font_serial_coords) ++ { ++ /* These caches are independent of scale or synthetic settings. ++ * Just variation changes will invalidate them. */ ++ h.clear (); ++ v.clear (); ++ draw.clear (); + +- cached_coords_serial.set_release (font_serial); ++ cached_coords_serial.set_release (font_serial_coords); ++ } + } + }; + +@@ -242,37 +387,92 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, + unsigned advance_stride, + void *user_data HB_UNUSED) + { ++ // Duplicated in v_advances. Ugly. Keep in sync'ish. + + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + const hb_ot_face_t *ot_face = ot_font->ot_face; + const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; + +- ot_font->check_serial (font); +- const OT::HVAR &HVAR = *hmtx.var_table; +- const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; +- OT::ItemVariationStore::cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); ++ if (unlikely (!hmtx.has_data ())) ++ { ++ hb_position_t advance = font->face->get_upem () / 2; ++ advance = font->em_scale_x (advance); ++ for (unsigned int i = 0; i < count; i++) ++ { ++ *first_advance = advance; ++ first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); ++ } ++ return; ++ } + +- hb_ot_font_advance_cache_t *advance_cache = nullptr; ++#ifndef HB_NO_VAR ++ if (!font->has_nonzero_coords) ++ { ++ fallback: ++#else ++ { ++#endif ++ // Just plain htmx data. No need to cache. ++ for (unsigned int i = 0; i < count; i++) ++ { ++ *first_advance = font->em_scale_x (hmtx.get_advance_without_var_unscaled (*first_glyph)); ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); ++ } ++ return; ++ } + +- bool use_cache = font->num_coords; +- if (use_cache) ++#ifndef HB_NO_VAR ++ /* has_nonzero_coords. */ ++ ++ ot_font->check_serial (font); ++ hb_ot_font_advance_cache_t *advance_cache = ot_font->h.acquire_advance_cache (); ++ if (!advance_cache) + { +- advance_cache = ot_font->h.acquire_advance_cache (); +- if (!advance_cache) +- use_cache = false; ++ // malloc failure. Just use the fallback non-variable path. ++ goto fallback; + } + +- if (!use_cache) ++ /* If HVAR is present, use it.*/ ++ const OT::HVAR &HVAR = *hmtx.var_table; ++ if (HVAR.has_data ()) + { ++ const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; ++ OT::hb_scalar_cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); ++ + for (unsigned int i = 0; i < count; i++) + { +- *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); ++ hb_position_t v; ++ unsigned cv; ++ if (advance_cache->get (*first_glyph, &cv)) ++ v = cv; ++ else ++ { ++ v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); ++ advance_cache->set (*first_glyph, v); ++ } ++ *first_advance = font->em_scale_x (v); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } ++ ++ ot_font->h.release_varStore_cache (varStore_cache); ++ ot_font->h.release_advance_cache (advance_cache); ++ return; + } +- else +- { /* Use cache. */ ++ ++ const auto &gvar = *ot_face->gvar; ++ if (gvar.has_data ()) ++ { ++ const auto &glyf = *ot_face->glyf; ++ auto *scratch = glyf.acquire_scratch (); ++ if (unlikely (!scratch)) ++ { ++ ot_font->h.release_advance_cache (advance_cache); ++ goto fallback; ++ } ++ OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); ++ + for (unsigned int i = 0; i < count; i++) + { + hb_position_t v; +@@ -281,7 +481,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, + v = cv; + else + { +- v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); ++ v = glyf.get_advance_with_var_unscaled (*first_glyph, font, false, *scratch, gvar_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_x (v); +@@ -289,10 +489,16 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + ++ ot_font->draw.release_gvar_cache (gvar_cache); ++ glyf.release_scratch (scratch); + ot_font->h.release_advance_cache (advance_cache); ++ return; + } + +- ot_font->h.release_varStore_cache (varStore_cache); ++ ot_font->h.release_advance_cache (advance_cache); ++ // No HVAR or GVAR. Just use the fallback non-variable path. ++ goto fallback; ++#endif + } + + #ifndef HB_NO_VERTICAL +@@ -305,99 +511,290 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, + unsigned advance_stride, + void *user_data HB_UNUSED) + { ++ // Duplicated from h_advances. Ugly. Keep in sync'ish. ++ + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + const hb_ot_face_t *ot_face = ot_font->ot_face; + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; + +- if (vmtx.has_data ()) ++ if (unlikely (!vmtx.has_data ())) ++ { ++ hb_font_extents_t font_extents; ++ font->get_h_extents_with_fallback (&font_extents); ++ hb_position_t advance = font_extents.descender - font_extents.ascender; ++ for (unsigned int i = 0; i < count; i++) ++ { ++ *first_advance = advance; ++ first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); ++ } ++ return; ++ } ++ ++#ifndef HB_NO_VAR ++ if (!font->has_nonzero_coords) ++ { ++ fallback: ++#else ++ { ++#endif ++ // Just plain vtmx data. No need to cache. ++ for (unsigned int i = 0; i < count; i++) ++ { ++ *first_advance = font->em_scale_y (- (int) vmtx.get_advance_without_var_unscaled (*first_glyph)); ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); ++ } ++ return; ++ } ++ ++#ifndef HB_NO_VAR ++ /* has_nonzero_coords. */ ++ ++ ot_font->check_serial (font); ++ hb_ot_font_advance_cache_t *advance_cache = ot_font->v.acquire_advance_cache (); ++ if (!advance_cache) ++ { ++ // malloc failure. Just use the fallback non-variable path. ++ goto fallback; ++ } ++ ++ /* If VVAR is present, use it.*/ ++ const OT::VVAR &VVAR = *vmtx.var_table; ++ if (VVAR.has_data ()) + { +- ot_font->check_serial (font); +- const OT::VVAR &VVAR = *vmtx.var_table; + const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; +- OT::ItemVariationStore::cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); +- // TODO Use advance_cache. ++ OT::hb_scalar_cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); + + for (unsigned int i = 0; i < count; i++) + { +- *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); ++ hb_position_t v; ++ unsigned cv; ++ if (advance_cache->get (*first_glyph, &cv)) ++ v = cv; ++ else ++ { ++ v = vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); ++ advance_cache->set (*first_glyph, v); ++ } ++ *first_advance = font->em_scale_y (- (int) v); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + + ot_font->v.release_varStore_cache (varStore_cache); ++ ot_font->v.release_advance_cache (advance_cache); ++ return; + } +- else ++ ++ const auto &gvar = *ot_face->gvar; ++ if (gvar.has_data ()) + { +- hb_font_extents_t font_extents; +- font->get_h_extents_with_fallback (&font_extents); +- hb_position_t advance = -(font_extents.ascender - font_extents.descender); ++ const auto &glyf = *ot_face->glyf; ++ auto *scratch = glyf.acquire_scratch (); ++ if (unlikely (!scratch)) ++ { ++ ot_font->v.release_advance_cache (advance_cache); ++ goto fallback; ++ } ++ OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); + + for (unsigned int i = 0; i < count; i++) + { +- *first_advance = advance; ++ hb_position_t v; ++ unsigned cv; ++ if (advance_cache->get (*first_glyph, &cv)) ++ v = cv; ++ else ++ { ++ v = glyf.get_advance_with_var_unscaled (*first_glyph, font, true, *scratch, gvar_cache); ++ advance_cache->set (*first_glyph, v); ++ } ++ *first_advance = font->em_scale_y (- (int) v); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } ++ ++ ot_font->draw.release_gvar_cache (gvar_cache); ++ glyf.release_scratch (scratch); ++ ot_font->v.release_advance_cache (advance_cache); ++ return; + } ++ ++ ot_font->v.release_advance_cache (advance_cache); ++ // No VVAR or GVAR. Just use the fallback non-variable path. ++ goto fallback; ++#endif + } + #endif + + #ifndef HB_NO_VERTICAL ++HB_HOT + static hb_bool_t +-hb_ot_get_glyph_v_origin (hb_font_t *font, +- void *font_data, +- hb_codepoint_t glyph, +- hb_position_t *x, +- hb_position_t *y, +- void *user_data HB_UNUSED) ++hb_ot_get_glyph_v_origins (hb_font_t *font, ++ void *font_data, ++ unsigned int count, ++ const hb_codepoint_t *first_glyph, ++ unsigned glyph_stride, ++ hb_position_t *first_x, ++ unsigned x_stride, ++ hb_position_t *first_y, ++ unsigned y_stride, ++ void *user_data HB_UNUSED) + { + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + const hb_ot_face_t *ot_face = ot_font->ot_face; + +- *x = font->get_glyph_h_advance (glyph) / 2; ++ /* First, set all the x values to half the advance width. */ ++ font->get_glyph_h_advances (count, ++ first_glyph, glyph_stride, ++ first_x, x_stride); ++ for (unsigned i = 0; i < count; i++) ++ { ++ *first_x /= 2; ++ first_x = &StructAtOffsetUnaligned (first_x, x_stride); ++ } ++ ++ /* The vertical origin business is messy... ++ * ++ * We allocate the cache, then have various code paths that use the cache. ++ * Each one is responsible to free it before returning. ++ */ ++ hb_ot_font_origin_cache_t *origin_cache = ot_font->v_origin.acquire_origin_cache (); + ++ /* If there is VORG, always use it. It uses VVAR for variations if necessary. */ + const OT::VORG &VORG = *ot_face->VORG; +- if (VORG.has_data ()) ++ if (origin_cache && VORG.has_data ()) + { +- float delta = 0; +- + #ifndef HB_NO_VAR +- const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; +- const OT::VVAR &VVAR = *vmtx.var_table; +- if (font->num_coords) +- VVAR.get_vorg_delta_unscaled (glyph, +- font->coords, font->num_coords, +- &delta); ++ if (!font->has_nonzero_coords) + #endif +- +- *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); ++ { ++ for (unsigned i = 0; i < count; i++) ++ { ++ hb_position_t origin; ++ unsigned cv; ++ if (origin_cache->get (*first_glyph, &cv)) ++ origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); ++ else ++ { ++ origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph)); ++ origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); ++ } ++ ++ *first_y = origin; ++ ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ } ++#ifndef HB_NO_VAR ++ else ++ { ++ const OT::VVAR &VVAR = *ot_face->vmtx->var_table; ++ const auto &varStore = &VVAR + VVAR.varStore; ++ auto *varStore_cache = ot_font->v_origin.acquire_varStore_cache (varStore); ++ for (unsigned i = 0; i < count; i++) ++ { ++ hb_position_t origin; ++ unsigned cv; ++ if (origin_cache->get (*first_glyph, &cv)) ++ origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); ++ else ++ { ++ origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph) + ++ VVAR.get_vorg_delta_unscaled (*first_glyph, ++ font->coords, font->num_coords, ++ varStore_cache)); ++ origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); ++ } ++ ++ *first_y = origin; ++ ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ ot_font->v_origin.release_varStore_cache (varStore_cache); ++ } ++#endif ++ ot_font->v_origin.release_origin_cache (origin_cache); + return true; + } + +- hb_glyph_extents_t extents = {0}; +- +- if (hb_font_get_glyph_extents (font, glyph, &extents)) ++ /* If and only if `vmtx` is present and it's a `glyf` font, ++ * we use the top phantom point, deduced from vmtx,glyf[,gvar]. */ ++ const auto &vmtx = *ot_face->vmtx; ++ const auto &glyf = *ot_face->glyf; ++ if (origin_cache && vmtx.has_data() && glyf.has_data ()) + { +- const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; +- int tsb = 0; +- if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) ++ auto *scratch = glyf.acquire_scratch (); ++ if (unlikely (!scratch)) + { +- *y = extents.y_bearing + font->em_scale_y (tsb); +- return true; ++ ot_font->v_origin.release_origin_cache (origin_cache); ++ return false; + } ++ OT::hb_scalar_cache_t *gvar_cache = font->has_nonzero_coords ? ++ ot_font->draw.acquire_gvar_cache (*ot_face->gvar) : ++ nullptr; + +- hb_font_extents_t font_extents; +- font->get_h_extents_with_fallback (&font_extents); +- hb_position_t advance = font_extents.ascender - font_extents.descender; +- hb_position_t diff = advance - -extents.height; +- *y = extents.y_bearing + (diff >> 1); ++ for (unsigned i = 0; i < count; i++) ++ { ++ hb_position_t origin; ++ unsigned cv; ++ if (origin_cache->get (*first_glyph, &cv)) ++ origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); ++ else ++ { ++ origin = font->em_scalef_y (glyf.get_v_origin_with_var_unscaled (*first_glyph, font, *scratch, gvar_cache)); ++ origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); ++ } ++ ++ *first_y = origin; ++ ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ ++ if (gvar_cache) ++ ot_font->draw.release_gvar_cache (gvar_cache); ++ glyf.release_scratch (scratch); ++ ot_font->v_origin.release_origin_cache (origin_cache); + return true; + } + +- hb_font_extents_t font_extents; +- font->get_h_extents_with_fallback (&font_extents); +- *y = font_extents.ascender; ++ /* Otherwise, use glyph extents to center the glyph vertically. ++ * If getting glyph extents failed, just use the font ascender. */ ++ if (origin_cache && font->has_glyph_extents_func ()) ++ { ++ hb_font_extents_t font_extents; ++ font->get_h_extents_with_fallback (&font_extents); ++ hb_position_t font_advance = font_extents.ascender - font_extents.descender; ++ ++ for (unsigned i = 0; i < count; i++) ++ { ++ hb_position_t origin; ++ unsigned cv; ++ ++ if (origin_cache->get (*first_glyph, &cv)) ++ origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); ++ else ++ { ++ hb_glyph_extents_t extents = {0}; ++ if (likely (font->get_glyph_extents (*first_glyph, &extents))) ++ origin = extents.y_bearing + ((font_advance - -extents.height) >> 1); ++ else ++ origin = font_extents.ascender; ++ ++ origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); ++ } + ++ *first_y = origin; ++ ++ first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); ++ first_y = &StructAtOffsetUnaligned (first_y, y_stride); ++ } ++ } ++ ++ ot_font->v_origin.release_origin_cache (origin_cache); + return true; + } + #endif +@@ -498,17 +895,33 @@ hb_ot_draw_glyph_or_fail (hb_font_t *font, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) + { ++ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + hb_draw_session_t draw_session {draw_funcs, draw_data}; ++ bool ret = false; ++ ++ OT::hb_scalar_cache_t *gvar_cache = nullptr; ++ if (font->num_coords) ++ { ++ ot_font->check_serial (font); ++ gvar_cache = ot_font->draw.acquire_gvar_cache (*ot_font->ot_face->gvar); ++ } ++ + #ifndef HB_NO_VAR_COMPOSITES +- if (font->face->table.VARC->get_path (font, glyph, draw_session)) return true; ++ if (font->face->table.VARC->get_path (font, glyph, draw_session)) { ret = true; goto done; } + #endif + // Keep the following in synch with VARC::get_path_at() +- if (font->face->table.glyf->get_path (font, glyph, draw_session)) return true; ++ if (font->face->table.glyf->get_path (font, glyph, draw_session, gvar_cache)) { ret = true; goto done; } ++ + #ifndef HB_NO_CFF +- if (font->face->table.cff2->get_path (font, glyph, draw_session)) return true; +- if (font->face->table.cff1->get_path (font, glyph, draw_session)) return true; ++ if (font->face->table.cff2->get_path (font, glyph, draw_session)) { ret = true; goto done; } ++ if (font->face->table.cff1->get_path (font, glyph, draw_session)) { ret = true; goto done; } + #endif +- return false; ++ ++done: ++ ++ ot_font->draw.release_gvar_cache (gvar_cache); ++ ++ return ret; + } + #endif + +@@ -548,12 +961,11 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_tplan->new_to_old_gid_list) +- | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _) ++ | hb_map ([&_mtx, mtx_map] (hb_codepoint_pair_t _) + { + hb_codepoint_t new_gid = _.first; + hb_codepoint_t old_gid = _.second; +@@ -246,8 +236,7 @@ struct hmtxvmtx + if (!mtx_map->has (new_gid, &v)) + { + int lsb = 0; +- if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) +- (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb); ++ _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); + return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); + } + return *v; +@@ -326,49 +315,23 @@ struct hmtxvmtx + + bool has_data () const { return (bool) num_bearings; } + +- bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, ++ void get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + int *lsb) const + { + if (glyph < num_long_metrics) + { + *lsb = table->longMetricZ[glyph].sb; +- return true; ++ return; + } + + if (unlikely (glyph >= num_bearings)) +- return false; +- +- const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; +- *lsb = bearings[glyph - num_long_metrics]; +- return true; +- } +- +- bool get_leading_bearing_with_var_unscaled (hb_font_t *font, +- hb_codepoint_t glyph, +- int *lsb) const +- { +- if (!font->num_coords) +- return get_leading_bearing_without_var_unscaled (glyph, lsb); +- +-#ifndef HB_NO_VAR +- float delta; +- if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) && +- get_leading_bearing_without_var_unscaled (glyph, lsb)) + { +- *lsb += roundf (delta); +- return true; ++ *lsb = 0; ++ return; + } + +- // If there's no vmtx data, the phantom points from glyf table are not accurate, +- // so we cannot take the next path. +- bool is_vertical = T::tableTag == HB_OT_TAG_vmtx; +- if (is_vertical && !has_data ()) +- return false; +- +- return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); +-#else +- return false; +-#endif ++ const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; ++ *lsb = bearings[glyph - num_long_metrics]; + } + + unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const +@@ -402,27 +365,17 @@ struct hmtxvmtx + return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; + } + +- unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, +- hb_font_t *font, +- ItemVariationStore::cache_t *store_cache = nullptr) const ++#ifndef HB_NO_VAR ++ unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, ++ hb_font_t *font, ++ hb_scalar_cache_t *store_cache = nullptr) const + { + unsigned int advance = get_advance_without_var_unscaled (glyph); +- +-#ifndef HB_NO_VAR +- if (unlikely (glyph >= num_bearings) || !font->num_coords) +- return advance; +- +- if (var_table.get_length ()) +- return advance + roundf (var_table->get_advance_delta_unscaled (glyph, +- font->coords, font->num_coords, +- store_cache)); +- +- unsigned glyf_advance = _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); +- return glyf_advance ? glyf_advance : advance; +-#else +- return advance; +-#endif ++ return hb_max(0.0f, advance + roundf (var_table->get_advance_delta_unscaled (glyph, ++ font->coords, font->num_coords, ++ store_cache))); + } ++#endif + + protected: + // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh +index 97d012e58b8..42326adcad2 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh +@@ -90,11 +90,11 @@ struct KernSubTableFormat3 + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { +- set_t set; + if (likely (glyphCount)) +- set.add_range (0, glyphCount - 1); +- left_set.union_ (set); +- right_set.union_ (set); ++ { ++ left_set.add_range (0, num_glyphs - 1); ++ right_set.add_range (0, num_glyphs - 1); ++ } + } + + protected: +@@ -306,8 +306,8 @@ struct kern + { + static constexpr hb_tag_t tableTag = HB_OT_TAG_kern; + +- bool has_data () const { return u.version32; } +- unsigned get_type () const { return u.major; } ++ bool has_data () const { return u.version32.v; } ++ unsigned get_type () const { return u.major.v; } + + bool has_state_machine () const + { +@@ -363,7 +363,7 @@ struct kern + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.version32.sanitize (c)) return_trace (false); ++ if (!u.version32.v.sanitize (c)) return_trace (false); + hb_barrier (); + return_trace (dispatch (c)); + } +@@ -406,15 +406,15 @@ struct kern + + protected: + union { +- HBUINT32 version32; +- HBUINT16 major; ++ struct { HBUINT32 v; } version32; ++ struct { HBUINT16 v; } major; + KernOT ot; + #ifndef HB_NO_AAT_SHAPE + KernAAT aat; + #endif + } u; + public: +- DEFINE_SIZE_UNION (4, version32); ++ DEFINE_SIZE_UNION (4, version32.v); + }; + + struct kern_accelerator_t : kern::accelerator_t { +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh +index 04a79a93a89..b9baaca2a23 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh +@@ -165,13 +165,13 @@ struct BaseCoordFormat3 + + struct BaseCoord + { +- bool has_data () const { return u.format; } ++ bool has_data () const { return u.format.v; } + + hb_position_t get_coord (hb_font_t *font, + const ItemVariationStore &var_store, + hb_direction_t direction) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.get_coord (font, direction); + case 2: hb_barrier (); return u.format2.get_coord (font, direction); + case 3: hb_barrier (); return u.format3.get_coord (font, var_store, direction); +@@ -181,7 +181,7 @@ struct BaseCoord + + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); return; + default:return; + } +@@ -190,9 +190,9 @@ struct BaseCoord + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); +@@ -203,9 +203,9 @@ struct BaseCoord + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (unlikely (!u.format.sanitize (c))) return_trace (false); ++ if (unlikely (!u.format.v.sanitize (c))) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); +@@ -215,13 +215,13 @@ struct BaseCoord + + protected: + union { +- HBUINT16 format; ++ struct { HBUINT16 v; } format; + BaseCoordFormat1 format1; + BaseCoordFormat2 format2; + BaseCoordFormat3 format3; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + struct FeatMinMaxRecord +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh +index 7ee34185575..dcacc9cb86c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh +@@ -141,6 +141,7 @@ struct hb_subset_layout_context_t : + const hb_map_t *lookup_index_map; + const hb_hashmap_t> *script_langsys_map; + const hb_map_t *feature_index_map; ++ const hb_map_t *feature_map_w_duplicates; + const hb_hashmap_t *feature_substitutes_map; + hb_hashmap_t> *feature_record_cond_idx_map; + const hb_set_t *catch_all_record_feature_idxes; +@@ -165,6 +166,7 @@ struct hb_subset_layout_context_t : + lookup_index_map = &c_->plan->gsub_lookups; + script_langsys_map = &c_->plan->gsub_langsys; + feature_index_map = &c_->plan->gsub_features; ++ feature_map_w_duplicates = &c_->plan->gsub_features_w_duplicates; + feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; + feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gsub_old_features; +@@ -175,6 +177,7 @@ struct hb_subset_layout_context_t : + lookup_index_map = &c_->plan->gpos_lookups; + script_langsys_map = &c_->plan->gpos_langsys; + feature_index_map = &c_->plan->gpos_features; ++ feature_map_w_duplicates = &c_->plan->gpos_features_w_duplicates; + feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; + feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gpos_old_features; +@@ -825,46 +828,9 @@ struct Feature + const Record_sanitize_closure_t *closure = nullptr) const + { + TRACE_SANITIZE (this); +- if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) +- return_trace (false); +- hb_barrier (); +- +- /* Some earlier versions of Adobe tools calculated the offset of the +- * FeatureParams subtable from the beginning of the FeatureList table! +- * +- * If sanitizing "failed" for the FeatureParams subtable, try it with the +- * alternative location. We would know sanitize "failed" if old value +- * of the offset was non-zero, but it's zeroed now. +- * +- * Only do this for the 'size' feature, since at the time of the faulty +- * Adobe tools, only the 'size' feature had FeatureParams defined. +- */ +- +- if (likely (featureParams.is_null ())) +- return_trace (true); +- +- unsigned int orig_offset = featureParams; +- if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) +- return_trace (false); +- hb_barrier (); +- +- if (featureParams == 0 && closure && +- closure->tag == HB_TAG ('s','i','z','e') && +- closure->list_base && closure->list_base < this) +- { +- unsigned int new_offset_int = orig_offset - +- (((char *) this) - ((char *) closure->list_base)); +- +- Offset16To new_offset; +- /* Check that it would not overflow. */ +- new_offset = new_offset_int; +- if (new_offset == new_offset_int && +- c->try_set (&featureParams, new_offset_int) && +- !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) +- return_trace (false); +- } +- +- return_trace (true); ++ return_trace (c->check_struct (this) && ++ featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE) && ++ lookupIndex.sanitize (c)); + } + + Offset16To +@@ -1082,15 +1048,15 @@ struct LangSys + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + const uint32_t *v; +- out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; ++ out->reqFeatureIndex = l->feature_map_w_duplicates->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; + + if (!l->visitFeatureIndex (featureIndex.len)) + return_trace (false); + + auto it = + + hb_iter (featureIndex) +- | hb_filter (l->feature_index_map) +- | hb_map (l->feature_index_map) ++ | hb_filter (l->feature_map_w_duplicates) ++ | hb_map (l->feature_map_w_duplicates) + ; + + bool ret = bool (it); +@@ -1337,7 +1303,7 @@ struct Lookup + TRACE_DISPATCH (this, lookup_type); + unsigned int count = get_subtable_count (); + for (unsigned int i = 0; i < count; i++) { +- typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, std::forward (ds)...); ++ typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, ds...); + if (c->stop_sublookup_iteration (r)) + return_trace (r); + } +@@ -1387,6 +1353,11 @@ struct Lookup + { + unsigned new_flag = lookupFlag; + new_flag &= ~LookupFlag::UseMarkFilteringSet; ++ // https://github.com/harfbuzz/harfbuzz/issues/5499 ++ // If we remove UseMarkFilteringSet flag because the set is now empty, ++ // we need to add IgnoreMarks flag, otherwise the lookup will not ++ // ignore any marks, which changes the behavior. ++ new_flag |= LookupFlag::IgnoreMarks; + out->lookupFlag = new_flag; + } + else +@@ -1425,7 +1396,7 @@ struct Lookup + if (unlikely (!get_subtables ().sanitize (c, this, get_type ()))) + return_trace (false); + +- if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) ++ if (unlikely (get_type () == TSubTable::Extension)) + { + hb_barrier (); + +@@ -1433,11 +1404,6 @@ struct Lookup + * have the same type, which shall not be the Extension type + * itself (but we already checked for that). + * This is specially important if one has a reverse type! +- * +- * We only do this if sanitizer edit_count is zero. Otherwise, +- * some of the subtables might have become insane after they +- * were sanity-checked by the edits of subsequent subtables. +- * https://bugs.chromium.org/p/chromium/issues/detail?id=960331 + */ + unsigned int type = get_subtable (0).u.extension.get_type (); + for (unsigned int i = 1; i < subtables; i++) +@@ -2067,7 +2033,7 @@ struct ClassDef + unsigned int get (hb_codepoint_t k) const { return get_class (k); } + unsigned int get_class (hb_codepoint_t glyph_id) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.get_class (glyph_id); + case 2: hb_barrier (); return u.format2.get_class (glyph_id); + #ifndef HB_NO_BEYOND_64K +@@ -2078,7 +2044,7 @@ struct ClassDef + } + } + unsigned int get_class (hb_codepoint_t glyph_id, +- hb_ot_lookup_cache_t *cache) const ++ hb_ot_layout_mapping_cache_t *cache) const + { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; +@@ -2089,7 +2055,7 @@ struct ClassDef + + unsigned get_population () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.get_population (); + case 2: hb_barrier (); return u.format2.get_population (); + #ifndef HB_NO_BEYOND_64K +@@ -2142,7 +2108,7 @@ struct ClassDef + + #ifndef HB_NO_BEYOND_64K + if (glyph_max > 0xFFFFu) +- u.format += 2; ++ u.format.v += 2; + if (unlikely (glyph_max > 0xFFFFFFu)) + #else + if (unlikely (glyph_max > 0xFFFFu)) +@@ -2152,9 +2118,9 @@ struct ClassDef + return_trace (false); + } + +- u.format = format; ++ u.format.v = format; + +- switch (u.format) ++ switch (u.format.v) + { + case 1: hb_barrier (); return_trace (u.format1.serialize (c, it)); + case 2: hb_barrier (); return_trace (u.format2.serialize (c, it)); +@@ -2173,7 +2139,7 @@ struct ClassDef + const Coverage* glyph_filter = nullptr) const + { + TRACE_SUBSET (this); +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 2: hb_barrier (); return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + #ifndef HB_NO_BEYOND_64K +@@ -2187,9 +2153,9 @@ struct ClassDef + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + #ifndef HB_NO_BEYOND_64K +@@ -2202,7 +2168,7 @@ struct ClassDef + + unsigned cost () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); + #ifndef HB_NO_BEYOND_64K +@@ -2218,7 +2184,7 @@ struct ClassDef + template + bool collect_coverage (set_t *glyphs) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.collect_coverage (glyphs); + case 2: hb_barrier (); return u.format2.collect_coverage (glyphs); + #ifndef HB_NO_BEYOND_64K +@@ -2234,7 +2200,7 @@ struct ClassDef + template + bool collect_class (set_t *glyphs, unsigned int klass) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.collect_class (glyphs, klass); + case 2: hb_barrier (); return u.format2.collect_class (glyphs, klass); + #ifndef HB_NO_BEYOND_64K +@@ -2247,7 +2213,7 @@ struct ClassDef + + bool intersects (const hb_set_t *glyphs) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.intersects (glyphs); + case 2: hb_barrier (); return u.format2.intersects (glyphs); + #ifndef HB_NO_BEYOND_64K +@@ -2259,7 +2225,7 @@ struct ClassDef + } + bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.intersects_class (glyphs, klass); + case 2: hb_barrier (); return u.format2.intersects_class (glyphs, klass); + #ifndef HB_NO_BEYOND_64K +@@ -2272,7 +2238,7 @@ struct ClassDef + + void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 2: hb_barrier (); return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + #ifndef HB_NO_BEYOND_64K +@@ -2285,7 +2251,7 @@ struct ClassDef + + void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.intersected_classes (glyphs, intersect_classes); + case 2: hb_barrier (); return u.format2.intersected_classes (glyphs, intersect_classes); + #ifndef HB_NO_BEYOND_64K +@@ -2299,7 +2265,7 @@ struct ClassDef + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + ClassDefFormat1_3 format1; + ClassDefFormat2_4 format2; + #ifndef HB_NO_BEYOND_64K +@@ -2308,7 +2274,7 @@ struct ClassDef + #endif + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + template +@@ -2326,139 +2292,168 @@ struct delta_row_encoding_t + { + /* each byte represents a region, value is one of 0/1/2/4, which means bytes + * needed for this region */ +- hb_vector_t chars; ++ struct chars_t : hb_vector_t ++ { ++ int cmp (const chars_t& other) const ++ { ++ return as_array ().cmp (other.as_array ()); ++ } ++ ++ hb_pair_t get_width () ++ { ++ unsigned width = 0; ++ unsigned columns = 0; ++ for (unsigned i = 0; i < length; i++) ++ { ++ unsigned v = arrayZ[i]; ++ width += v; ++ columns += (v != 0); ++ } ++ return hb_pair (width, columns); ++ } ++ ++ HB_HOT ++ hb_pair_t combine_width (const chars_t& other) const ++ { ++ unsigned combined_width = 0; ++ unsigned combined_columns = 0; ++ for (unsigned i = 0; i < length; i++) ++ { ++ unsigned v = hb_max (arrayZ[i], other.arrayZ[i]); ++ combined_width += v; ++ combined_columns += (v != 0); ++ } ++ return hb_pair (combined_width, combined_columns); ++ } ++ }; ++ ++ hb_pair_t combine_width (const delta_row_encoding_t& other_encoding) const { return chars.combine_width (other_encoding.chars); } ++ ++ // Actual data ++ ++ chars_t chars; + unsigned width = 0; +- hb_vector_t columns; + unsigned overhead = 0; + hb_vector_t*> items; + + delta_row_encoding_t () = default; +- delta_row_encoding_t (hb_vector_t&& chars_, +- const hb_vector_t* row = nullptr) : +- delta_row_encoding_t () ++ delta_row_encoding_t (hb_vector_t*> &&rows, unsigned num_cols) ++ { ++ assert (rows); ++ ++ items = std::move (rows); ++ ++ if (unlikely (!chars.resize (num_cols))) ++ return; ++ ++ calculate_chars (); ++ } + ++ void merge (const delta_row_encoding_t& other) + { +- chars = std::move (chars_); +- width = get_width (); +- columns = get_columns (); +- overhead = get_chars_overhead (columns); +- if (row) items.push (row); ++ items.alloc (items.length + other.items.length); ++ for (auto &row : other.items) ++ add_row (row); ++ ++ // Merge chars ++ assert (chars.length == other.chars.length); ++ for (unsigned i = 0; i < chars.length; i++) ++ chars.arrayZ[i] = hb_max (chars.arrayZ[i], other.chars.arrayZ[i]); ++ chars_changed (); + } + +- bool is_empty () const +- { return !items; } ++ void chars_changed () ++ { ++ auto _ = chars.get_width (); ++ width = _.first; ++ overhead = get_chars_overhead (_.second); ++ } + +- static hb_vector_t get_row_chars (const hb_vector_t& row) ++ void calculate_chars () + { +- hb_vector_t ret; +- if (!ret.alloc (row.length)) return ret; ++ assert (items); + + bool long_words = false; + +- /* 0/1/2 byte encoding */ +- for (int i = row.length - 1; i >= 0; i--) ++ for (auto &row : items) + { +- int v = row.arrayZ[i]; +- if (v == 0) +- ret.push (0); +- else if (v > 32767 || v < -32768) ++ assert (row->length == chars.length); ++ ++ /* 0/1/2 byte encoding */ ++ for (unsigned i = 0; i < row->length; i++) + { +- long_words = true; +- break; ++ int v = row->arrayZ[i]; ++ if (v == 0) ++ continue; ++ else if (v > 32767 || v < -32768) ++ { ++ long_words = true; ++ chars.arrayZ[i] = hb_max (chars.arrayZ[i], 4); ++ } ++ else if (v > 127 || v < -128) ++ chars.arrayZ[i] = hb_max (chars.arrayZ[i], 2); ++ else ++ chars.arrayZ[i] = hb_max (chars.arrayZ[i], 1); + } +- else if (v > 127 || v < -128) +- ret.push (2); +- else +- ret.push (1); + } + +- if (!long_words) +- return ret; +- +- /* redo, 0/2/4 bytes encoding */ +- ret.reset (); +- for (int i = row.length - 1; i >= 0; i--) ++ if (long_words) + { +- int v = row.arrayZ[i]; +- if (v == 0) +- ret.push (0); +- else if (v > 32767 || v < -32768) +- ret.push (4); +- else +- ret.push (2); ++ // Convert 1s to 2s ++ for (auto &v : chars) ++ if (v == 1) ++ v = 2; + } +- return ret; +- } + +- inline unsigned get_width () +- { +- unsigned ret = + hb_iter (chars) +- | hb_reduce (hb_add, 0u) +- ; +- return ret; ++ chars_changed (); + } + +- hb_vector_t get_columns () +- { +- hb_vector_t cols; +- cols.alloc (chars.length); +- for (auto v : chars) +- { +- uint8_t flag = v ? 1 : 0; +- cols.push (flag); +- } +- return cols; +- } ++ bool is_empty () const ++ { return !items; } + +- static inline unsigned get_chars_overhead (const hb_vector_t& cols) ++ static inline unsigned get_chars_overhead (unsigned num_columns) + { + unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header +- unsigned cols_bit_count = 0; +- for (auto v : cols) +- if (v) cols_bit_count++; +- return c + cols_bit_count * 2; ++ return c + num_columns * 2; + } + +- unsigned get_gain () const ++ unsigned get_gain (unsigned additional_bytes_per_rows = 1) const + { + int count = items.length; +- return hb_max (0, (int) overhead - count); ++ return hb_max (0, (int) overhead - count * (int) additional_bytes_per_rows); + } + + int gain_from_merging (const delta_row_encoding_t& other_encoding) const + { +- int combined_width = 0; +- for (unsigned i = 0; i < chars.length; i++) +- combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]); ++ // Back of the envelope calculations to reject early. ++ signed additional_bytes_per_rows = other_encoding.width - width; ++ if (additional_bytes_per_rows > 0) ++ { ++ if (get_gain (additional_bytes_per_rows) == 0) ++ return 0; ++ } ++ else ++ { ++ if (other_encoding.get_gain (-additional_bytes_per_rows) == 0) ++ return 0; ++ } + +- hb_vector_t combined_columns; +- combined_columns.alloc (columns.length); +- for (unsigned i = 0; i < columns.length; i++) +- combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]); ++ auto pair = combine_width (other_encoding); ++ unsigned combined_width = pair.first; ++ unsigned combined_columns = pair.second; + +- int combined_overhead = get_chars_overhead (combined_columns); +- int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead +- - (combined_width - (int) width) * items.length +- - (combined_width - (int) other_encoding.width) * other_encoding.items.length; ++ int combined_gain = (int) overhead + (int) other_encoding.overhead; ++ combined_gain -= (combined_width - (int) width) * items.length; ++ combined_gain -= (combined_width - (int) other_encoding.width) * other_encoding.items.length; ++ combined_gain -= get_chars_overhead (combined_columns); + + return combined_gain; + } + +- static int cmp (const void *pa, const void *pb) +- { +- const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; +- const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; +- +- int gain_a = a->get_gain (); +- int gain_b = b->get_gain (); +- +- if (gain_a != gain_b) +- return gain_a - gain_b; +- +- return (b->chars).as_array ().cmp ((a->chars).as_array ()); +- } ++ bool add_row (const hb_vector_t* row) ++ { return items.push (row); } + +- static int cmp_width (const void *pa, const void *pb) ++ static int cmp (const void *pa, const void *pb) + { + const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; + const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; +@@ -2466,11 +2461,8 @@ struct delta_row_encoding_t + if (a->width != b->width) + return (int) a->width - (int) b->width; + +- return (b->chars).as_array ().cmp ((a->chars).as_array ()); ++ return b->chars.cmp (a->chars); + } +- +- bool add_row (const hb_vector_t* row) +- { return items.push (row); } + }; + + struct VarRegionAxis +@@ -2548,32 +2540,112 @@ struct SparseVarRegionAxis + DEFINE_SIZE_STATIC (8); + }; + +-#define REGION_CACHE_ITEM_CACHE_INVALID INT_MIN +-#define REGION_CACHE_ITEM_MULTIPLIER (float (1 << ((sizeof (int) * 8) - 2))) +-#define REGION_CACHE_ITEM_DIVISOR (1.f / float (1 << ((sizeof (int) * 8) - 2))) +- +-struct VarRegionList ++struct hb_scalar_cache_t + { +- using cache_t = hb_atomic_t; ++ private: ++ static constexpr unsigned STATIC_LENGTH = 16; ++ static constexpr int INVALID = INT_MIN; ++ static constexpr float MULTIPLIER = 1 << ((sizeof (int) * 8) - 2); ++ static constexpr float DIVISOR = 1.f / MULTIPLIER; + +- float evaluate (unsigned int region_index, +- const int *coords, unsigned int coord_len, +- cache_t *cache = nullptr) const ++ public: ++ hb_scalar_cache_t () : length (STATIC_LENGTH) { clear (); } ++ ++ hb_scalar_cache_t (const hb_scalar_cache_t&) = delete; ++ hb_scalar_cache_t (hb_scalar_cache_t&&) = delete; ++ hb_scalar_cache_t& operator= (const hb_scalar_cache_t&) = delete; ++ hb_scalar_cache_t& operator= (hb_scalar_cache_t&&) = delete; ++ ++ static hb_scalar_cache_t *create (unsigned int count, ++ hb_scalar_cache_t *scratch_cache = nullptr) + { +- if (unlikely (region_index >= regionCount)) +- return 0.; ++ if (!count) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); + +- cache_t *cached_value = nullptr; +- if (cache) ++ if (scratch_cache && count <= scratch_cache->length) + { +- cached_value = &(cache[region_index]); +- if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) +- return *cached_value * REGION_CACHE_ITEM_DIVISOR; ++ scratch_cache->clear (); ++ return scratch_cache; + } + ++ auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (static_values) + sizeof (static_values[0]) * count); ++ if (unlikely (!cache)) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); ++ ++ cache->length = count; ++ cache->clear (); ++ ++ return cache; ++ } ++ ++ static void destroy (hb_scalar_cache_t *cache, ++ hb_scalar_cache_t *scratch_cache = nullptr) ++ { ++ if (cache != &Null(hb_scalar_cache_t) && cache != scratch_cache) ++ hb_free (cache); ++ } ++ ++ void clear () ++ { ++ auto *values = &static_values[0]; ++ unsigned i = 0; ++#ifndef HB_OPTIMIZE_SIZE ++ for (; i + 3 < length; i += 4) ++ { ++ values[i + 0] = INVALID; ++ values[i + 1] = INVALID; ++ values[i + 2] = INVALID; ++ values[i + 3] = INVALID; ++ } ++#endif ++ for (; i < length; i++) ++ values[i] = INVALID; ++ } ++ ++ HB_ALWAYS_INLINE ++ bool get (unsigned i, float *value) const ++ { ++ if (unlikely (i >= length)) ++ { ++ *value = 0.f; ++ return true; ++ } ++ auto *values = &static_values[0]; ++ auto *cached_value = &values[i]; ++ // Super hot. Most common path is that we have a cached value of 0. ++ int v = *cached_value; ++ if (likely (!v)) ++ { ++ *value = 0.f; ++ return true; ++ } ++ if (v == INVALID) ++ return false; ++ *value = v * DIVISOR; ++ return true; ++ } ++ ++ HB_ALWAYS_INLINE ++ void set (unsigned i, float value) ++ { ++ if (unlikely (i >= length)) return; ++ auto *values = &static_values[0]; ++ auto *cached_value = &values[i]; ++ *cached_value = roundf(value * MULTIPLIER); ++ } ++ ++ private: ++ unsigned length; ++ mutable hb_atomic_t static_values[STATIC_LENGTH]; ++}; ++ ++struct VarRegionList ++{ ++ private: ++ float evaluate_impl (unsigned int region_index, ++ const int *coords, unsigned int coord_len) const ++ { + const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); ++ float v = 1.f; + +- float v = 1.; + unsigned int count = axisCount; + for (unsigned int i = 0; i < count; i++) + { +@@ -2581,15 +2653,32 @@ struct VarRegionList + float factor = axes[i].evaluate (coord); + if (factor == 0.f) + { +- if (cache) +- *cached_value = 0.; +- return 0.; ++ v = 0.f; ++ break; + } + v *= factor; + } + ++ return v; ++ } ++ ++ public: ++ HB_ALWAYS_INLINE ++ float evaluate (unsigned int region_index, ++ const int *coords, unsigned int coord_len, ++ hb_scalar_cache_t *cache = nullptr) const ++ { ++ if (unlikely (region_index >= regionCount)) ++ return 0.; ++ ++ float v; ++ if (cache && cache->get (region_index, &v)) ++ return v; ++ ++ v = evaluate_impl (region_index, coords, coord_len); ++ + if (cache) +- *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; ++ cache->set (region_index, v); + return v; + } + +@@ -2732,29 +2821,24 @@ struct SparseVariationRegion : Array16Of + + struct SparseVarRegionList + { +- using cache_t = hb_atomic_t; +- ++ HB_ALWAYS_INLINE + float evaluate (unsigned int region_index, + const int *coords, unsigned int coord_len, +- cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + if (unlikely (region_index >= regions.len)) + return 0.; + +- cache_t *cached_value = nullptr; +- if (cache) +- { +- cached_value = &(cache[region_index]); +- if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) +- return *cached_value * REGION_CACHE_ITEM_DIVISOR; +- } ++ float v; ++ if (cache && cache->get (region_index, &v)) ++ return v; + + const SparseVariationRegion ®ion = this+regions[region_index]; + +- float v = region.evaluate (coords, coord_len); +- ++ v = region.evaluate (coords, coord_len); + if (cache) +- *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; ++ cache->set (region_index, v); ++ + return v; + } + +@@ -2792,46 +2876,62 @@ struct VarData + + itemCount * get_row_size (); + } + +- float get_delta (unsigned int inner, +- const int *coords, unsigned int coord_count, +- const VarRegionList ®ions, +- VarRegionList::cache_t *cache = nullptr) const ++ float _get_delta (unsigned int inner, ++ const int *coords, unsigned int coord_count, ++ const VarRegionList ®ions, ++ hb_scalar_cache_t *cache = nullptr) const + { + if (unlikely (inner >= itemCount)) + return 0.; ++ bool is_long = longWords (); ++ unsigned int count = regionIndices.len; ++ unsigned word_count = wordCount (); ++ unsigned int scount = is_long ? count : word_count; ++ unsigned int lcount = is_long ? word_count : 0; + +- unsigned int count = regionIndices.len; +- bool is_long = longWords (); +- unsigned word_count = wordCount (); +- unsigned int scount = is_long ? count : word_count; +- unsigned int lcount = is_long ? word_count : 0; ++ const HBUINT8 *bytes = get_delta_bytes (); ++ const HBUINT8 *row = bytes + inner * get_row_size (); + +- const HBUINT8 *bytes = get_delta_bytes (); +- const HBUINT8 *row = bytes + inner * get_row_size (); ++ float delta = 0.; ++ unsigned int i = 0; + +- float delta = 0.; +- unsigned int i = 0; ++ const HBINT32 *lcursor = reinterpret_cast (row); ++ for (; i < lcount; i++) ++ { ++ float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); ++ if (scalar) ++ delta += scalar * *lcursor; ++ lcursor++; ++ } ++ const HBINT16 *scursor = reinterpret_cast (lcursor); ++ for (; i < scount; i++) ++ { ++ float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); ++ if (scalar) ++ delta += scalar * *scursor; ++ scursor++; ++ } ++ const HBINT8 *bcursor = reinterpret_cast (scursor); ++ for (; i < count; i++) ++ { ++ float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); ++ if (scalar) ++ delta += scalar * *bcursor; ++ bcursor++; ++ } + +- const HBINT32 *lcursor = reinterpret_cast (row); +- for (; i < lcount; i++) +- { +- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); +- delta += scalar * *lcursor++; +- } +- const HBINT16 *scursor = reinterpret_cast (lcursor); +- for (; i < scount; i++) +- { +- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); +- delta += scalar * *scursor++; +- } +- const HBINT8 *bcursor = reinterpret_cast (scursor); +- for (; i < count; i++) +- { +- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); +- delta += scalar * *bcursor++; +- } ++ return delta; ++ } + +- return delta; ++ HB_ALWAYS_INLINE ++ float get_delta (unsigned int inner, ++ const int *coords, unsigned int coord_count, ++ const VarRegionList ®ions, ++ hb_scalar_cache_t *cache = nullptr) const ++ { ++ unsigned int count = regionIndices.len; ++ if (!count) return 0.f; // This is quite common, so optimize it. ++ return _get_delta (inner, coords, coord_count, regions, cache); + } + + void get_region_scalars (const int *coords, unsigned int coord_count, +@@ -3150,7 +3250,7 @@ struct MultiVarData + const int *coords, unsigned int coord_count, + const SparseVarRegionList ®ions, + hb_array_t out, +- SparseVarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + auto &deltaSets = StructAfter (regionIndices); + +@@ -3187,31 +3287,24 @@ struct MultiVarData + struct ItemVariationStore + { + friend struct item_variations_t; +- using cache_t = VarRegionList::cache_t; + +- cache_t *create_cache () const ++ hb_scalar_cache_t *create_cache () const + { + #ifdef HB_NO_VAR +- return nullptr; ++ return hb_scalar_cache_t::create (0); + #endif +- unsigned count = (this+regions).regionCount; +- if (!count) return nullptr; +- +- cache_t *cache = (cache_t *) hb_malloc (sizeof (float) * count); +- if (unlikely (!cache)) return nullptr; +- +- for (unsigned i = 0; i < count; i++) +- cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; +- +- return cache; ++ return hb_scalar_cache_t::create ((this+regions).regionCount); + } + +- static void destroy_cache (cache_t *cache) { hb_free (cache); } ++ static void destroy_cache (hb_scalar_cache_t *cache) ++ { ++ hb_scalar_cache_t::destroy (cache); ++ } + + private: + float get_delta (unsigned int outer, unsigned int inner, + const int *coords, unsigned int coord_count, +- VarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + #ifdef HB_NO_VAR + return 0.f; +@@ -3229,7 +3322,7 @@ struct ItemVariationStore + public: + float get_delta (unsigned int index, + const int *coords, unsigned int coord_count, +- VarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + unsigned int outer = index >> 16; + unsigned int inner = index & 0xFFFF; +@@ -3237,7 +3330,7 @@ struct ItemVariationStore + } + float get_delta (unsigned int index, + hb_array_t coords, +- VarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + return get_delta (index, + coords.arrayZ, coords.length, +@@ -3356,7 +3449,7 @@ struct ItemVariationStore + for (unsigned i = 0; i < count; i++) + { + hb_inc_bimap_t *map = inner_maps.push (); +- if (!c->propagate_error(inner_maps)) ++ if (unlikely (!c->propagate_error(inner_maps))) + return_trace(nullptr); + auto &data = this+dataSets[i]; + +@@ -3445,43 +3538,28 @@ struct ItemVariationStore + + struct MultiItemVariationStore + { +- using cache_t = SparseVarRegionList::cache_t; +- +- cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const ++ hb_scalar_cache_t *create_cache (hb_scalar_cache_t *static_cache = nullptr) const + { + #ifdef HB_NO_VAR +- return nullptr; ++ return hb_scalar_cache_t::create (0); + #endif + auto &r = this+regions; + unsigned count = r.regions.len; + +- cache_t *cache; +- if (count <= static_cache.length) +- cache = static_cache.arrayZ; +- else +- { +- cache = (cache_t *) hb_malloc (sizeof (float) * count); +- if (unlikely (!cache)) return nullptr; +- } +- +- for (unsigned i = 0; i < count; i++) +- cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; +- +- return cache; ++ return hb_scalar_cache_t::create (count, static_cache); + } + +- static void destroy_cache (cache_t *cache, +- hb_array_t static_cache = hb_array_t ()) ++ static void destroy_cache (hb_scalar_cache_t *cache, ++ hb_scalar_cache_t *static_cache = nullptr) + { +- if (cache != static_cache.arrayZ) +- hb_free (cache); ++ hb_scalar_cache_t::destroy (cache, static_cache); + } + + private: + void get_delta (unsigned int outer, unsigned int inner, + const int *coords, unsigned int coord_count, + hb_array_t out, +- VarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + #ifdef HB_NO_VAR + return; +@@ -3501,7 +3579,7 @@ struct MultiItemVariationStore + void get_delta (unsigned int index, + const int *coords, unsigned int coord_count, + hb_array_t out, +- VarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + unsigned int outer = index >> 16; + unsigned int inner = index & 0xFFFF; +@@ -3510,7 +3588,7 @@ struct MultiItemVariationStore + void get_delta (unsigned int index, + hb_array_t coords, + hb_array_t out, +- VarRegionList::cache_t *cache = nullptr) const ++ hb_scalar_cache_t *cache = nullptr) const + { + return get_delta (index, + coords.arrayZ, coords.length, +@@ -3540,8 +3618,6 @@ struct MultiItemVariationStore + DEFINE_SIZE_ARRAY_SIZED (8, dataSets); + }; + +-#undef REGION_CACHE_ITEM_CACHE_INVALID +- + template + struct DeltaSetIndexMapFormat01 + { +@@ -3592,13 +3668,19 @@ struct DeltaSetIndexMapFormat01 + return_trace (true); + } + ++ HB_ALWAYS_INLINE + uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ + { + /* If count is zero, pass value unchanged. This takes + * care of direct mapping for advance map. */ + if (!mapCount) + return v; ++ return _map (v); ++ } + ++ HB_HOT ++ uint32_t _map (unsigned int v) const /* Returns 16.16 outer.inner. */ ++ { + if (v >= mapCount) + v = mapCount - 1; + +@@ -3654,8 +3736,8 @@ struct DeltaSetIndexMap + { + TRACE_SERIALIZE (this); + unsigned length = plan.get_output_map ().length; +- u.format = length <= 0xFFFF ? 0 : 1; +- switch (u.format) { ++ u.format.v = length <= 0xFFFF ? 0 : 1; ++ switch (u.format.v) { + case 0: hb_barrier (); return_trace (u.format0.serialize (c, plan)); + case 1: hb_barrier (); return_trace (u.format1.serialize (c, plan)); + default:return_trace (false); +@@ -3664,7 +3746,7 @@ struct DeltaSetIndexMap + + uint32_t map (unsigned v) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return (u.format0.map (v)); + case 1: hb_barrier (); return (u.format1.map (v)); + default:return v; +@@ -3673,7 +3755,7 @@ struct DeltaSetIndexMap + + unsigned get_map_count () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return u.format0.get_map_count (); + case 1: hb_barrier (); return u.format1.get_map_count (); + default:return 0; +@@ -3682,7 +3764,7 @@ struct DeltaSetIndexMap + + unsigned get_width () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return u.format0.get_width (); + case 1: hb_barrier (); return u.format1.get_width (); + default:return 0; +@@ -3691,7 +3773,7 @@ struct DeltaSetIndexMap + + unsigned get_inner_bit_count () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return u.format0.get_inner_bit_count (); + case 1: hb_barrier (); return u.format1.get_inner_bit_count (); + default:return 0; +@@ -3701,9 +3783,9 @@ struct DeltaSetIndexMap + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + default:return_trace (true); +@@ -3713,7 +3795,7 @@ struct DeltaSetIndexMap + DeltaSetIndexMap* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); +- switch (u.format) { ++ switch (u.format.v) { + case 0: hb_barrier (); return_trace (reinterpret_cast (u.format0.copy (c))); + case 1: hb_barrier (); return_trace (reinterpret_cast (u.format1.copy (c))); + default:return_trace (nullptr); +@@ -3722,12 +3804,12 @@ struct DeltaSetIndexMap + + protected: + union { +- HBUINT8 format; /* Format identifier */ ++ struct { HBUINT8 v; } format; /* Format identifier */ + DeltaSetIndexMapFormat01 format0; + DeltaSetIndexMapFormat01 format1; + } u; + public: +- DEFINE_SIZE_UNION (1, format); ++ DEFINE_SIZE_UNION (1, format.v); + }; + + +@@ -3736,7 +3818,7 @@ struct ItemVarStoreInstancer + ItemVarStoreInstancer (const ItemVariationStore *varStore_, + const DeltaSetIndexMap *varIdxMap, + hb_array_t coords, +- VarRegionList::cache_t *cache = nullptr) : ++ hb_scalar_cache_t *cache = nullptr) : + varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache) + { + if (!varStore) +@@ -3762,7 +3844,7 @@ struct ItemVarStoreInstancer + const ItemVariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; + hb_array_t coords; +- VarRegionList::cache_t *cache; ++ hb_scalar_cache_t *cache; + }; + + struct MultiItemVarStoreInstancer +@@ -3770,7 +3852,7 @@ struct MultiItemVarStoreInstancer + MultiItemVarStoreInstancer (const MultiItemVariationStore *varStore, + const DeltaSetIndexMap *varIdxMap, + hb_array_t coords, +- SparseVarRegionList::cache_t *cache = nullptr) : ++ hb_scalar_cache_t *cache = nullptr) : + varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache) + { + if (!varStore) +@@ -3803,7 +3885,7 @@ struct MultiItemVarStoreInstancer + const MultiItemVariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; + hb_array_t coords; +- SparseVarRegionList::cache_t *cache; ++ hb_scalar_cache_t *cache; + }; + + +@@ -4130,7 +4212,7 @@ struct Condition + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.evaluate (coords, coord_len, instancer); + case 2: hb_barrier (); return u.format2.evaluate (coords, coord_len, instancer); + case 3: hb_barrier (); return u.format3.evaluate (coords, coord_len, instancer); +@@ -4143,7 +4225,7 @@ struct Condition + Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c, + hb_map_t *condition_map /* OUT */) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.keep_with_variations (c, condition_map); + // TODO(subset) + default: c->apply = false; return KEEP_COND_WITH_VAR; +@@ -4153,9 +4235,9 @@ struct Condition + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); +@@ -4168,9 +4250,9 @@ struct Condition + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +- if (!u.format.sanitize (c)) return_trace (false); ++ if (!u.format.v.sanitize (c)) return_trace (false); + hb_barrier (); +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); +@@ -4182,7 +4264,7 @@ struct Condition + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + ConditionAxisRange format1; + ConditionValue format2; + ConditionAnd format3; +@@ -4190,7 +4272,7 @@ struct Condition + ConditionNegate format5; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + template +@@ -4353,7 +4435,7 @@ struct FeatureTableSubstitutionRecord + if (unlikely (!s->extend_min (this))) return_trace (false); + + uint32_t *new_feature_idx; +- if (!c->feature_index_map->has (feature_index, &new_feature_idx)) ++ if (!c->feature_map_w_duplicates->has (feature_index, &new_feature_idx)) + return_trace (false); + + if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) +@@ -4371,7 +4453,7 @@ struct FeatureTableSubstitutionRecord + { + TRACE_SUBSET (this); + uint32_t *new_feature_index; +- if (!c->feature_index_map->has (featureIndex, &new_feature_index)) ++ if (!c->feature_map_w_duplicates->has (featureIndex, &new_feature_index)) + return_trace (false); + + auto *out = c->subset_context->serializer->embed (this); +@@ -4645,7 +4727,7 @@ struct FeatureVariations + + int keep_up_to = -1; + for (int i = varRecords.len - 1; i >= 0; i--) { +- if (varRecords[i].intersects_features (this, l->feature_index_map)) { ++ if (varRecords[i].intersects_features (this, l->feature_map_w_duplicates)) { + keep_up_to = i; + break; + } +@@ -4783,13 +4865,13 @@ struct VariationDevice + + hb_position_t get_x_delta (hb_font_t *font, + const ItemVariationStore &store, +- ItemVariationStore::cache_t *store_cache = nullptr) const +- { return !font->num_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } ++ hb_scalar_cache_t *store_cache = nullptr) const ++ { return !font->has_nonzero_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } + + hb_position_t get_y_delta (hb_font_t *font, + const ItemVariationStore &store, +- ItemVariationStore::cache_t *store_cache = nullptr) const +- { return !font->num_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } ++ hb_scalar_cache_t *store_cache = nullptr) const ++ { return !font->has_nonzero_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } + + VariationDevice* copy (hb_serialize_context_t *c, + const hb_hashmap_t> *layout_variation_idx_delta_map) const +@@ -4823,9 +4905,9 @@ struct VariationDevice + + float get_delta (hb_font_t *font, + const ItemVariationStore &store, +- ItemVariationStore::cache_t *store_cache = nullptr) const ++ hb_scalar_cache_t *store_cache = nullptr) const + { +- return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); ++ return store.get_delta (varIdx, font->coords, font->num_coords, store_cache); + } + + protected: +@@ -4850,7 +4932,7 @@ struct Device + { + hb_position_t get_x_delta (hb_font_t *font, + const ItemVariationStore &store=Null (ItemVariationStore), +- ItemVariationStore::cache_t *store_cache = nullptr) const ++ hb_scalar_cache_t *store_cache = nullptr) const + { + switch (u.b.format) + { +@@ -4868,7 +4950,7 @@ struct Device + } + hb_position_t get_y_delta (hb_font_t *font, + const ItemVariationStore &store=Null (ItemVariationStore), +- ItemVariationStore::cache_t *store_cache = nullptr) const ++ hb_scalar_cache_t *store_cache = nullptr) const + { + switch (u.b.format) + { +@@ -4954,6 +5036,18 @@ struct Device + } + } + ++ bool is_variation_device () const ++ { ++ switch (u.b.format) { ++#ifndef HB_NO_VAR ++ case 0x8000: ++ return true; ++#endif ++ default: ++ return false; ++ } ++ } ++ + protected: + union { + DeviceHeader b; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh +index 0cfa139a260..f6aabc84ac9 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gpos-table.hh +@@ -63,12 +63,20 @@ inline bool PosLookup::dispatch_recurse_func (hb_ot_apply + c->set_lookup_index (lookup_index); + c->set_lookup_props (l.get_props ()); + ++ uint32_t stack_match_positions[8]; ++ hb_vector_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 +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh +index fd8a68be02d..8d5e1f18638 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsub-table.hh +@@ -76,12 +76,20 @@ inline bool SubstLookup::dispatch_recurse_func (hb_ot_app + c->set_lookup_index (lookup_index); + c->set_lookup_props (l.get_props ()); + ++ uint32_t stack_match_positions[8]; ++ hb_vector_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 +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh +index 072e5cdba26..05bbf3395bf 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh +@@ -397,303 +397,311 @@ struct hb_collect_coverage_context_t : + set_t *set; + }; + +-struct hb_ot_apply_context_t : +- hb_dispatch_context_t ++struct matcher_t + { +- struct matcher_t +- { +- typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); +- +- void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } +- void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } +- void set_ignore_hidden (bool ignore_hidden_) { ignore_hidden = ignore_hidden_; } +- void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } +- void set_mask (hb_mask_t mask_) { mask = mask_; } +- void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; } +- void set_syllable (uint8_t syllable_) { syllable = per_syllable ? syllable_ : 0; } +- void set_match_func (match_func_t match_func_, +- const void *match_data_) +- { match_func = match_func_; match_data = match_data_; } +- +- enum may_match_t { +- MATCH_NO, +- MATCH_YES, +- MATCH_MAYBE +- }; ++ typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); ++ ++ template ++ void init (const context_t *c, bool context_match = false) ++ { ++ set_match_func (nullptr, nullptr); ++ lookup_props = c->lookup_props; ++ /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ ++ ignore_zwnj = c->table_index == 1 || (context_match && c->auto_zwnj); ++ /* Ignore ZWJ if we are matching context, or asked to. */ ++ ignore_zwj = context_match || c->auto_zwj; ++ /* Ignore hidden glyphs (like CGJ) during GPOS. */ ++ ignore_hidden = c->table_index == 1; ++ mask = context_match ? -1 : c->lookup_mask; ++ /* Per syllable matching is only for GSUB. */ ++ per_syllable = c->table_index == 0 && c->per_syllable; ++ syllable = 0; ++ } ++ ++ void set_match_func (match_func_t match_func_, ++ const void *match_data_) ++ { match_func = match_func_; match_data = match_data_; } ++ ++ enum may_match_t { ++ MATCH_NO, ++ MATCH_YES, ++ MATCH_MAYBE ++ }; + + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- may_match_t may_match (hb_glyph_info_t &info, +- hb_codepoint_t glyph_data) const +- { +- if (!(info.mask & mask) || +- (syllable && syllable != info.syllable ())) +- return MATCH_NO; ++ may_match_t may_match (hb_glyph_info_t &info, ++ hb_codepoint_t glyph_data) const ++ { ++ if (!(info.mask & mask) || ++ (per_syllable && syllable && syllable != info.syllable ())) ++ return MATCH_NO; + +- if (match_func) +- return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; ++ if (match_func) ++ return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; + +- return MATCH_MAYBE; +- } ++ return MATCH_MAYBE; ++ } + +- enum may_skip_t { +- SKIP_NO, +- SKIP_YES, +- SKIP_MAYBE +- }; ++ enum may_skip_t { ++ SKIP_NO, ++ SKIP_YES, ++ SKIP_MAYBE ++ }; + ++ template + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- may_skip_t may_skip (const hb_ot_apply_context_t *c, +- const hb_glyph_info_t &info) const +- { +- if (!c->check_glyph_property (&info, lookup_props)) +- return SKIP_YES; ++ may_skip_t may_skip (const context_t *c, ++ const hb_glyph_info_t &info) const ++ { ++ if (!c->check_glyph_property (&info, lookup_props)) ++ return SKIP_YES; + +- if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && +- (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && +- (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && +- (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) +- return SKIP_MAYBE; ++ if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && ++ (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && ++ (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && ++ (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) ++ return SKIP_MAYBE; + +- return SKIP_NO; +- } ++ return SKIP_NO; ++ } + +- protected: +- unsigned int lookup_props = 0; +- hb_mask_t mask = -1; +- bool ignore_zwnj = false; +- bool ignore_zwj = false; +- bool ignore_hidden = false; +- bool per_syllable = false; +- uint8_t syllable = 0; +- match_func_t match_func = nullptr; +- const void *match_data = nullptr; +- }; ++ public: ++ unsigned int lookup_props = 0; ++ hb_mask_t mask = -1; ++ bool ignore_zwnj = false; ++ bool ignore_zwj = false; ++ bool ignore_hidden = false; ++ bool per_syllable = false; ++ uint8_t syllable = 0; ++ match_func_t match_func = nullptr; ++ const void *match_data = nullptr; ++}; + +- struct skipping_iterator_t ++template ++struct skipping_iterator_t ++{ ++ void init (context_t *c_, bool context_match = false) + { +- void init (hb_ot_apply_context_t *c_, bool context_match = false) +- { +- c = c_; +- end = c->buffer->len; +- match_glyph_data16 = nullptr; ++ c = c_; ++ end = c->buffer->len; ++ match_glyph_data16 = nullptr; + #ifndef HB_NO_BEYOND_64K +- match_glyph_data24 = nullptr; ++ match_glyph_data24 = nullptr; + #endif +- matcher.set_match_func (nullptr, nullptr); +- matcher.set_lookup_props (c->lookup_props); +- /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ +- matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); +- /* Ignore ZWJ if we are matching context, or asked to. */ +- matcher.set_ignore_zwj (context_match || c->auto_zwj); +- /* Ignore hidden glyphs (like CGJ) during GPOS. */ +- matcher.set_ignore_hidden (c->table_index == 1); +- matcher.set_mask (context_match ? -1 : c->lookup_mask); +- /* Per syllable matching is only for GSUB. */ +- matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); +- matcher.set_syllable (0); +- } +- void set_lookup_props (unsigned int lookup_props) +- { +- matcher.set_lookup_props (lookup_props); +- } +- void set_match_func (matcher_t::match_func_t match_func_, +- const void *match_data_) +- { +- matcher.set_match_func (match_func_, match_data_); +- } +- void set_glyph_data (const HBUINT16 glyph_data[]) +- { +- match_glyph_data16 = glyph_data; ++ matcher.init (c, context_match); ++ } ++ void set_lookup_props (unsigned int lookup_props) ++ { ++ matcher.lookup_props = lookup_props; ++ } ++ void set_match_func (matcher_t::match_func_t match_func_, ++ const void *match_data_) ++ { ++ matcher.set_match_func (match_func_, match_data_); ++ } ++ void set_glyph_data (const HBUINT16 glyph_data[]) ++ { ++ match_glyph_data16 = glyph_data; + #ifndef HB_NO_BEYOND_64K +- match_glyph_data24 = nullptr; ++ match_glyph_data24 = nullptr; + #endif +- } ++ } + #ifndef HB_NO_BEYOND_64K +- void set_glyph_data (const HBUINT24 glyph_data[]) +- { +- match_glyph_data16 = nullptr; +- match_glyph_data24 = glyph_data; +- } ++ void set_glyph_data (const HBUINT24 glyph_data[]) ++ { ++ match_glyph_data16 = nullptr; ++ match_glyph_data24 = glyph_data; ++ } + #endif + + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- void reset (unsigned int start_index_) +- { +- idx = start_index_; +- end = c->buffer->len; +- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); +- } ++ void reset (unsigned int start_index_) ++ { ++ // For GSUB forward iterator ++ idx = start_index_; ++ end = c->buffer->len; ++ matcher.syllable = c->buffer->cur().syllable(); ++ } ++ void reset_back (unsigned int start_index_, bool from_out_buffer = false) ++ { ++ // For GSUB backward iterator ++ idx = start_index_; ++ matcher.syllable = c->buffer->cur().syllable(); ++ } + + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- void reset_fast (unsigned int start_index_) +- { +- // Doesn't set end or syllable. Used by GPOS which doesn't care / change. +- idx = start_index_; +- } +- +- void reject () +- { +- backup_glyph_data (); +- } ++ void reset_fast (unsigned int start_index_) ++ { ++ // Doesn't set end or syllable. Used by GPOS which doesn't care / change. ++ idx = start_index_; ++ } + +- matcher_t::may_skip_t + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- may_skip (const hb_glyph_info_t &info) const +- { return matcher.may_skip (c, info); } ++ matcher_t::may_skip_t may_skip (const hb_glyph_info_t &info) const ++ { return matcher.may_skip (c, info); } + +- enum match_t { +- MATCH, +- NOT_MATCH, +- SKIP +- }; ++ enum match_t { ++ MATCH, ++ NOT_MATCH, ++ SKIP ++ }; + + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- match_t match (hb_glyph_info_t &info) +- { +- matcher_t::may_skip_t skip = matcher.may_skip (c, info); +- if (unlikely (skip == matcher_t::SKIP_YES)) +- return SKIP; ++ match_t match (hb_glyph_info_t &info) ++ { ++ matcher_t::may_skip_t skip = matcher.may_skip (c, info); ++ if (unlikely (skip == matcher_t::SKIP_YES)) ++ return SKIP; + +- matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); +- if (match == matcher_t::MATCH_YES || +- (match == matcher_t::MATCH_MAYBE && +- skip == matcher_t::SKIP_NO)) +- return MATCH; ++ matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); ++ if (match == matcher_t::MATCH_YES || ++ (match == matcher_t::MATCH_MAYBE && ++ skip == matcher_t::SKIP_NO)) ++ return MATCH; + +- if (skip == matcher_t::SKIP_NO) +- return NOT_MATCH; ++ if (skip == matcher_t::SKIP_NO) ++ return NOT_MATCH; + +- return SKIP; ++ return SKIP; + } + + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- bool next (unsigned *unsafe_to = nullptr) ++ bool next (unsigned *unsafe_to = nullptr) ++ { ++ auto *info = c->buffer->info; ++ const signed stop = (signed) end - 1; ++ while ((signed) idx < stop) + { +- const signed stop = (signed) end - 1; +- while ((signed) idx < stop) ++ idx++; ++ switch (match (info[idx])) + { +- idx++; +- switch (match (c->buffer->info[idx])) ++ case MATCH: + { +- case MATCH: +- { +- advance_glyph_data (); +- return true; +- } +- case NOT_MATCH: +- { +- if (unsafe_to) +- *unsafe_to = idx + 1; +- return false; +- } +- case SKIP: +- continue; ++ advance_glyph_data (); ++ return true; + } ++ case NOT_MATCH: ++ { ++ if (unsafe_to) ++ *unsafe_to = idx + 1; ++ return false; ++ } ++ case SKIP: ++ continue; + } +- if (unsafe_to) +- *unsafe_to = end; +- return false; + } ++ if (unsafe_to) ++ *unsafe_to = end; ++ return false; ++ } + #ifndef HB_OPTIMIZE_SIZE +- HB_ALWAYS_INLINE ++ HB_ALWAYS_INLINE + #endif +- bool prev (unsigned *unsafe_from = nullptr) ++ bool prev (unsigned *unsafe_from = nullptr) ++ { ++ auto *out_info = c->buffer->out_info; ++ const unsigned stop = 0; ++ while (idx > stop) + { +- const unsigned stop = 0; +- while (idx > stop) ++ idx--; ++ switch (match (out_info[idx])) + { +- idx--; +- switch (match (c->buffer->out_info[idx])) ++ case MATCH: + { +- case MATCH: +- { +- advance_glyph_data (); +- return true; +- } +- case NOT_MATCH: +- { +- if (unsafe_from) +- *unsafe_from = hb_max (1u, idx) - 1u; +- return false; +- } +- case SKIP: +- continue; ++ advance_glyph_data (); ++ return true; ++ } ++ case NOT_MATCH: ++ { ++ if (unsafe_from) ++ *unsafe_from = hb_max (1u, idx) - 1u; ++ return false; + } ++ case SKIP: ++ continue; + } +- if (unsafe_from) +- *unsafe_from = 0; +- return false; + } ++ if (unsafe_from) ++ *unsafe_from = 0; ++ return false; ++ } + +- HB_ALWAYS_INLINE +- hb_codepoint_t +- get_glyph_data () +- { +- if (match_glyph_data16) return *match_glyph_data16; +-#ifndef HB_NO_BEYOND_64K +- else +- if (match_glyph_data24) return *match_glyph_data24; +-#endif +- return 0; +- } +- HB_ALWAYS_INLINE +- void +- advance_glyph_data () +- { +- if (match_glyph_data16) match_glyph_data16++; ++ HB_ALWAYS_INLINE ++ hb_codepoint_t ++ get_glyph_data () ++ { ++ if (match_glyph_data16) return *match_glyph_data16; + #ifndef HB_NO_BEYOND_64K +- else +- if (match_glyph_data24) match_glyph_data24++; ++ else ++ if (match_glyph_data24) return *match_glyph_data24; + #endif +- } +- void +- backup_glyph_data () +- { +- if (match_glyph_data16) match_glyph_data16--; ++ return 0; ++ } ++ HB_ALWAYS_INLINE ++ void ++ advance_glyph_data () ++ { ++ if (match_glyph_data16) match_glyph_data16++; + #ifndef HB_NO_BEYOND_64K +- else +- if (match_glyph_data24) match_glyph_data24--; ++ else ++ if (match_glyph_data24) match_glyph_data24++; + #endif +- } ++ } + +- unsigned int idx; +- protected: +- hb_ot_apply_context_t *c; +- matcher_t matcher; +- const HBUINT16 *match_glyph_data16; ++ unsigned int idx; ++ protected: ++ context_t *c; ++ matcher_t matcher; ++ const HBUINT16 *match_glyph_data16; + #ifndef HB_NO_BEYOND_64K +- const HBUINT24 *match_glyph_data24; ++ const HBUINT24 *match_glyph_data24; + #endif + +- unsigned int end; +- }; +- ++ unsigned int end; ++}; + ++struct hb_ot_apply_context_t : ++ hb_dispatch_context_t ++{ + const char *get_name () { return "APPLY"; } + typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); ++ ++ template ++ static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (return_t, obj.apply (c, nullptr) ) ++ template ++ static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (return_t, obj.apply (c) ) + template +- return_t dispatch (const T &obj) { return obj.apply (this); } ++ return_t dispatch (const T &obj) { return apply_(obj, this, hb_prioritize); } ++ + static return_t default_return_value () { return false; } + 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->successful = false; ++ return default_return_value (); ++ } ++ ++ buffer->max_ops--; ++ if (unlikely (buffer->max_ops < 0)) + { +- buffer->shaping_failed = true; ++ buffer->successful = false; + return default_return_value (); + } + +@@ -703,7 +711,7 @@ struct hb_ot_apply_context_t : + return ret; + } + +- skipping_iterator_t iter_input, iter_context; ++ skipping_iterator_t iter_input, iter_context; + + unsigned int table_index; /* GSUB/GPOS */ + hb_font_t *font; +@@ -715,8 +723,7 @@ struct hb_ot_apply_context_t : + const GDEF::accelerator_t &gdef_accel; + const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; + const ItemVariationStore &var_store; +- ItemVariationStore::cache_t *var_store_cache; +- hb_set_digest_t digest; ++ hb_scalar_cache_t *var_store_cache; + + hb_direction_t direction; + hb_mask_t lookup_mask = 1; +@@ -734,11 +741,14 @@ struct hb_ot_apply_context_t : + signed last_base = -1; // GPOS uses + unsigned last_base_until = 0; // GPOS uses + ++ hb_vector_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_, + hb_blob_t *table_blob_, +- ItemVariationStore::cache_t *var_store_cache_ = nullptr) : ++ hb_scalar_cache_t *var_store_cache_ = nullptr) : + table_index (table_index_), + font (font_), face (font->face), buffer (buffer_), + sanitizer (table_blob_), +@@ -762,7 +772,7 @@ struct hb_ot_apply_context_t : + has_glyph_classes (gdef.has_glyph_classes ()) + { + init_iters (); +- buffer->collect_codepoints (digest); ++ match_positions.set_storage (stack_match_positions); + } + + void init_iters () +@@ -778,7 +788,11 @@ struct hb_ot_apply_context_t : + void set_random (bool random_) { random = random_; } + void set_recurse_func (recurse_func_t func) { recurse_func = func; } + void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } +- void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); } ++ void set_lookup_props (unsigned int lookup_props_) ++ { ++ lookup_props = gdef_accel.sanitize_lookup_props (lookup_props_); ++ init_iters (); ++ } + + uint32_t random_number () + { +@@ -787,7 +801,9 @@ struct hb_ot_apply_context_t : + return buffer->random_state; + } + +- bool match_properties_mark (hb_codepoint_t glyph, ++ HB_ALWAYS_INLINE ++ HB_HOT ++ bool match_properties_mark (const hb_glyph_info_t *info, + unsigned int glyph_props, + unsigned int match_props) const + { +@@ -795,7 +811,7 @@ struct hb_ot_apply_context_t : + * match_props has the set index. + */ + if (match_props & LookupFlag::UseMarkFilteringSet) +- return gdef_accel.mark_set_covers (match_props >> 16, glyph); ++ return gdef_accel.mark_set_covers (match_props >> 16, info->codepoint); + + /* The second byte of match_props has the meaning + * "ignore marks of attachment type different than +@@ -811,7 +827,7 @@ struct hb_ot_apply_context_t : + HB_ALWAYS_INLINE + #endif + bool check_glyph_property (const hb_glyph_info_t *info, +- unsigned int match_props) const ++ unsigned match_props) const + { + unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); + +@@ -821,8 +837,8 @@ struct hb_ot_apply_context_t : + if (glyph_props & match_props & LookupFlag::IgnoreFlags) + return false; + +- if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) +- return match_properties_mark (info->codepoint, glyph_props, match_props); ++ if (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK) ++ return match_properties_mark (info, glyph_props, match_props); + + return true; + } +@@ -832,7 +848,7 @@ struct hb_ot_apply_context_t : + bool ligature = false, + bool component = false) + { +- digest.add (glyph_index); ++ buffer->digest.add (glyph_index); + + if (new_syllables != (unsigned) -1) + buffer->cur().syllable() = new_syllables; +@@ -890,54 +906,58 @@ struct hb_ot_apply_context_t : + } + }; + +-enum class hb_ot_lookup_cache_op_t ++enum class hb_ot_subtable_cache_op_t + { +- CREATE, + ENTER, + LEAVE, +- DESTROY, + }; + + struct hb_accelerate_subtables_context_t : + hb_dispatch_context_t + { +- template +- static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c) ++ template ++ static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) ++ template ++ static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) ++ template ++ static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) + { +- const Type *typed_obj = (const Type *) obj; +- return typed_obj->apply (c); ++ const T *typed_obj = (const T *) obj; ++ return apply_ (typed_obj, c, external_cache, hb_prioritize); + } + + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + template +- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) ) ++ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<2>) HB_RETURN (bool, obj->apply_cached (c, external_cache) ) + template +- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) +- template +- static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c) ++ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) ++ template ++ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) ++ template ++ static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) + { +- const Type *typed_obj = (const Type *) obj; +- return apply_cached_ (typed_obj, c, hb_prioritize); ++ const T *typed_obj = (const T *) obj; ++ return apply_cached_ (typed_obj, c, external_cache, hb_prioritize); + } + + template +- static inline auto cache_func_ (void *p, +- hb_ot_lookup_cache_op_t op, +- hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) ) ++ static inline auto cache_func_ (hb_ot_apply_context_t *c, ++ hb_ot_subtable_cache_op_t op, ++ hb_priority<1>) HB_RETURN (bool, T::cache_func (c, op) ) + template +- static inline void * cache_func_ (void *p, +- hb_ot_lookup_cache_op_t op HB_UNUSED, +- hb_priority<0>) { return (void *) false; } ++ 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 +- static inline void * cache_func_to (void *p, +- hb_ot_lookup_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_ (p, op, hb_prioritize); ++ return cache_func_ (c, op, hb_prioritize); + } + #endif + +- typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); +- typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op); ++ typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, void *external_cache); ++ typedef bool (*hb_cache_func_t) (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op); + + struct hb_applicable_t + { +@@ -950,6 +970,7 @@ struct hb_accelerate_subtables_context_t : + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + , hb_apply_func_t apply_cached_func_ + , hb_cache_func_t cache_func_ ++ , void *external_cache_ + #endif + ) + { +@@ -958,27 +979,34 @@ struct hb_accelerate_subtables_context_t : + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + apply_cached_func = apply_cached_func_; + cache_func = cache_func_; ++ external_cache = external_cache_; + #endif + digest.init (); + obj_.get_coverage ().collect_coverage (&digest); + } + ++#ifdef HB_NO_OT_LAYOUT_LOOKUP_CACHE + bool apply (hb_ot_apply_context_t *c) const + { +- return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); ++ return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, nullptr); ++ } ++#else ++ bool apply (hb_ot_apply_context_t *c) const ++ { ++ return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, external_cache); + } +-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + bool apply_cached (hb_ot_apply_context_t *c) const + { +- return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c); ++ return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c, external_cache); + } ++ + bool cache_enter (hb_ot_apply_context_t *c) const + { +- return (bool) cache_func (c, hb_ot_lookup_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 + { +- cache_func (c, hb_ot_lookup_cache_op_t::LEAVE); ++ cache_func (c, hb_ot_subtable_cache_op_t::LEAVE); + } + #endif + +@@ -988,6 +1016,7 @@ struct hb_accelerate_subtables_context_t : + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_apply_func_t apply_cached_func; + hb_cache_func_t cache_func; ++ void *external_cache; + #endif + hb_set_digest_t digest; + }; +@@ -997,12 +1026,23 @@ struct hb_accelerate_subtables_context_t : + auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () ) + template + auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u ) ++ ++ template ++ auto external_cache_create (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.external_cache_create () ) ++ template ++ auto external_cache_create (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( nullptr ) + #endif + + /* Dispatch interface. */ + template + 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, +@@ -1010,6 +1050,7 @@ struct hb_accelerate_subtables_context_t : + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + , apply_cached_to + , cache_func_to ++ , external_cache + #endif + ); + +@@ -1023,10 +1064,10 @@ struct hb_accelerate_subtables_context_t : + * and we allocate the cache opportunity to the costliest subtable. + */ + unsigned cost = cache_cost (obj, hb_prioritize); +- if (cost > cache_user_cost) ++ if (cost > subtable_cache_user_cost) + { +- cache_user_idx = i - 1; +- cache_user_cost = cost; ++ subtable_cache_user_idx = i - 1; ++ subtable_cache_user_cost = cost; + } + #endif + +@@ -1041,8 +1082,8 @@ struct hb_accelerate_subtables_context_t : + unsigned i = 0; + + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- unsigned cache_user_idx = (unsigned) -1; +- unsigned cache_user_cost = 0; ++ unsigned subtable_cache_user_idx = (unsigned) -1; ++ unsigned subtable_cache_user_cost = 0; + #endif + }; + +@@ -1191,38 +1232,50 @@ static inline bool match_class (hb_glyph_info_t &info, unsigned value, const voi + const ClassDef &class_def = *reinterpret_cast(data); + return class_def.get_class (info.codepoint) == value; + } +-static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) ++static inline unsigned get_class_cached (const ClassDef &class_def, hb_glyph_info_t &info) + { + unsigned klass = info.syllable(); + if (klass < 255) +- return klass == value; +- const ClassDef &class_def = *reinterpret_cast(data); ++ return klass; + klass = class_def.get_class (info.codepoint); + if (likely (klass < 255)) + info.syllable() = klass; +- return klass == value; ++ return klass; + } +-static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) ++static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) ++{ ++ const ClassDef &class_def = *reinterpret_cast(data); ++ return get_class_cached (class_def, info) == value; ++} ++static inline unsigned get_class_cached1 (const ClassDef &class_def, hb_glyph_info_t &info) + { + unsigned klass = info.syllable() & 0x0F; + if (klass < 15) +- return klass == value; +- const ClassDef &class_def = *reinterpret_cast(data); ++ return klass; + klass = class_def.get_class (info.codepoint); + if (likely (klass < 15)) + info.syllable() = (info.syllable() & 0xF0) | klass; +- return klass == value; ++ return klass; + } +-static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) ++static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) ++{ ++ const ClassDef &class_def = *reinterpret_cast(data); ++ return get_class_cached1 (class_def, info) == value; ++} ++static inline unsigned get_class_cached2 (const ClassDef &class_def, hb_glyph_info_t &info) + { + unsigned klass = (info.syllable() & 0xF0) >> 4; + if (klass < 15) +- return klass == value; +- const ClassDef &class_def = *reinterpret_cast(data); ++ return klass; + klass = class_def.get_class (info.codepoint); + if (likely (klass < 15)) + info.syllable() = (info.syllable() & 0x0F) | (klass << 4); +- return klass == value; ++ return klass; ++} ++static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) ++{ ++ const ClassDef &class_def = *reinterpret_cast(data); ++ return get_class_cached2 (class_def, info) == value; + } + static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data) + { +@@ -1261,16 +1314,24 @@ static bool match_input (hb_ot_apply_context_t *c, + 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); + +- if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); +- + hb_buffer_t *buffer = c->buffer; + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ if (count == 1) ++ { ++ *end_position = buffer->idx + 1; ++ c->match_positions[0] = buffer->idx; ++ if (p_total_component_count) ++ *p_total_component_count = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); ++ return_trace (true); ++ } ++ ++ if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); ++ ++ auto &skippy_iter = c->iter_input; + skippy_iter.reset (buffer->idx); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (input); +@@ -1319,7 +1380,10 @@ static bool match_input (hb_ot_apply_context_t *c, + return_trace (false); + } + +- match_positions[i] = skippy_iter.idx; ++ if (unlikely (i + 1 > c->match_positions.length && ++ !c->match_positions.resize_dirty (i + 1))) ++ 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]); +@@ -1349,7 +1413,7 @@ static bool match_input (hb_ot_apply_context_t *c, + j--; + } + +- if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES) ++ if (found && skippy_iter.may_skip (out[j]) == matcher_t::SKIP_YES) + ligbase = LIGBASE_MAY_SKIP; + else + ligbase = LIGBASE_MAY_NOT_SKIP; +@@ -1379,13 +1443,12 @@ static bool match_input (hb_ot_apply_context_t *c, + *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) +@@ -1428,10 +1491,10 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, + * 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; +@@ -1457,7 +1520,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, + + 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) + { +@@ -1512,8 +1575,14 @@ static bool match_backtrack (hb_ot_apply_context_t *c, + { + TRACE_APPLY (nullptr); + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; +- skippy_iter.reset (c->buffer->backtrack_len ()); ++ if (!count) ++ { ++ *match_start = c->buffer->backtrack_len (); ++ return_trace (true); ++ } ++ ++ auto &skippy_iter = c->iter_context; ++ skippy_iter.reset_back (c->buffer->backtrack_len ()); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (backtrack); + +@@ -1545,7 +1614,13 @@ static bool match_lookahead (hb_ot_apply_context_t *c, + { + TRACE_APPLY (nullptr); + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; ++ if (!count) ++ { ++ *end_index = start_index; ++ return_trace (true); ++ } ++ ++ auto &skippy_iter = c->iter_context; + assert (start_index >= 1); + skippy_iter.reset (start_index - 1); + skippy_iter.set_match_func (match_func, match_data); +@@ -1696,7 +1771,6 @@ static inline void recurse_lookups (context_t *c, + + 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) +@@ -1704,9 +1778,6 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + 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. */ + { +@@ -1716,7 +1787,7 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + 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++) +@@ -1728,10 +1799,10 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + 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)) +@@ -1790,9 +1861,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + */ + + 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. +@@ -1800,8 +1871,8 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + * 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. */ +@@ -1810,27 +1881,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + { + 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_dirty (count + delta))) ++ return; + } + else + { +@@ -1840,23 +1893,20 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, + } + + /* 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); + } +@@ -1950,34 +2000,25 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, + } + + template +-HB_ALWAYS_INLINE +-static bool context_apply_lookup (hb_ot_apply_context_t *c, +- unsigned int inputCount, /* Including the first glyph (not matched) */ +- const HBUINT input[], /* Array of input values--start with second glyph */ +- unsigned int lookupCount, +- const LookupRecord lookupRecord[], +- const ContextApplyLookupContext &lookup_context) ++static inline bool context_apply_lookup (hb_ot_apply_context_t *c, ++ unsigned int inputCount, /* Including the first glyph (not matched) */ ++ const HBUINT input[], /* Array of input values--start with second glyph */ ++ unsigned int lookupCount, ++ const LookupRecord lookupRecord[], ++ 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; + 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; +@@ -1988,12 +2029,34 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, + ret = false; + } + +- if (unlikely (match_positions != match_positions_stack)) +- hb_free (match_positions); +- + return ret; + } + ++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::ENTER: ++ { ++ if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) ++ 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 true; ++ } ++ case hb_ot_subtable_cache_op_t::LEAVE: ++ { ++ c->new_syllables = (unsigned) -1; ++ HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); ++ break; ++ } ++ } ++ return false; ++} ++ + template + struct Rule + { +@@ -2209,24 +2272,29 @@ struct RuleSet + * + * Replicated from LigatureSet::apply(). */ + +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ /* We use the iter_context instead of iter_input, to avoid skipping ++ * default-ignorables and such. ++ * ++ * Related: https://github.com/harfbuzz/harfbuzz/issues/4813 ++ */ ++ auto &skippy_iter = c->iter_context; + skippy_iter.reset (c->buffer->idx); + skippy_iter.set_match_func (match_always, nullptr); + skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); +- unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; ++ unsigned unsafe_to = (unsigned) -1, unsafe_to1, unsafe_to2 = 0; + hb_glyph_info_t *first = nullptr, *second = nullptr; + bool matched = skippy_iter.next (); + if (likely (matched)) + { +- first = &c->buffer->info[skippy_iter.idx]; +- unsafe_to = skippy_iter.idx + 1; +- + if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) + { + /* Can't use the fast path if eg. the next char is a default-ignorable + * or other skippable. */ + goto slow; + } ++ ++ first = &c->buffer->info[skippy_iter.idx]; ++ unsafe_to1 = skippy_iter.idx + 1; + } + else + { +@@ -2242,8 +2310,15 @@ struct RuleSet + ; + } + matched = skippy_iter.next (); +- if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) ++ if (likely (matched)) + { ++ if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) ++ { ++ /* Can't use the fast path if eg. the next char is a default-ignorable ++ * or other skippable. */ ++ goto slow; ++ } ++ + second = &c->buffer->info[skippy_iter.idx]; + unsafe_to2 = skippy_iter.idx + 1; + } +@@ -2280,6 +2355,15 @@ struct RuleSet + { + if (unsafe_to == (unsigned) -1) + unsafe_to = unsafe_to1; ++ ++ // Skip ahead to next possible first glyph match. ++ for (; i + 1 < num_rules; i++) ++ { ++ const auto &r2 = this+rule.arrayZ[i + 1]; ++ const auto &input2 = r2.inputZ; ++ if (r2.inputCount <= 1 || input2.arrayZ[0] != input.arrayZ[0]) ++ break; ++ } + } + } + if (likely (unsafe_to != (unsigned) -1)) +@@ -2622,46 +2706,37 @@ struct ContextFormat2_5 + + unsigned cache_cost () const + { +- unsigned c = (this+classDef).cost () * ruleSet.len; +- return c >= 4 ? c : 0; ++ return (this+classDef).cost (); ++ } ++ static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) ++ { ++ return context_cache_func (c, op); + } +- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) ++ ++ struct external_cache_t ++ { ++ hb_ot_layout_binary_cache_t coverage; ++ }; ++ 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_lookup_cache_op_t::CREATE: +- return (void *) true; +- case hb_ot_lookup_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; +- 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; +- } +- case hb_ot_lookup_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; +- } +- case hb_ot_lookup_cache_op_t::DESTROY: +- return nullptr; ++ cache->coverage.clear (); + } +- return nullptr; ++ return cache; + } +- +- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } +- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } +- bool _apply (hb_ot_apply_context_t *c, bool cached) const ++ bool apply_cached (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, true, external_cache); } ++ bool apply (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, false, external_cache); } ++ bool _apply (hb_ot_apply_context_t *c, bool cached, void *external_cache) const + { + TRACE_APPLY (this); ++#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE ++ external_cache_t *cache = (external_cache_t *) external_cache; ++ unsigned int index = (this+coverage).get_coverage_binary (c->buffer->cur().codepoint, cache ? &cache->coverage : nullptr); ++#else + unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); ++#endif + if (index == NOT_COVERED) return_trace (false); + + const ClassDef &class_def = this+classDef; +@@ -2671,10 +2746,7 @@ struct ContextFormat2_5 + &class_def + }; + +- if (cached && c->buffer->cur().syllable() < 255) +- index = c->buffer->cur().syllable (); +- else +- index = class_def.get_class (c->buffer->cur().codepoint); ++ index = cached ? get_class_cached (class_def, c->buffer->cur()) : class_def.get_class (c->buffer->cur().codepoint); + const RuleSet &rule_set = this+ruleSet[index]; + return_trace (rule_set.apply (c, lookup_context)); + } +@@ -2919,9 +2991,9 @@ struct Context + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); +@@ -2935,7 +3007,7 @@ struct Context + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + ContextFormat1_4 format1; + ContextFormat2_5 format2; + ContextFormat3 format3; +@@ -3069,27 +3141,18 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c + } + + template +-HB_ALWAYS_INLINE +-static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, +- unsigned int backtrackCount, +- const HBUINT backtrack[], +- unsigned int inputCount, /* Including the first glyph (not matched) */ +- const HBUINT input[], /* Array of input values--start with second glyph */ +- unsigned int lookaheadCount, +- const HBUINT lookahead[], +- unsigned int lookupCount, +- const LookupRecord lookupRecord[], +- const ChainContextApplyLookupContext &lookup_context) ++static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, ++ unsigned int backtrackCount, ++ const HBUINT backtrack[], ++ unsigned int inputCount, /* Including the first glyph (not matched) */ ++ const HBUINT input[], /* Array of input values--start with second glyph */ ++ unsigned int lookaheadCount, ++ const HBUINT lookahead[], ++ unsigned int lookupCount, ++ const LookupRecord lookupRecord[], ++ 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; +@@ -3098,15 +3161,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, + 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], + match_end, &end_index))) + { + c->buffer->unsafe_to_concat (c->buffer->idx, end_index); +- ret = false; +- goto done; ++ return false; + } + + if (!match_backtrack (c, +@@ -3115,19 +3177,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, + &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; + } +@@ -3411,33 +3468,29 @@ struct ChainRuleSet + * + * Replicated from LigatureSet::apply(). */ + +- /* If the input skippy has non-auto joiners behavior (as in Indic shapers), +- * skip this fast path, as we don't distinguish between input & lookahead +- * matching in the fast path. ++ /* We use the iter_context instead of iter_input, to avoid skipping ++ * default-ignorables and such. + * +- * https://github.com/harfbuzz/harfbuzz/issues/4813 ++ * Related: https://github.com/harfbuzz/harfbuzz/issues/4813 + */ +- if (!c->auto_zwnj || !c->auto_zwj) +- goto slow; +- +- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; ++ auto &skippy_iter = c->iter_context; + skippy_iter.reset (c->buffer->idx); + skippy_iter.set_match_func (match_always, nullptr); + skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); +- unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; ++ unsigned unsafe_to = (unsigned) -1, unsafe_to1, unsafe_to2 = 0; + hb_glyph_info_t *first = nullptr, *second = nullptr; + bool matched = skippy_iter.next (); + if (likely (matched)) + { +- first = &c->buffer->info[skippy_iter.idx]; +- unsafe_to1 = skippy_iter.idx + 1; +- + if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) + { + /* Can't use the fast path if eg. the next char is a default-ignorable + * or other skippable. */ + goto slow; + } ++ ++ first = &c->buffer->info[skippy_iter.idx]; ++ unsafe_to1 = skippy_iter.idx + 1; + } + else + { +@@ -3458,8 +3511,15 @@ struct ChainRuleSet + ; + } + matched = skippy_iter.next (); +- if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) ++ if (likely (matched)) + { ++ if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) ++ { ++ /* Can't use the fast path if eg. the next char is a default-ignorable ++ * or other skippable. */ ++ goto slow; ++ } ++ + second = &c->buffer->info[skippy_iter.idx]; + unsafe_to2 = skippy_iter.idx + 1; + } +@@ -3475,7 +3535,7 @@ struct ChainRuleSet + const auto &input = StructAfter (r.backtrack); + const auto &lookahead = StructAfter (input); + +- unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u); ++ unsigned lenP1 = input.lenP1; + if (lenP1 > 1 ? + (!match_input || + match_input (*first, input.arrayZ[0], input_data)) +@@ -3483,6 +3543,7 @@ struct ChainRuleSet + (!lookahead.len || !match_lookahead || + match_lookahead (*first, lookahead.arrayZ[0], lookahead_data))) + { ++ lenP1 = hb_max (lenP1, 1u); + if (!second || + (lenP1 > 2 ? + (!match_input || +@@ -3505,6 +3566,18 @@ struct ChainRuleSet + { + if (unsafe_to == (unsigned) -1) + unsafe_to = unsafe_to1; ++ ++ if (lenP1 > 1) ++ { ++ // Skip ahead to next possible first glyph match. ++ for (; i + 1 < num_rules; i++) ++ { ++ const auto &r2 = this+rule.arrayZ[i + 1]; ++ const auto &input2 = StructAfter (r2.backtrack); ++ if (input2.lenP1 <= 1 || input2.arrayZ[0] != input.arrayZ[0]) ++ break; ++ } ++ } + } + } + if (likely (unsafe_to != (unsigned) -1)) +@@ -3873,45 +3946,37 @@ struct ChainContextFormat2_5 + + unsigned cache_cost () const + { +- return (this+lookaheadClassDef).cost () * ruleSet.len; ++ return (this+inputClassDef).cost () + (this+lookaheadClassDef).cost (); + } +- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) ++ static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) + { +- switch (op) ++ return context_cache_func (c, op); ++ } ++ ++ struct external_cache_t ++ { ++ hb_ot_layout_binary_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_lookup_cache_op_t::CREATE: +- return (void *) true; +- case hb_ot_lookup_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; +- 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; +- } +- case hb_ot_lookup_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; +- } +- case hb_ot_lookup_cache_op_t::DESTROY: +- return nullptr; ++ cache->coverage.clear (); + } +- return nullptr; ++ return cache; + } +- +- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } +- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } +- bool _apply (hb_ot_apply_context_t *c, bool cached) const ++ bool apply_cached (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, true, external_cache); } ++ bool apply (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, false, external_cache); } ++ bool _apply (hb_ot_apply_context_t *c, bool cached, void *external_cache) const + { + TRACE_APPLY (this); ++#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE ++ external_cache_t *cache = (external_cache_t *) external_cache; ++ unsigned int index = (this+coverage).get_coverage_binary (c->buffer->cur().codepoint, cache ? &cache->coverage : nullptr); ++#else + unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); ++#endif + if (index == NOT_COVERED) return_trace (false); + + const ClassDef &backtrack_class_def = this+backtrackClassDef; +@@ -3929,11 +3994,9 @@ struct ChainContextFormat2_5 + &lookahead_class_def} + }; + +- // Note: Corresponds to match_class_cached2 +- if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15) +- index = (c->buffer->cur().syllable () & 0xF0) >> 4; +- else +- index = input_class_def.get_class (c->buffer->cur().codepoint); ++ index = cached ++ ? get_class_cached2 (input_class_def, c->buffer->cur()) ++ : input_class_def.get_class (c->buffer->cur().codepoint); + const ChainRuleSet &rule_set = this+ruleSet[index]; + return_trace (rule_set.apply (c, lookup_context)); + } +@@ -4261,9 +4324,9 @@ struct ChainContext + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); +@@ -4277,7 +4340,7 @@ struct ChainContext + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + ChainContextFormat1_4 format1; + ChainContextFormat2_5 format2; + ChainContextFormat3 format3; +@@ -4352,7 +4415,7 @@ struct Extension + { + unsigned int get_type () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.get_type (); + default:return 0; + } +@@ -4360,7 +4423,7 @@ struct Extension + template + const X& get_subtable () const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.template get_subtable (); + default:return Null (typename T::SubTable); + } +@@ -4372,7 +4435,7 @@ struct Extension + template + typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const + { +- switch (u.format) { ++ switch (u.format.v) { + case 1: hb_barrier (); return u.format1.subset (c); + default: return c->default_return_value (); + } +@@ -4381,9 +4444,9 @@ struct Extension + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (u.format1.dispatch (c, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } +@@ -4391,7 +4454,7 @@ struct Extension + + protected: + union { +- HBUINT16 format; /* Format identifier */ ++ struct { HBUINT16 v; } format; /* Format identifier */ + ExtensionFormat1 format1; + } u; + }; +@@ -4428,22 +4491,14 @@ struct hb_ot_layout_lookup_accelerator_t + for (auto& subtable : hb_iter (thiz->subtables, count)) + thiz->digest.union_ (subtable.digest); + +-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- if (c_accelerate_subtables.cache_user_cost < 4) +- c_accelerate_subtables.cache_user_idx = (unsigned) -1; +- +- thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; ++ thiz->count = count; + +- if (thiz->cache_user_idx != (unsigned) -1) +- { +- thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE); +- if (!thiz->cache) +- thiz->cache_user_idx = (unsigned) -1; +- } ++#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE ++ thiz->subtable_cache_user_idx = c_accelerate_subtables.subtable_cache_user_idx; + + for (unsigned i = 0; i < count; i++) +- if (i != thiz->cache_user_idx) +- thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; ++ if (i != thiz->subtable_cache_user_idx) ++ thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; + #endif + + return thiz; +@@ -4452,11 +4507,8 @@ struct hb_ot_layout_lookup_accelerator_t + void fini () + { + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- if (cache) +- { +- assert (cache_user_idx != (unsigned) -1); +- subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY); +- } ++ for (unsigned i = 0; i < count; i++) ++ hb_free (subtables[i].external_cache); + #endif + } + +@@ -4466,14 +4518,14 @@ struct hb_ot_layout_lookup_accelerator_t + #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 + 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 + ; +@@ -4482,7 +4534,7 @@ struct hb_ot_layout_lookup_accelerator_t + #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 + ; +@@ -4493,8 +4545,8 @@ struct hb_ot_layout_lookup_accelerator_t + bool cache_enter (hb_ot_apply_context_t *c) const + { + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- return cache_user_idx != (unsigned) -1 && +- subtables[cache_user_idx].cache_enter (c); ++ return subtable_cache_user_idx != (unsigned) -1 && ++ subtables[subtable_cache_user_idx].cache_enter (c); + #else + return false; + #endif +@@ -4502,19 +4554,17 @@ struct hb_ot_layout_lookup_accelerator_t + void cache_leave (hb_ot_apply_context_t *c) const + { + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- subtables[cache_user_idx].cache_leave (c); ++ subtables[subtable_cache_user_idx].cache_leave (c); + #endif + } + + + hb_set_digest_t digest; +-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE +- public: +- void *cache = nullptr; + private: +- unsigned cache_user_idx = (unsigned) -1; ++ 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]; + }; + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc +index afe52963201..c73e4dc4b6d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc +@@ -343,7 +343,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, + * @face: The #hb_face_t to work on + * @glyph: The #hb_codepoint_t code point to query + * @start_offset: offset of the first attachment point to retrieve +- * @point_count: (inout) (optional): Input = the maximum number of attachment points to return; ++ * @point_count: (inout) (nullable): Input = the maximum number of attachment points to return; + * Output = the actual number of attachment points returned (may be zero) + * @point_array: (out) (array length=point_count): The array of attachment points found for the query + * +@@ -373,7 +373,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, + * @direction: The #hb_direction_t text direction to use + * @glyph: The #hb_codepoint_t code point to query + * @start_offset: offset of the first caret position to retrieve +- * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return; ++ * @caret_count: (inout) (nullable): Input = the maximum number of caret positions to return; + * Output = the actual number of caret positions returned (may be zero) + * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query + * +@@ -444,7 +444,7 @@ get_gsubgpos_table (hb_face_t *face, + * @face: #hb_face_t to work upon + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS + * @start_offset: offset of the first script tag to retrieve +- * @script_count: (inout) (optional): Input = the maximum number of script tags to return; ++ * @script_count: (inout) (nullable): Input = the maximum number of script tags to return; + * Output = the actual number of script tags returned (may be zero) + * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query + * +@@ -541,8 +541,8 @@ hb_ot_layout_table_choose_script (hb_face_t *face, + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS + * @script_count: Number of script tags in the array + * @script_tags: Array of #hb_tag_t script tags +- * @script_index: (out) (optional): The index of the requested script +- * @chosen_script: (out) (optional): #hb_tag_t of the requested script ++ * @script_index: (out) (nullable): The index of the requested script ++ * @chosen_script: (out) (nullable): #hb_tag_t of the requested script + * + * Selects an OpenType script for @table_tag from the @script_tags array. + * +@@ -613,7 +613,7 @@ hb_ot_layout_table_select_script (hb_face_t *face, + * @face: #hb_face_t to work upon + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS + * @start_offset: offset of the first feature tag to retrieve +- * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; ++ * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; + * Output = the actual number of feature tags returned (may be zero) + * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table + * +@@ -683,7 +683,7 @@ hb_ot_layout_table_find_feature (hb_face_t *face, + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS + * @script_index: The index of the requested script tag + * @start_offset: offset of the first language tag to retrieve +- * @language_count: (inout) (optional): Input = the maximum number of language tags to return; ++ * @language_count: (inout) (nullable): Input = the maximum number of language tags to return; + * Output = the actual number of language tags returned (may be zero) + * @language_tags: (out) (array length=language_count): Array of language tags found in the table + * +@@ -911,7 +911,7 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, + * @script_index: The index of the requested script tag + * @language_index: The index of the requested language tag + * @start_offset: offset of the first feature tag to retrieve +- * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; ++ * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; + * Output: the actual number of feature tags returned (may be zero) + * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query + * +@@ -947,7 +947,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, + * @script_index: The index of the requested script tag + * @language_index: The index of the requested language tag + * @start_offset: offset of the first feature tag to retrieve +- * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; ++ * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; + * Output = the actual number of feature tags returned (may be zero) + * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query + * +@@ -1035,7 +1035,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face, + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS + * @feature_index: The index of the requested feature + * @start_offset: offset of the first lookup to retrieve +- * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; ++ * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; + * Output = the actual number of lookups returned (may be zero) + * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query + * +@@ -1386,10 +1386,10 @@ hb_ot_layout_collect_lookups (hb_face_t *face, + * @face: #hb_face_t to work upon + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS + * @lookup_index: The index of the feature lookup to query +- * @glyphs_before: (out): Array of glyphs preceding the substitution range +- * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup +- * @glyphs_after: (out): Array of glyphs following the substitution range +- * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup ++ * @glyphs_before: (out) (nullable): Array of glyphs preceding the substitution range ++ * @glyphs_input: (out) (nullable): Array of input glyphs that would be substituted by the lookup ++ * @glyphs_after: (out) (nullable): Array of glyphs following the substitution range ++ * @glyphs_output: (out) (nullable): Array of glyphs that would be the substituted output of the lookup + * + * Fetches a list of all glyphs affected by the specified lookup in the + * specified face's GSUB table or GPOS table. +@@ -1473,7 +1473,7 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, + * @feature_index: The index of the feature to query + * @variations_index: The index of the feature variation to query + * @start_offset: offset of the first lookup to retrieve +- * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; ++ * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; + * Output = the actual number of lookups returned (may be zero) + * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query + * +@@ -1777,15 +1777,15 @@ hb_ot_layout_get_size_params (hb_face_t *face, + * @face: #hb_face_t to work upon + * @table_tag: table tag to query, "GSUB" or "GPOS". + * @feature_index: index of feature to query. +- * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string +- * for a user-interface label for this feature. (May be NULL.) +- * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string ++ * @label_id: (out) (nullable): The ‘name’ table name ID that specifies a string ++ * for a user-interface label for this feature. ++ * @tooltip_id: (out) (nullable): The ‘name’ table name ID that specifies a string + * that an application can use for tooltip text for this +- * feature. (May be NULL.) +- * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text +- * that illustrates the effect of this feature. (May be NULL.) +- * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.) +- * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify ++ * feature. ++ * @sample_id: (out) (nullable): The ‘name’ table name ID that specifies sample text ++ * that illustrates the effect of this feature. ++ * @num_named_parameters: (out) (nullable): Number of named parameters. ++ * @first_param_id: (out) (nullable): The first ‘name’ table name ID used to specify + * strings for user-interface labels for the feature + * parameters. (Must be zero if numParameters is zero.) + * +@@ -1852,7 +1852,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, + * @table_tag: table tag to query, "GSUB" or "GPOS". + * @feature_index: index of feature to query. + * @start_offset: offset of the first character to retrieve +- * @char_count: (inout) (optional): Input = the maximum number of characters to return; ++ * @char_count: (inout) (nullable): Input = the maximum number of characters to return; + * Output = the actual number of characters returned (may be zero) + * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. + * The Unicode codepoints of the characters for which this feature provides +@@ -1915,31 +1915,33 @@ struct GPOSProxy + + 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_cache = accel.cache_enter (c); ++ bool use_hot_subtable_cache = accel.cache_enter (c); + + bool ret = false; + hb_buffer_t *buffer = c->buffer; +- while (buffer->idx < buffer->len && buffer->successful) ++ while (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_cache); +- } ++ hb_glyph_info_t *info = buffer->info; ++ unsigned j = buffer->idx; ++ while (j < buffer->len && ++ !(accel.digest.may_have (info[j].codepoint) && ++ (info[j].mask & c->lookup_mask) && ++ c->check_glyph_property (&info[j], c->lookup_props))) ++ j++; ++ if (unlikely (j > buffer->idx && !buffer->next_glyphs (j - buffer->idx))) ++ break; ++ if (buffer->idx >= buffer->len) ++ break; + +- if (applied) ++ if (accel.apply (c, use_hot_subtable_cache)) + ret = true; + else + (void) buffer->next_glyph (); + } + +- if (use_cache) ++ if (use_hot_subtable_cache) + accel.cache_leave (c); + + return ret; +@@ -1947,8 +1949,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, + + 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 +1959,10 @@ apply_backward (OT::hb_ot_apply_context_t *c, + 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; +@@ -1975,7 +1975,6 @@ apply_string (OT::hb_ot_apply_context_t *c, + const OT::hb_ot_layout_lookup_accelerator_t &accel) + { + hb_buffer_t *buffer = c->buffer; +- unsigned subtable_count = lookup.get_subtable_count (); + + if (unlikely (!buffer->len || !c->lookup_mask)) + return false; +@@ -1991,7 +1990,7 @@ apply_string (OT::hb_ot_apply_context_t *c, + buffer->clear_output (); + + buffer->idx = 0; +- ret = apply_forward (c, accel, subtable_count); ++ ret = apply_forward (c, accel); + + if (!Proxy::always_inplace) + buffer->sync (); +@@ -2001,7 +2000,7 @@ apply_string (OT::hb_ot_apply_context_t *c, + /* 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; +@@ -2017,7 +2016,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, + unsigned int i = 0; + + auto *font_data = font->data.ot.get (); +- auto *var_store_cache = font_data == HB_SHAPER_DATA_SUCCEEDED ? nullptr : (OT::ItemVariationStore::cache_t *) font_data; ++ auto *var_store_cache = (OT::hb_scalar_cache_t *) font_data; + + OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob (), var_store_cache); + c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func); +@@ -2037,11 +2036,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, + if (buffer->messaging () && + !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue; + +- /* c.digest is a digest of all the current glyphs in the buffer +- * (plus some past glyphs). +- * +- * Only try applying the lookup if there is any overlap. */ +- if (accel->digest.may_intersect (c.digest)) ++ /* Only try applying the lookup if there is any overlap. */ ++ if (accel->digest.may_intersect (buffer->digest)) + { + c.set_lookup_index (lookup_index); + c.set_lookup_mask (lookup.mask, false); +@@ -2067,7 +2063,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, + if (stage->pause_func (plan, font, buffer)) + { + /* Refresh working buffer digest since buffer changed. */ +- buffer->collect_codepoints (c.digest); ++ buffer->update_digest (); + } + } + } +@@ -2601,6 +2597,7 @@ hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font, + #endif + + ++#ifndef HB_NO_LAYOUT_RARELY_USED + struct hb_get_glyph_alternates_dispatch_t : + hb_dispatch_context_t + { +@@ -2620,14 +2617,13 @@ struct hb_get_glyph_alternates_dispatch_t : + ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) + }; + +-#ifndef HB_NO_LAYOUT_RARELY_USED + /** + * hb_ot_layout_lookup_get_glyph_alternates: + * @face: a face. + * @lookup_index: index of the feature lookup to query. + * @glyph: a glyph id. + * @start_offset: starting offset. +- * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return; ++ * @alternate_count: (inout) (nullable): Input = the maximum number of alternate glyphs to return; + * Output = the actual number of alternate glyphs returned (may be zero). + * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. + * Alternate glyphs associated with the glyph id. +@@ -2654,6 +2650,64 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, + return ret; + } + ++struct hb_collect_glyph_alternates_dispatch_t : ++ hb_dispatch_context_t ++{ ++ static return_t default_return_value () { return false; } ++ bool stop_sublookup_iteration (return_t r) const { return false; } ++ ++ private: ++ template auto ++ _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN ++ ( (obj.collect_glyph_alternates (std::forward (ds)...), true) ) ++ template auto ++ _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN ++ ( default_return_value () ) ++ public: ++ template auto ++ dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN ++ ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) ++}; ++ ++/** ++ * hb_ot_layout_lookup_collect_glyph_alternates: ++ * @face: a face. ++ * @lookup_index: index of the feature lookup to query. ++ * @alternate_count: (inout): mapping from glyph index to number of alternates for that glyph. ++ * @alternate_glyphs: (inout): mapping from encoded glyph index and alternate index, to alternate glyph ids. ++ * ++ * Collects alternates of glyphs from a given GSUB lookup index. ++ * ++ * For one-to-one GSUB glyph substitutions, this function collects the ++ * substituted glyph. ++ * ++ * For lookups that assign multiple alternates to a glyph, all alternate glyphs are collected. ++ * ++ * For other lookup types, nothing is performed and `false` is returned. ++ * ++ * The `alternate_count` mapping will contain the number of alternates for each glyph id. ++ * Upon entry, this mapping should contain the glyph ids as keys, and the number of alternates ++ * currently known for each glyph id as values. ++ * ++ * The `alternate_glyphs` mapping will contain the alternate glyph ids for each glyph id. ++ * The mapping is encoded in the following way, upon entry and after processing: ++ * If G is the glyph id, and A0, A1, ..., A(n-1) are the alternate glyph ids, ++ * the mapping will contain the following entries: (G + (i << 24)) -> A(i) ++ * for i = 0, 1, ..., n-1 where n is the number of alternates for G as per `alternate_count`. ++ * ++ * Return value: `true` if alternates were collected, `false` otherwise. ++ * Since: 12.1.0 ++ */ ++HB_EXTERN hb_bool_t ++hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, ++ unsigned lookup_index, ++ hb_map_t *alternate_count /* IN/OUT */, ++ hb_map_t *alternate_glyphs /* IN/OUT */) ++{ ++ hb_collect_glyph_alternates_dispatch_t c; ++ const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); ++ return lookup.dispatch (&c, alternate_count, alternate_glyphs); ++} + + struct hb_position_single_dispatch_t : + hb_dispatch_context_t +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h +index 1d9db1105bd..b814c2acda3 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h +@@ -383,6 +383,12 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, + unsigned *alternate_count /* IN/OUT */, + hb_codepoint_t *alternate_glyphs /* OUT */); + ++HB_EXTERN hb_bool_t ++hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, ++ unsigned lookup_index, ++ hb_map_t *alternate_count /* IN/OUT */, ++ hb_map_t *alternate_glyphs /* IN/OUT */); ++ + HB_EXTERN hb_bool_t + hb_ot_layout_lookup_would_substitute (hb_face_t *face, + unsigned int lookup_index, +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh +index a68c8421e4c..f669ac7c46d 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh +@@ -217,8 +217,6 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) + + if (u >= 0x80u) + { +- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; +- + if (unlikely (unicode->is_default_ignorable (u))) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; +@@ -247,6 +245,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) + + if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) + { ++ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; + props |= UPROPS_MASK_CONTINUATION; + props |= unicode->modified_combining_class (u)<<8; + } +@@ -361,8 +360,9 @@ _hb_glyph_info_unhide (hb_glyph_info_t *info) + } + + static inline void +-_hb_glyph_info_set_continuation (hb_glyph_info_t *info) ++_hb_glyph_info_set_continuation (hb_glyph_info_t *info, hb_buffer_t *buffer) + { ++ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; + info->unicode_props() |= UPROPS_MASK_CONTINUATION; + } + static inline void +@@ -410,18 +410,6 @@ _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); + } + static inline bool +-_hb_glyph_info_is_joiner (const hb_glyph_info_t *info) +-{ +- return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); +-} +-static inline void +-_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) +-{ +- if (!_hb_glyph_info_is_unicode_format (info)) +- return; +- info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; +-} +-static inline bool + _hb_glyph_info_is_aat_deleted (const hb_glyph_info_t *info) + { + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_AAT_DELETED); +@@ -657,4 +645,18 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) + #undef lig_props + #undef glyph_props + ++static inline void ++_hb_collect_glyph_alternates_add (hb_codepoint_t from, ++ hb_codepoint_t to, ++ hb_map_t *alternate_count, ++ hb_map_t *alternate_glyphs) ++{ ++ hb_codepoint_t zero = 0; ++ hb_codepoint_t *i = &zero; ++ alternate_count->has (from, &i); ++ alternate_glyphs->set (from | (*i << 24), to); ++ alternate_count->set (from, *i + 1); ++} ++ ++ + #endif /* HB_OT_LAYOUT_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh +index b33e01fd6c9..ad9d7cb03e8 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh +@@ -69,6 +69,8 @@ struct MathValueRecord + + struct MathConstants + { ++ friend struct MATH; ++ + MathConstants* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); +@@ -1109,8 +1111,8 @@ struct MATH + { + #ifndef HB_NO_MATH + switch HB_CODEPOINT_ENCODE3 (font->face->table.MATH.get_blob ()->length, +- get_constant (HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT, font), +- get_constant (HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT, font)) ++ (this+mathConstants).minHeight[1], // displayOperatorMinHeight ++ (this+mathConstants).minHeight[0]) // delimitedSubFormulaMinHeight + { + /* sha1sum:ab4a4fe054d23061f3c039493d6f665cfda2ecf5 cambria.ttc + * sha1sum:086855301bff644f9d8827b88491fcf73a6d4cb9 cambria.ttc +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh +index b4df8aaeeab..269b4d3fe45 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-macroman.hh +@@ -31,264 +31,264 @@ + #endif + + +-_S(".notdef") +-_S(".null") +-_S("nonmarkingreturn") +-_S("space") +-_S("exclam") +-_S("quotedbl") +-_S("numbersign") +-_S("dollar") +-_S("percent") +-_S("ampersand") +-_S("quotesingle") +-_S("parenleft") +-_S("parenright") +-_S("asterisk") +-_S("plus") +-_S("comma") +-_S("hyphen") +-_S("period") +-_S("slash") +-_S("zero") +-_S("one") +-_S("two") +-_S("three") +-_S("four") +-_S("five") +-_S("six") +-_S("seven") +-_S("eight") +-_S("nine") +-_S("colon") +-_S("semicolon") +-_S("less") +-_S("equal") +-_S("greater") +-_S("question") +-_S("at") +-_S("A") +-_S("B") +-_S("C") +-_S("D") +-_S("E") +-_S("F") +-_S("G") +-_S("H") +-_S("I") +-_S("J") +-_S("K") +-_S("L") +-_S("M") +-_S("N") +-_S("O") +-_S("P") +-_S("Q") +-_S("R") +-_S("S") +-_S("T") +-_S("U") +-_S("V") +-_S("W") +-_S("X") +-_S("Y") +-_S("Z") +-_S("bracketleft") +-_S("backslash") +-_S("bracketright") +-_S("asciicircum") +-_S("underscore") +-_S("grave") +-_S("a") +-_S("b") +-_S("c") +-_S("d") +-_S("e") +-_S("f") +-_S("g") +-_S("h") +-_S("i") +-_S("j") +-_S("k") +-_S("l") +-_S("m") +-_S("n") +-_S("o") +-_S("p") +-_S("q") +-_S("r") +-_S("s") +-_S("t") +-_S("u") +-_S("v") +-_S("w") +-_S("x") +-_S("y") +-_S("z") +-_S("braceleft") +-_S("bar") +-_S("braceright") +-_S("asciitilde") +-_S("Adieresis") +-_S("Aring") +-_S("Ccedilla") +-_S("Eacute") +-_S("Ntilde") +-_S("Odieresis") +-_S("Udieresis") +-_S("aacute") +-_S("agrave") +-_S("acircumflex") +-_S("adieresis") +-_S("atilde") +-_S("aring") +-_S("ccedilla") +-_S("eacute") +-_S("egrave") +-_S("ecircumflex") +-_S("edieresis") +-_S("iacute") +-_S("igrave") +-_S("icircumflex") +-_S("idieresis") +-_S("ntilde") +-_S("oacute") +-_S("ograve") +-_S("ocircumflex") +-_S("odieresis") +-_S("otilde") +-_S("uacute") +-_S("ugrave") +-_S("ucircumflex") +-_S("udieresis") +-_S("dagger") +-_S("degree") +-_S("cent") +-_S("sterling") +-_S("section") +-_S("bullet") +-_S("paragraph") +-_S("germandbls") +-_S("registered") +-_S("copyright") +-_S("trademark") +-_S("acute") +-_S("dieresis") +-_S("notequal") +-_S("AE") +-_S("Oslash") +-_S("infinity") +-_S("plusminus") +-_S("lessequal") +-_S("greaterequal") +-_S("yen") +-_S("mu") +-_S("partialdiff") +-_S("summation") +-_S("product") +-_S("pi") +-_S("integral") +-_S("ordfeminine") +-_S("ordmasculine") +-_S("Omega") +-_S("ae") +-_S("oslash") +-_S("questiondown") +-_S("exclamdown") +-_S("logicalnot") +-_S("radical") +-_S("florin") +-_S("approxequal") +-_S("Delta") +-_S("guillemotleft") +-_S("guillemotright") +-_S("ellipsis") +-_S("nonbreakingspace") +-_S("Agrave") +-_S("Atilde") +-_S("Otilde") +-_S("OE") +-_S("oe") +-_S("endash") +-_S("emdash") +-_S("quotedblleft") +-_S("quotedblright") +-_S("quoteleft") +-_S("quoteright") +-_S("divide") +-_S("lozenge") +-_S("ydieresis") +-_S("Ydieresis") +-_S("fraction") +-_S("currency") +-_S("guilsinglleft") +-_S("guilsinglright") +-_S("fi") +-_S("fl") +-_S("daggerdbl") +-_S("periodcentered") +-_S("quotesinglbase") +-_S("quotedblbase") +-_S("perthousand") +-_S("Acircumflex") +-_S("Ecircumflex") +-_S("Aacute") +-_S("Edieresis") +-_S("Egrave") +-_S("Iacute") +-_S("Icircumflex") +-_S("Idieresis") +-_S("Igrave") +-_S("Oacute") +-_S("Ocircumflex") +-_S("apple") +-_S("Ograve") +-_S("Uacute") +-_S("Ucircumflex") +-_S("Ugrave") +-_S("dotlessi") +-_S("circumflex") +-_S("tilde") +-_S("macron") +-_S("breve") +-_S("dotaccent") +-_S("ring") +-_S("cedilla") +-_S("hungarumlaut") +-_S("ogonek") +-_S("caron") +-_S("Lslash") +-_S("lslash") +-_S("Scaron") +-_S("scaron") +-_S("Zcaron") +-_S("zcaron") +-_S("brokenbar") +-_S("Eth") +-_S("eth") +-_S("Yacute") +-_S("yacute") +-_S("Thorn") +-_S("thorn") +-_S("minus") +-_S("multiply") +-_S("onesuperior") +-_S("twosuperior") +-_S("threesuperior") +-_S("onehalf") +-_S("onequarter") +-_S("threequarters") +-_S("franc") +-_S("Gbreve") +-_S("gbreve") +-_S("Idotaccent") +-_S("Scedilla") +-_S("scedilla") +-_S("Cacute") +-_S("cacute") +-_S("Ccaron") +-_S("ccaron") +-_S("dcroat") ++HB_STR(".notdef") ++HB_STR(".null") ++HB_STR("nonmarkingreturn") ++HB_STR("space") ++HB_STR("exclam") ++HB_STR("quotedbl") ++HB_STR("numbersign") ++HB_STR("dollar") ++HB_STR("percent") ++HB_STR("ampersand") ++HB_STR("quotesingle") ++HB_STR("parenleft") ++HB_STR("parenright") ++HB_STR("asterisk") ++HB_STR("plus") ++HB_STR("comma") ++HB_STR("hyphen") ++HB_STR("period") ++HB_STR("slash") ++HB_STR("zero") ++HB_STR("one") ++HB_STR("two") ++HB_STR("three") ++HB_STR("four") ++HB_STR("five") ++HB_STR("six") ++HB_STR("seven") ++HB_STR("eight") ++HB_STR("nine") ++HB_STR("colon") ++HB_STR("semicolon") ++HB_STR("less") ++HB_STR("equal") ++HB_STR("greater") ++HB_STR("question") ++HB_STR("at") ++HB_STR("A") ++HB_STR("B") ++HB_STR("C") ++HB_STR("D") ++HB_STR("E") ++HB_STR("F") ++HB_STR("G") ++HB_STR("H") ++HB_STR("I") ++HB_STR("J") ++HB_STR("K") ++HB_STR("L") ++HB_STR("M") ++HB_STR("N") ++HB_STR("O") ++HB_STR("P") ++HB_STR("Q") ++HB_STR("R") ++HB_STR("S") ++HB_STR("T") ++HB_STR("U") ++HB_STR("V") ++HB_STR("W") ++HB_STR("X") ++HB_STR("Y") ++HB_STR("Z") ++HB_STR("bracketleft") ++HB_STR("backslash") ++HB_STR("bracketright") ++HB_STR("asciicircum") ++HB_STR("underscore") ++HB_STR("grave") ++HB_STR("a") ++HB_STR("b") ++HB_STR("c") ++HB_STR("d") ++HB_STR("e") ++HB_STR("f") ++HB_STR("g") ++HB_STR("h") ++HB_STR("i") ++HB_STR("j") ++HB_STR("k") ++HB_STR("l") ++HB_STR("m") ++HB_STR("n") ++HB_STR("o") ++HB_STR("p") ++HB_STR("q") ++HB_STR("r") ++HB_STR("s") ++HB_STR("t") ++HB_STR("u") ++HB_STR("v") ++HB_STR("w") ++HB_STR("x") ++HB_STR("y") ++HB_STR("z") ++HB_STR("braceleft") ++HB_STR("bar") ++HB_STR("braceright") ++HB_STR("asciitilde") ++HB_STR("Adieresis") ++HB_STR("Aring") ++HB_STR("Ccedilla") ++HB_STR("Eacute") ++HB_STR("Ntilde") ++HB_STR("Odieresis") ++HB_STR("Udieresis") ++HB_STR("aacute") ++HB_STR("agrave") ++HB_STR("acircumflex") ++HB_STR("adieresis") ++HB_STR("atilde") ++HB_STR("aring") ++HB_STR("ccedilla") ++HB_STR("eacute") ++HB_STR("egrave") ++HB_STR("ecircumflex") ++HB_STR("edieresis") ++HB_STR("iacute") ++HB_STR("igrave") ++HB_STR("icircumflex") ++HB_STR("idieresis") ++HB_STR("ntilde") ++HB_STR("oacute") ++HB_STR("ograve") ++HB_STR("ocircumflex") ++HB_STR("odieresis") ++HB_STR("otilde") ++HB_STR("uacute") ++HB_STR("ugrave") ++HB_STR("ucircumflex") ++HB_STR("udieresis") ++HB_STR("dagger") ++HB_STR("degree") ++HB_STR("cent") ++HB_STR("sterling") ++HB_STR("section") ++HB_STR("bullet") ++HB_STR("paragraph") ++HB_STR("germandbls") ++HB_STR("registered") ++HB_STR("copyright") ++HB_STR("trademark") ++HB_STR("acute") ++HB_STR("dieresis") ++HB_STR("notequal") ++HB_STR("AE") ++HB_STR("Oslash") ++HB_STR("infinity") ++HB_STR("plusminus") ++HB_STR("lessequal") ++HB_STR("greaterequal") ++HB_STR("yen") ++HB_STR("mu") ++HB_STR("partialdiff") ++HB_STR("summation") ++HB_STR("product") ++HB_STR("pi") ++HB_STR("integral") ++HB_STR("ordfeminine") ++HB_STR("ordmasculine") ++HB_STR("Omega") ++HB_STR("ae") ++HB_STR("oslash") ++HB_STR("questiondown") ++HB_STR("exclamdown") ++HB_STR("logicalnot") ++HB_STR("radical") ++HB_STR("florin") ++HB_STR("approxequal") ++HB_STR("Delta") ++HB_STR("guillemotleft") ++HB_STR("guillemotright") ++HB_STR("ellipsis") ++HB_STR("nonbreakingspace") ++HB_STR("Agrave") ++HB_STR("Atilde") ++HB_STR("Otilde") ++HB_STR("OE") ++HB_STR("oe") ++HB_STR("endash") ++HB_STR("emdash") ++HB_STR("quotedblleft") ++HB_STR("quotedblright") ++HB_STR("quoteleft") ++HB_STR("quoteright") ++HB_STR("divide") ++HB_STR("lozenge") ++HB_STR("ydieresis") ++HB_STR("Ydieresis") ++HB_STR("fraction") ++HB_STR("currency") ++HB_STR("guilsinglleft") ++HB_STR("guilsinglright") ++HB_STR("fi") ++HB_STR("fl") ++HB_STR("daggerdbl") ++HB_STR("periodcentered") ++HB_STR("quotesinglbase") ++HB_STR("quotedblbase") ++HB_STR("perthousand") ++HB_STR("Acircumflex") ++HB_STR("Ecircumflex") ++HB_STR("Aacute") ++HB_STR("Edieresis") ++HB_STR("Egrave") ++HB_STR("Iacute") ++HB_STR("Icircumflex") ++HB_STR("Idieresis") ++HB_STR("Igrave") ++HB_STR("Oacute") ++HB_STR("Ocircumflex") ++HB_STR("apple") ++HB_STR("Ograve") ++HB_STR("Uacute") ++HB_STR("Ucircumflex") ++HB_STR("Ugrave") ++HB_STR("dotlessi") ++HB_STR("circumflex") ++HB_STR("tilde") ++HB_STR("macron") ++HB_STR("breve") ++HB_STR("dotaccent") ++HB_STR("ring") ++HB_STR("cedilla") ++HB_STR("hungarumlaut") ++HB_STR("ogonek") ++HB_STR("caron") ++HB_STR("Lslash") ++HB_STR("lslash") ++HB_STR("Scaron") ++HB_STR("scaron") ++HB_STR("Zcaron") ++HB_STR("zcaron") ++HB_STR("brokenbar") ++HB_STR("Eth") ++HB_STR("eth") ++HB_STR("Yacute") ++HB_STR("yacute") ++HB_STR("Thorn") ++HB_STR("thorn") ++HB_STR("minus") ++HB_STR("multiply") ++HB_STR("onesuperior") ++HB_STR("twosuperior") ++HB_STR("threesuperior") ++HB_STR("onehalf") ++HB_STR("onequarter") ++HB_STR("threequarters") ++HB_STR("franc") ++HB_STR("Gbreve") ++HB_STR("gbreve") ++HB_STR("Idotaccent") ++HB_STR("Scedilla") ++HB_STR("scedilla") ++HB_STR("Cacute") ++HB_STR("cacute") ++HB_STR("Ccaron") ++HB_STR("ccaron") ++HB_STR("dcroat") + + + #endif /* HB_OT_POST_MACROMAN_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc +index 2401e18f0e6..c17e7628975 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc +@@ -409,16 +409,13 @@ position_around_base (const hb_ot_shape_plan_t *plan, + } + + static inline void +-position_cluster (const hb_ot_shape_plan_t *plan, +- hb_font_t *font, +- hb_buffer_t *buffer, +- unsigned int start, +- unsigned int end, +- bool adjust_offsets_when_zeroing) ++position_cluster_impl (const hb_ot_shape_plan_t *plan, ++ hb_font_t *font, ++ hb_buffer_t *buffer, ++ unsigned int start, ++ unsigned int end, ++ bool adjust_offsets_when_zeroing) + { +- if (end - start < 2) +- return; +- + /* Find the base glyph */ + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = start; i < end; i++) +@@ -441,6 +438,20 @@ position_cluster (const hb_ot_shape_plan_t *plan, + } + } + ++static HB_ALWAYS_INLINE void ++position_cluster (const hb_ot_shape_plan_t *plan, ++ hb_font_t *font, ++ hb_buffer_t *buffer, ++ unsigned int start, ++ unsigned int end, ++ bool adjust_offsets_when_zeroing) ++{ ++ if (end - start < 2) ++ return; ++ ++ position_cluster_impl (plan, font, buffer, start, end, adjust_offsets_when_zeroing); ++} ++ + void + _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, + hb_font_t *font, +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc +index cb941bc7fbd..508ed6a5076 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc +@@ -78,14 +78,14 @@ + static inline void + set_glyph (hb_glyph_info_t &info, hb_font_t *font) + { +- (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index()); ++ (void) font->get_nominal_glyph (info.codepoint, &info.normalizer_glyph_index()); + } + + static inline void + output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) + { + /* This is very confusing indeed. */ +- buffer->cur().glyph_index() = glyph; ++ buffer->cur().normalizer_glyph_index() = glyph; + (void) buffer->output_glyph (unichar); + _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); + } +@@ -93,7 +93,7 @@ output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) + static inline void + next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) + { +- buffer->cur().glyph_index() = glyph; ++ buffer->cur().normalizer_glyph_index() = glyph; + (void) buffer->next_glyph (); + } + +@@ -210,7 +210,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, + hb_font_t * const font = c->font; + for (; buffer->idx < end - 1 && buffer->successful;) { + if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { +- if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) ++ if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().normalizer_glyph_index())) + { + hb_codepoint_t unicode = buffer->cur().codepoint; + (void) buffer->replace_glyphs (2, 1, &unicode); +@@ -342,7 +342,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, + unsigned int done = font->get_nominal_glyphs (end - buffer->idx, + &buffer->cur().codepoint, + sizeof (buffer->info[0]), +- &buffer->cur().glyph_index(), ++ &buffer->cur().normalizer_glyph_index(), + sizeof (buffer->info[0])); + if (unlikely (!buffer->next_glyphs (done))) break; + } +@@ -456,7 +456,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, + buffer->out_len--; /* Remove the second composable. */ + /* Modify starter and carry on. */ + buffer->out_info[starter].codepoint = composed; +- buffer->out_info[starter].glyph_index() = glyph; ++ buffer->out_info[starter].normalizer_glyph_index() = glyph; + _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); + + continue; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh +index 9f17bdbb243..138e895e8e1 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh +@@ -32,7 +32,7 @@ + + + /* buffer var allocations, used during the normalization process */ +-#define glyph_index() var1.u32 ++#define normalizer_glyph_index() var1.u32 + + struct hb_ot_shape_plan_t; + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc +index 477a7c7fc72..69b188f7aa3 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc +@@ -44,6 +44,7 @@ + #include "hb-ot-face.hh" + + #include "hb-set.hh" ++#include "hb-unicode.hh" + + #include "hb-aat-layout.hh" + #include "hb-ot-layout-gdef-table.hh" +@@ -92,7 +93,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac + shaper = hb_ot_shaper_categorize (props.script, props.direction, map.chosen_script[0]); + + script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; +- script_fallback_mark_positioning = shaper->fallback_position; ++ script_fallback_position = shaper->fallback_position; + + #ifndef HB_NO_AAT_SHAPE + /* https://github.com/harfbuzz/harfbuzz/issues/1528 */ +@@ -178,12 +179,12 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, + #endif + #ifndef HB_NO_OT_KERN + else if (hb_ot_layout_has_kerning (face)) +- plan.apply_kern = true; ++ plan.apply_kern = script_fallback_position; // Not all shapers apply legacy `kern` + #endif + else {} + } + +- plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); ++ plan.apply_fallback_kern = script_fallback_position && !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); + + plan.zero_marks = script_zero_marks && + !plan.apply_kerx && +@@ -203,7 +204,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, + ); + + plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing && +- script_fallback_mark_positioning; ++ script_fallback_position; + + #ifndef HB_NO_AAT_SHAPE + /* If we're using morx shaping, we cancel mark position adjustment because +@@ -425,25 +426,20 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) + */ + + struct hb_ot_font_data_t { +- OT::ItemVariationStore::cache_t unused; // Just for alignment ++ OT::hb_scalar_cache_t unused; // Just for alignment + }; + + hb_ot_font_data_t * + _hb_ot_shaper_font_data_create (hb_font_t *font) + { +- if (!font->num_coords) +- return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; +- + const OT::ItemVariationStore &var_store = font->face->table.GDEF->table->get_var_store (); +- auto *cache = (hb_ot_font_data_t *) var_store.create_cache (); +- return cache ? cache : (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; ++ return (hb_ot_font_data_t *) var_store.create_cache (); + } + + void + _hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data) + { +- if (data == HB_SHAPER_DATA_SUCCEEDED) return; +- OT::ItemVariationStore::destroy_cache ((OT::ItemVariationStore::cache_t *) data); ++ OT::ItemVariationStore::destroy_cache ((OT::hb_scalar_cache_t *) data); + } + + +@@ -488,6 +484,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) + { + _hb_glyph_info_set_unicode_props (&info[i], buffer); + ++ if (info[i].codepoint < 0x80) ++ continue; ++ + unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]); + if (FLAG_UNSAFE (gen_cat) & + (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | +@@ -502,7 +501,7 @@ hb_set_unicode_props (hb_buffer_t *buffer) + if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && + hb_in_range (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) + { +- _hb_glyph_info_set_continuation (&info[i]); ++ _hb_glyph_info_set_continuation (&info[i], buffer); + } + /* Regional_Indicators are hairy as hell... + * https://github.com/harfbuzz/harfbuzz/issues/2265 */ +@@ -510,18 +509,18 @@ hb_set_unicode_props (hb_buffer_t *buffer) + { + if (_hb_codepoint_is_regional_indicator (info[i - 1].codepoint) && + !_hb_glyph_info_is_continuation (&info[i - 1])) +- _hb_glyph_info_set_continuation (&info[i]); ++ _hb_glyph_info_set_continuation (&info[i], buffer); + } + #ifndef HB_NO_EMOJI_SEQUENCES + else if (unlikely (_hb_glyph_info_is_zwj (&info[i]))) + { +- _hb_glyph_info_set_continuation (&info[i]); ++ _hb_glyph_info_set_continuation (&info[i], buffer); + if (i + 1 < count && + _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint)) + { + i++; + _hb_glyph_info_set_unicode_props (&info[i], buffer); +- _hb_glyph_info_set_continuation (&info[i]); ++ _hb_glyph_info_set_continuation (&info[i], buffer); + } + } + #endif +@@ -540,7 +539,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) + * https://github.com/harfbuzz/harfbuzz/issues/3844 + */ + else if (unlikely (hb_in_ranges (info[i].codepoint, 0xFF9Eu, 0xFF9Fu, 0xE0020u, 0xE007Fu))) +- _hb_glyph_info_set_continuation (&info[i]); ++ _hb_glyph_info_set_continuation (&info[i], buffer); ++ else if (unlikely (info[i].codepoint == 0x2044u /* FRACTION SLASH */)) ++ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH; + } + } + +@@ -576,7 +577,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) + static void + hb_form_clusters (hb_buffer_t *buffer) + { +- if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) ++ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS)) + return; + + if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) +@@ -618,14 +619,14 @@ hb_ensure_native_direction (hb_buffer_t *buffer) + for (unsigned i = 0; i < count; i++) + { + auto gc = _hb_glyph_info_get_general_category (&info[i]); +- if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) +- found_number = true; +- else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) ++ if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) + { + found_letter = true; + break; + } +- else if (_hb_codepoint_is_regional_indicator (info[i].codepoint)) ++ else if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) ++ found_number = true; ++ else if (unlikely (_hb_codepoint_is_regional_indicator (info[i].codepoint))) + found_ri = true; + } + if ((found_number || found_ri) && !found_letter) +@@ -651,59 +652,6 @@ hb_ensure_native_direction (hb_buffer_t *buffer) + * Substitute + */ + +-#ifndef HB_NO_VERTICAL +-static hb_codepoint_t +-hb_vert_char_for (hb_codepoint_t u) +-{ +- switch (u >> 8) +- { +- case 0x20: switch (u) { +- case 0x2013u: return 0xfe32u; // EN DASH +- case 0x2014u: return 0xfe31u; // EM DASH +- case 0x2025u: return 0xfe30u; // TWO DOT LEADER +- case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS +- } break; +- case 0x30: switch (u) { +- case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA +- case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP +- case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET +- case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET +- case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET +- case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET +- case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET +- case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET +- case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET +- case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET +- case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET +- case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET +- case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET +- case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET +- case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET +- case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET +- } break; +- case 0xfe: switch (u) { +- case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE +- } break; +- case 0xff: switch (u) { +- case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK +- case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS +- case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS +- case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA +- case 0xff1au: return 0xfe13u; // FULLWIDTH COLON +- case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON +- case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK +- case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET +- case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET +- case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE +- case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET +- case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET +- } break; +- } +- +- return u; +-} +-#endif +- + static inline void + hb_ot_rotate_chars (const hb_ot_shape_context_t *c) + { +@@ -729,7 +677,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) + if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) + { + for (unsigned int i = 0; i < count; i++) { +- hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint); ++ hb_codepoint_t codepoint = hb_unicode_funcs_t::vertical_char_for (info[i].codepoint); + if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint))) + info[i].codepoint = codepoint; + } +@@ -744,7 +692,7 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c) + return; + #endif + +- if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || ++ if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH) || + !c->plan->has_frac) + return; + +@@ -845,7 +793,13 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) + unsigned int i = 0; + for (i = 0; i < count; i++) + if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) +- pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; ++ { ++ pos[i].x_advance = pos[i].y_advance = 0; ++ if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) ++ pos[i].x_offset = 0; ++ else ++ pos[i].y_offset = 0; ++ } + } + + static void +@@ -900,11 +854,11 @@ hb_ot_hide_default_ignorables (hb_buffer_t *buffer, + static inline void + hb_ot_map_glyphs_fast (hb_buffer_t *buffer) + { +- /* Normalization process sets up glyph_index(), we just copy it. */ ++ /* Normalization process sets up normalizer_glyph_index(), we just copy it. */ + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) +- info[i].codepoint = info[i].glyph_index(); ++ info[i].codepoint = info[i].normalizer_glyph_index(); + + buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; + } +@@ -942,7 +896,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) + + hb_ot_rotate_chars (c); + +- HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); ++ HB_BUFFER_ALLOCATE_VAR (buffer, normalizer_glyph_index); + + _hb_ot_shape_normalize (c->plan, buffer, c->font); + +@@ -954,7 +908,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) + + hb_ot_map_glyphs_fast (buffer); + +- HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); ++ HB_BUFFER_DEALLOCATE_VAR (buffer, normalizer_glyph_index); + } + + static inline void +@@ -969,11 +923,17 @@ hb_ot_substitute_plan (const hb_ot_shape_context_t *c) + + #ifndef HB_NO_AAT_SHAPE + if (unlikely (c->plan->apply_morx)) ++ { + hb_aat_layout_substitute (c->plan, c->font, c->buffer, + c->user_features, c->num_user_features); ++ c->buffer->update_digest (); ++ } + else + #endif ++ { ++ c->buffer->update_digest (); + c->plan->substitute (c->font, buffer); ++ } + } + + static inline void +@@ -1054,23 +1014,16 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) + { + c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]), + &pos[0].x_advance, sizeof(pos[0])); +- /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ +- if (c->font->has_glyph_h_origin_func ()) +- for (unsigned int i = 0; i < count; i++) +- c->font->subtract_glyph_h_origin (info[i].codepoint, +- &pos[i].x_offset, +- &pos[i].y_offset); ++ // h_origin defaults to zero; only apply it if the font has it. ++ if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) ++ c->font->subtract_glyph_h_origins (c->buffer); + } + else + { + c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]), + &pos[0].y_advance, sizeof(pos[0])); +- for (unsigned int i = 0; i < count; i++) +- { +- c->font->subtract_glyph_v_origin (info[i].codepoint, +- &pos[i].x_offset, +- &pos[i].y_offset); +- } ++ // v_origin defaults to non-zero; apply even if only fallback is there. ++ c->font->subtract_glyph_v_origins (c->buffer); + } + if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) + _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); +@@ -1079,10 +1032,6 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) + static inline void + hb_ot_position_plan (const hb_ot_shape_context_t *c) + { +- unsigned int count = c->buffer->len; +- hb_glyph_info_t *info = c->buffer->info; +- hb_glyph_position_t *pos = c->buffer->pos; +- + /* If the font has no GPOS and direction is forward, then when + * zeroing mark widths, we shift the mark with it, such that the + * mark is positioned hanging over the previous glyph. When +@@ -1097,12 +1046,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) + + /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ + +- /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ +- if (c->font->has_glyph_h_origin_func ()) +- for (unsigned int i = 0; i < count; i++) +- c->font->add_glyph_h_origin (info[i].codepoint, +- &pos[i].x_offset, +- &pos[i].y_offset); ++ // h_origin defaults to zero; only apply it if the font has it. ++ if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) ++ c->font->add_glyph_h_origins (c->buffer); + + hb_ot_layout_position_start (c->font, c->buffer); + +@@ -1139,12 +1085,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) + hb_ot_zero_width_default_ignorables (c->buffer); + hb_ot_layout_position_finish_offsets (c->font, c->buffer); + +- /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ +- if (c->font->has_glyph_h_origin_func ()) +- for (unsigned int i = 0; i < count; i++) +- c->font->subtract_glyph_h_origin (info[i].codepoint, +- &pos[i].x_offset, +- &pos[i].y_offset); ++ // h_origin defaults to zero; only apply it if the font has it. ++ if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) ++ c->font->subtract_glyph_h_origins (c->buffer); + + if (c->plan->fallback_mark_positioning) + _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer, +@@ -1172,8 +1115,33 @@ hb_propagate_flags (hb_buffer_t *buffer) + /* Propagate cluster-level glyph flags to be the same on all cluster glyphs. + * Simplifies using them. */ + +- if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS)) ++ hb_mask_t and_mask = HB_GLYPH_FLAG_DEFINED; ++ if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0) ++ and_mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; ++ ++ hb_glyph_info_t *info = buffer->info; ++ ++ if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0) ++ { ++ foreach_cluster (buffer, start, end) ++ { ++ if (end - start == 1) ++ { ++ info[start].mask &= and_mask; ++ continue; ++ } ++ ++ unsigned int mask = 0; ++ for (unsigned int i = start; i < end; i++) ++ mask |= info[i].mask; ++ ++ mask &= and_mask; ++ ++ for (unsigned int i = start; i < end; i++) ++ info[i].mask = mask; ++ } + return; ++ } + + /* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things: + * +@@ -1181,30 +1149,20 @@ hb_propagate_flags (hb_buffer_t *buffer) + * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL, + * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK. + * +- * We couldn't make this interaction earlier. It has to be done here. ++ * We couldn't make this interaction earlier. It has to be done this way. + */ +- bool flip_tatweel = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL; +- +- bool clear_concat = (buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0; +- +- hb_glyph_info_t *info = buffer->info; +- + foreach_cluster (buffer, start, end) + { + unsigned int mask = 0; + for (unsigned int i = start; i < end; i++) +- mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED; ++ mask |= info[i].mask; + +- if (flip_tatweel) +- { +- if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) +- mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; +- if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) +- mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; +- } ++ if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) ++ mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; ++ if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) ++ mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + +- if (clear_concat) +- mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; ++ mask &= and_mask; + + for (unsigned int i = start; i < end; i++) + info[i].mask = mask; +@@ -1245,8 +1203,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) + _hb_buffer_deallocate_unicode_vars (c->buffer); + + c->buffer->props.direction = c->target_direction; +- +- c->buffer->leave (); + } + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh +index 068d7192d0d..649acddb414 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh +@@ -150,7 +150,7 @@ struct hb_ot_shape_planner_t + static constexpr bool apply_morx = false; + #endif + bool script_zero_marks : 1; +- bool script_fallback_mark_positioning : 1; ++ bool script_fallback_position : 1; + const struct hb_ot_shaper_t *shaper; + + HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh +index e38686e3ebb..79d3014d3e1 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh +@@ -6,10 +6,10 @@ + * + * on files with these headers: + * +- * # ArabicShaping-16.0.0.txt +- * # Date: 2024-07-30 +- * # Scripts-16.0.0.txt +- * # Date: 2024-04-30, 21:48:40 GMT ++ * # ArabicShaping-17.0.0.txt ++ * # Date: 2025-08-14 ++ * # Scripts-17.0.0.txt ++ * # Date: 2025-07-24, 13:28:55 GMT + */ + + #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh +index 19bd72d4218..5f87995ea9c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh +@@ -6,10 +6,10 @@ + * + * on files with these headers: + * +- * # ArabicShaping-16.0.0.txt +- * # Date: 2024-07-30 +- * # Blocks-16.0.0.txt +- * # Date: 2024-02-02 ++ * # ArabicShaping-17.0.0.txt ++ * # Date: 2025-08-14 ++ * # Blocks-17.0.0.txt ++ * # Date: 2025-08-01 + * UnicodeData.txt does not have a header. + */ + +@@ -80,7 +80,7 @@ static const uint8_t joining_table[] = + /* Arabic Extended-B */ + + /* 0860 */ R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R, +- /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,X,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, ++ /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,D,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + + /* Arabic Extended-A */ + +@@ -140,9 +140,9 @@ static const uint8_t joining_table[] = + + /* Arabic Extended-C */ + +- /* 10EC0 */ R,D,D, ++ /* 10EC0 */ R,D,D,X,D,D, + +-#define joining_offset_0x10f30u 1185 ++#define joining_offset_0x10f30u 1188 + + /* Sogdian */ + +@@ -161,14 +161,14 @@ static const uint8_t joining_table[] = + /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, + /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, + +-#define joining_offset_0x110bdu 1341 ++#define joining_offset_0x110bdu 1344 + + /* Kaithi */ + + /* 110A0 */ U,X,X, + /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, + +-#define joining_offset_0x1e900u 1358 ++#define joining_offset_0x1e900u 1361 + + /* Adlam */ + +@@ -176,7 +176,7 @@ static const uint8_t joining_table[] = + /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, + /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, + +-}; /* Table items: 1434; occupancy: 57% */ ++}; /* Table items: 1437; occupancy: 58% */ + + + static unsigned int +@@ -204,7 +204,7 @@ joining_type (hb_codepoint_t u) + if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; + if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; + if (hb_in_range (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; +- if (hb_in_range (u, 0x10EC2u, 0x10EC4u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; ++ if (hb_in_range (u, 0x10EC2u, 0x10EC7u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; + if (hb_in_range (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; + break; + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc +index 7379bb7f15b..981c0f9224b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc +@@ -654,7 +654,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, + + /* https://www.unicode.org/reports/tr53/ */ + +-static hb_codepoint_t ++static const hb_codepoint_t + modifier_combining_marks[] = + { + 0x0654u, /* ARABIC HAMZA ABOVE */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc +index 5c46ebbc281..5f15aff8b7c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc +@@ -427,7 +427,7 @@ const hb_ot_shaper_t _hb_ot_shaper_hangul = + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, +- false, /* fallback_position */ ++ true, /* fallback_position */ + }; + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh +index 25e6d85ef80..76c5e83e30f 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh +@@ -53,7 +53,7 @@ enum indic_syllable_type_t { + }; + + +-#line 57 "hb-ot-shaper-indic-machine.hh" ++#line 54 "hb-ot-shaper-indic-machine.hh" + #define indic_syllable_machine_ex_A 9u + #define indic_syllable_machine_ex_C 1u + #define indic_syllable_machine_ex_CM 16u +@@ -77,7 +77,7 @@ enum indic_syllable_type_t { + #define indic_syllable_machine_ex_ZWNJ 5u + + +-#line 81 "hb-ot-shaper-indic-machine.hh" ++#line 76 "hb-ot-shaper-indic-machine.hh" + static const unsigned char _indic_syllable_machine_trans_keys[] = { + 8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u, +@@ -1126,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer) + int cs; + hb_glyph_info_t *info = buffer->info; + +-#line 1130 "hb-ot-shaper-indic-machine.hh" ++#line 1119 "hb-ot-shaper-indic-machine.hh" + { + cs = indic_syllable_machine_start; + ts = 0; +@@ -1142,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer) + + unsigned int syllable_serial = 1; + +-#line 1146 "hb-ot-shaper-indic-machine.hh" ++#line 1131 "hb-ot-shaper-indic-machine.hh" + { + int _slen; + int _trans; +@@ -1156,7 +1156,7 @@ _resume: + #line 1 "NONE" + {ts = p;} + break; +-#line 1160 "hb-ot-shaper-indic-machine.hh" ++#line 1143 "hb-ot-shaper-indic-machine.hh" + } + + _keys = _indic_syllable_machine_trans_keys + (cs<<1); +@@ -1268,7 +1268,7 @@ _eof_trans: + #line 117 "hb-ot-shaper-indic-machine.rl" + {act = 7;} + break; +-#line 1272 "hb-ot-shaper-indic-machine.hh" ++#line 1232 "hb-ot-shaper-indic-machine.hh" + } + + _again: +@@ -1277,7 +1277,7 @@ _again: + #line 1 "NONE" + {ts = 0;} + break; +-#line 1281 "hb-ot-shaper-indic-machine.hh" ++#line 1239 "hb-ot-shaper-indic-machine.hh" + } + + if ( ++p != pe ) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc +index b87c530853b..bf27efee21b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc +@@ -6,12 +6,12 @@ + * + * on files with these headers: + * +- * # IndicSyllabicCategory-16.0.0.txt +- * # Date: 2024-04-30, 21:48:21 GMT +- * # IndicPositionalCategory-16.0.0.txt +- * # Date: 2024-04-30, 21:48:21 GMT +- * # Blocks-16.0.0.txt +- * # Date: 2024-02-02 ++ * # IndicSyllabicCategory-17.0.0.txt ++ * # Date: 2025-08-01, 04:02:23 GMT ++ * # IndicPositionalCategory-17.0.0.txt ++ * # Date: 2025-07-29, 13:35:52 GMT ++ * # Blocks-17.0.0.txt ++ * # Date: 2025-08-01 + */ + + #include "hb.hh" +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc +index d78b5670f61..bec802429ab 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc +@@ -296,11 +296,6 @@ struct indic_shape_plan_t + const indic_config_t *config; + + bool is_old_spec; +-#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE +- bool uniscribe_bug_compatible; +-#else +- static constexpr bool uniscribe_bug_compatible = false; +-#endif + mutable hb_atomic_t virama_glyph; + + hb_indic_would_substitute_feature_t rphf; +@@ -327,9 +322,6 @@ data_create_indic (const hb_ot_shape_plan_t *plan) + } + + indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2'); +-#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE +- indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible; +-#endif + indic_plan->virama_glyph = -1; + + /* Use zero-context would_substitute() matching for new-spec of the main +@@ -943,17 +935,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, + unsigned int start, unsigned int end) + { + /* We treat placeholder/dotted-circle as if they are consonants, so we +- * should just chain. Only if not in compatibility mode that is... */ +- +- const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; +- if (indic_plan->uniscribe_bug_compatible) +- { +- /* For dotted-circle, this is what Uniscribe does: +- * If dotted-circle is the last glyph, it just does nothing. +- * Ie. It doesn't form Reph. */ +- if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE)) +- return; +- } ++ * should just chain... */ + + initial_reordering_consonant_syllable (plan, face, buffer, start, end); + } +@@ -1347,8 +1329,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, + * Uniscribe doesn't do this. + * TEST: U+0930,U+094D,U+0915,U+094B,U+094D + */ +- if (!indic_plan->uniscribe_bug_compatible && +- unlikely (is_halant (info[new_reph_pos]))) ++ if (unlikely (is_halant (info[new_reph_pos]))) + { + for (unsigned int i = base + 1; i < new_reph_pos; i++) + if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)))) +@@ -1451,27 +1432,6 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, + else + buffer->unsafe_to_break (start - 1, start + 1); + } +- +- +- /* +- * Finish off the clusters and go home! +- */ +- if (indic_plan->uniscribe_bug_compatible) +- { +- switch ((hb_tag_t) plan->props.script) +- { +- case HB_SCRIPT_TAMIL: +- break; +- +- default: +- /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil. +- * This means, half forms are submerged into the main consonant's cluster. +- * This is unnecessary, and makes cursor positioning harder, but that's what +- * Uniscribe does. */ +- buffer->merge_clusters (start, end); +- break; +- } +- } + } + + +@@ -1501,9 +1461,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) + { +- const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; +- if (!indic_plan->uniscribe_bug_compatible) +- _hb_preprocess_text_vowel_constraints (plan, buffer, font); ++ _hb_preprocess_text_vowel_constraints (plan, buffer, font); + } + + static bool +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh +index e1f657c758a..2442f0341ef 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh +@@ -48,7 +48,7 @@ enum khmer_syllable_type_t { + }; + + +-#line 52 "hb-ot-shaper-khmer-machine.hh" ++#line 49 "hb-ot-shaper-khmer-machine.hh" + #define khmer_syllable_machine_ex_C 1u + #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u + #define khmer_syllable_machine_ex_H 4u +@@ -66,7 +66,7 @@ enum khmer_syllable_type_t { + #define khmer_syllable_machine_ex_ZWNJ 5u + + +-#line 70 "hb-ot-shaper-khmer-machine.hh" ++#line 65 "hb-ot-shaper-khmer-machine.hh" + static const unsigned char _khmer_syllable_machine_trans_keys[] = { + 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, + 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, +@@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer) + int cs; + hb_glyph_info_t *info = buffer->info; + +-#line 298 "hb-ot-shaper-khmer-machine.hh" ++#line 287 "hb-ot-shaper-khmer-machine.hh" + { + cs = khmer_syllable_machine_start; + ts = 0; +@@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer) + + unsigned int syllable_serial = 1; + +-#line 314 "hb-ot-shaper-khmer-machine.hh" ++#line 299 "hb-ot-shaper-khmer-machine.hh" + { + int _slen; + int _trans; +@@ -324,7 +324,7 @@ _resume: + #line 1 "NONE" + {ts = p;} + break; +-#line 328 "hb-ot-shaper-khmer-machine.hh" ++#line 311 "hb-ot-shaper-khmer-machine.hh" + } + + _keys = _khmer_syllable_machine_trans_keys + (cs<<1); +@@ -394,7 +394,7 @@ _eof_trans: + #line 98 "hb-ot-shaper-khmer-machine.rl" + {act = 3;} + break; +-#line 398 "hb-ot-shaper-khmer-machine.hh" ++#line 368 "hb-ot-shaper-khmer-machine.hh" + } + + _again: +@@ -403,7 +403,7 @@ _again: + #line 1 "NONE" + {ts = 0;} + break; +-#line 407 "hb-ot-shaper-khmer-machine.hh" ++#line 375 "hb-ot-shaper-khmer-machine.hh" + } + + if ( ++p != pe ) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc +index 2a4aed2ab1b..1f5028aa3ee 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer.cc +@@ -141,12 +141,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan) + * typographical correctness.", hence in overrides... */ + map->enable_feature (HB_TAG('c','l','i','g')); + +- /* Uniscribe does not apply 'kern' in Khmer. */ +- if (hb_options ().uniscribe_bug_compatible) +- { +- map->disable_feature (HB_TAG('k','e','r','n')); +- } +- + map->disable_feature (HB_TAG('l','i','g','a')); + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh +index 64eb761b4ea..6e5fce609bc 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh +@@ -50,7 +50,7 @@ enum myanmar_syllable_type_t { + }; + + +-#line 54 "hb-ot-shaper-myanmar-machine.hh" ++#line 51 "hb-ot-shaper-myanmar-machine.hh" + #define myanmar_syllable_machine_ex_A 9u + #define myanmar_syllable_machine_ex_As 32u + #define myanmar_syllable_machine_ex_C 1u +@@ -78,7 +78,7 @@ enum myanmar_syllable_type_t { + #define myanmar_syllable_machine_ex_ZWNJ 5u + + +-#line 82 "hb-ot-shaper-myanmar-machine.hh" ++#line 77 "hb-ot-shaper-myanmar-machine.hh" + static const unsigned char _myanmar_syllable_machine_trans_keys[] = { + 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, +@@ -549,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) + int cs; + hb_glyph_info_t *info = buffer->info; + +-#line 553 "hb-ot-shaper-myanmar-machine.hh" ++#line 542 "hb-ot-shaper-myanmar-machine.hh" + { + cs = myanmar_syllable_machine_start; + ts = 0; +@@ -565,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) + + unsigned int syllable_serial = 1; + +-#line 569 "hb-ot-shaper-myanmar-machine.hh" ++#line 554 "hb-ot-shaper-myanmar-machine.hh" + { + int _slen; + int _trans; +@@ -579,7 +579,7 @@ _resume: + #line 1 "NONE" + {ts = p;} + break; +-#line 583 "hb-ot-shaper-myanmar-machine.hh" ++#line 566 "hb-ot-shaper-myanmar-machine.hh" + } + + _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); +@@ -649,7 +649,7 @@ _eof_trans: + #line 113 "hb-ot-shaper-myanmar-machine.rl" + {act = 3;} + break; +-#line 653 "hb-ot-shaper-myanmar-machine.hh" ++#line 623 "hb-ot-shaper-myanmar-machine.hh" + } + + _again: +@@ -658,7 +658,7 @@ _again: + #line 1 "NONE" + {ts = 0;} + break; +-#line 662 "hb-ot-shaper-myanmar-machine.hh" ++#line 630 "hb-ot-shaper-myanmar-machine.hh" + } + + if ( ++p != pe ) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc +index a0ea464e775..42fc4bbcc44 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc +@@ -163,7 +163,7 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) + } + + +-static enum thai_above_state_t ++static const enum thai_above_state_t + { /* Cluster above looks like: */ + T0, /* ⣤ */ + T1, /* ⣼ */ +@@ -191,7 +191,7 @@ static const struct thai_above_state_machine_edge_t { + }; + + +-static enum thai_below_state_t ++static const enum thai_below_state_t + { + B0, /* No descender */ + B1, /* Removable descender */ +@@ -334,7 +334,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, + + /* Is SARA AM. Decompose and reorder. */ + (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); +- _hb_glyph_info_set_continuation (&buffer->prev()); ++ _hb_glyph_info_set_continuation (&buffer->prev(), buffer); + if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break; + + /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh +index 46f66f7d285..22a5356a877 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh +@@ -53,7 +53,7 @@ enum use_syllable_type_t { + }; + + +-#line 57 "hb-ot-shaper-use-machine.hh" ++#line 54 "hb-ot-shaper-use-machine.hh" + #define use_syllable_machine_ex_B 1u + #define use_syllable_machine_ex_CGJ 6u + #define use_syllable_machine_ex_CMAbv 31u +@@ -100,7 +100,7 @@ enum use_syllable_type_t { + #define use_syllable_machine_ex_ZWNJ 14u + + +-#line 104 "hb-ot-shaper-use-machine.hh" ++#line 99 "hb-ot-shaper-use-machine.hh" + static const unsigned char _use_syllable_machine_trans_keys[] = { + 49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, + 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, +@@ -929,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer) + unsigned int act HB_UNUSED; + int cs; + +-#line 933 "hb-ot-shaper-use-machine.hh" ++#line 922 "hb-ot-shaper-use-machine.hh" + { + cs = use_syllable_machine_start; + ts = 0; +@@ -942,7 +942,7 @@ find_syllables_use (hb_buffer_t *buffer) + + unsigned int syllable_serial = 1; + +-#line 946 "hb-ot-shaper-use-machine.hh" ++#line 931 "hb-ot-shaper-use-machine.hh" + { + int _slen; + int _trans; +@@ -956,7 +956,7 @@ _resume: + #line 1 "NONE" + {ts = p;} + break; +-#line 960 "hb-ot-shaper-use-machine.hh" ++#line 943 "hb-ot-shaper-use-machine.hh" + } + + _keys = _use_syllable_machine_trans_keys + (cs<<1); +@@ -1078,7 +1078,7 @@ _eof_trans: + #line 181 "hb-ot-shaper-use-machine.rl" + {act = 9;} + break; +-#line 1082 "hb-ot-shaper-use-machine.hh" ++#line 1039 "hb-ot-shaper-use-machine.hh" + } + + _again: +@@ -1087,7 +1087,7 @@ _again: + #line 1 "NONE" + {ts = 0;} + break; +-#line 1091 "hb-ot-shaper-use-machine.hh" ++#line 1046 "hb-ot-shaper-use-machine.hh" + } + + if ( ++p != pe ) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh +index d3c49949aa8..a69abefdd01 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh +@@ -6,18 +6,18 @@ + * + * on files with these headers: + * +- * # IndicSyllabicCategory-16.0.0.txt +- * # Date: 2024-04-30, 21:48:21 GMT +- * # IndicPositionalCategory-16.0.0.txt +- * # Date: 2024-04-30, 21:48:21 GMT +- * # ArabicShaping-16.0.0.txt +- * # Date: 2024-07-30 +- * # DerivedCoreProperties-16.0.0.txt +- * # Date: 2024-05-31, 18:09:32 GMT +- * # Blocks-16.0.0.txt +- * # Date: 2024-02-02 +- * # Scripts-16.0.0.txt +- * # Date: 2024-04-30, 21:48:40 GMT ++ * # IndicSyllabicCategory-17.0.0.txt ++ * # Date: 2025-08-01, 04:02:23 GMT ++ * # IndicPositionalCategory-17.0.0.txt ++ * # Date: 2025-07-29, 13:35:52 GMT ++ * # ArabicShaping-17.0.0.txt ++ * # Date: 2025-08-14 ++ * # DerivedCoreProperties-17.0.0.txt ++ * # Date: 2025-07-30, 23:55:08 GMT ++ * # Blocks-17.0.0.txt ++ * # Date: 2025-08-01 ++ * # Scripts-17.0.0.txt ++ * # Date: 2025-07-24, 13:28:55 GMT + * # Override values For Indic_Syllabic_Category + * # Not derivable + * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 +@@ -101,8 +101,9 @@ + + #ifndef HB_OPTIMIZE_SIZE + +-static const uint8_t +-hb_use_u8[3345] = ++#include ++ ++static const uint8_t hb_use_u8[3343]= + { + 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +@@ -126,24 +127,24 @@ hb_use_u8[3345] = + 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, + 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73, +- 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84, +- 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, +- 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, +- 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2, ++ 2, 74, 2, 75, 76, 77, 78, 79, 2, 80, 81, 82, 83, 2, 84, 85, ++ 2, 86, 86, 86, 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, ++ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, ++ 86, 86, 86, 86, 86, 86, 86, 86, 88, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92, +- 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2, ++ 2, 2, 2, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 90, 91, 2, 2, 2, 92, 2, 2, 2, 93, ++ 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 95, 95, 95, 96, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, +- 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 98, 2, 2, 2, 2, 2, ++ 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2, +- 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, +- 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, +- 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ++ 2, 2, 2, 100, 2, 2, 101, 2, 2, 2, 102, 2, 103, 2, 2, 2, ++ 2, 2, 2, 104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 105, 105, 106, 107, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, ++ 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, ++ 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, + 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +@@ -192,99 +193,99 @@ hb_use_u8[3345] = + 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, + 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, + 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, +- 0, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 9, 22, 80, 45, 22, 94, 61, 0, 0, 95, 96, 95, 95, 97, 98, 0, +- 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, +- 0, 2, 2, 2, 2, 2, 9, 0, 0, 2, 2, 2, 52, 99, 45, 0, +- 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, +- 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, +- 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, +- 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0, +- 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61, +- 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0, +- 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, +- 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, +- 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 6, 119, +- 120, 42, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, +- 121, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 122, 0, 0, 0, 0, +- 0, 0, 7, 122, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 123, 123, 0, 0, +- 0, 2, 2, 2, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +- 124, 0, 123, 123, 0, 0, 0, 0, 0, 2, 53, 2, 108, 2, 10, 2, +- 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, +- 0, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 23, 23, 23, 23, +- 23, 23, 23, 126, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, +- 11, 11, 2, 0, 0, 0, 0, 0, 52, 2, 2, 2, 22, 22, 127, 116, +- 0, 2, 2, 2, 128, 20, 59, 20, 113, 102, 129, 0, 0, 0, 0, 0, +- 0, 11, 130, 2, 2, 2, 2, 2, 2, 2, 131, 23, 22, 20, 48, 132, +- 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, +- 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, +- 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15, +- 2, 53, 22, 140, 52, 53, 2, 2, 105, 10, 9, 0, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0, +- 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, +- 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, +- 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, +- 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 145, +- 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, +- 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, +- 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, +- 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, +- 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, +- 0, 149, 150, 151, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, +- 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152, +- 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, +- 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, +- 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 128, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2, +- 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, +- 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 158, 0, 0, 56, 159, 31, +- 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, +- 19, 22, 22, 161, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, +- 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, +- 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0, +- 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, +- 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, +- 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, +- 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, +- 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, +- 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, +- 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, +- 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, +- 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, +- 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, +- 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, +- 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0, +- 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, +- 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, +- 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, +- 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0, +- 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178, +- 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, ++ 0, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 93, 61, 0, ++ 0, 94, 95, 94, 94, 96, 97, 0, 0, 2, 2, 2, 2, 2, 2, 2, ++ 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, ++ 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, ++ 0, 2, 2, 2, 52, 98, 45, 0, 0, 2, 2, 99, 100, 101, 102, 61, ++ 63, 103, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 104, 46, ++ 40, 11, 105, 74, 2, 2, 2, 2, 2, 2, 2, 106, 22, 20, 20, 22, ++ 48, 48, 22, 107, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 108, 109, ++ 109, 109, 109, 0, 0, 0, 0, 0, 0, 105, 74, 2, 2, 2, 2, 2, ++ 2, 60, 61, 59, 25, 22, 110, 61, 2, 2, 2, 2, 106, 22, 23, 45, ++ 45, 101, 111, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 112, ++ 101, 101, 101, 113, 114, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, ++ 2, 11, 46, 115, 115, 115, 11, 115, 115, 15, 115, 115, 115, 26, 0, 40, ++ 0, 0, 0, 116, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 117, 0, ++ 0, 0, 0, 0, 0, 0, 6, 118, 119, 42, 42, 5, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, ++ 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 7, 121, 0, 0, 0, 0, ++ 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, ++ 0, 0, 0, 0, 122, 122, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, ++ 30, 0, 0, 0, 0, 0, 0, 0, 123, 0, 122, 122, 0, 0, 0, 0, ++ 0, 2, 53, 2, 107, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, ++ 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 124, 23, 23, 23, 23, 23, 23, 23, 125, 0, 0, 0, 0, ++ 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, ++ 52, 2, 2, 2, 22, 22, 126, 115, 0, 2, 2, 2, 127, 20, 59, 20, ++ 112, 101, 128, 0, 0, 0, 0, 0, 0, 11, 129, 2, 2, 2, 2, 2, ++ 2, 2, 130, 23, 22, 20, 48, 131, 132, 133, 0, 0, 0, 0, 0, 0, ++ 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, ++ 98, 76, 134, 135, 136, 0, 0, 0, 0, 2, 137, 2, 2, 2, 2, 138, ++ 0, 30, 2, 42, 5, 0, 79, 15, 2, 139, 20, 53, 127, 139, 2, 2, ++ 140, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, ++ 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, ++ 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, ++ 6, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, ++ 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, ++ 0, 127, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, ++ 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, ++ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, ++ 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, ++ 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, ++ 0, 2, 2, 2, 115, 115, 115, 115, 115, 148, 2, 9, 0, 0, 0, 0, ++ 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, ++ 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 133, 0, 0, 0, ++ 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, ++ 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, ++ 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, ++ 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 20, 22, 154, ++ 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, ++ 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, ++ 22, 107, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, ++ 49, 127, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, ++ 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, ++ 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, ++ 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, ++ 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, ++ 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, ++ 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, ++ 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, ++ 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 125, 15, 17, 0, 0, 0, ++ 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, ++ 0, 18, 19, 20, 20, 66, 98, 25, 160, 11, 168, 9, 0, 0, 0, 0, ++ 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, ++ 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, ++ 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, ++ 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, ++ 0, 2, 2, 2, 2, 2, 9, 43, 135, 23, 22, 20, 76, 21, 22, 0, ++ 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, ++ 19, 20, 21, 22, 104, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, ++ 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, ++ 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, ++ 2, 65, 25, 20, 20, 0, 22, 23, 29, 107, 0, 33, 0, 0, 0, 0, ++ 0, 52, 20, 22, 22, 22, 139, 2, 2, 2, 174, 140, 11, 15, 175, 61, ++ 176, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, ++ 2, 2, 2, 158, 158, 158, 177, 177, 177, 177, 177, 177, 15, 178, 0, 30, ++ 0, 16, 20, 16, 16, 0, 0, 0, 0, 22, 20, 20, 31, 22, 22, 11, + 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, +- 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, ++ 27, 11, 159, 179, 180, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, +- 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, ++ 0, 2, 181, 66, 47, 0, 0, 0, 0, 11, 182, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184, +- 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, +- 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, +- 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, +- 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, ++ 0, 2, 2, 2, 2, 2, 156, 0, 0, 183, 183, 183, 183, 183, 183, 183, ++ 183, 184, 184, 184, 185, 186, 184, 183, 183, 187, 183, 183, 188, 189, 189, 189, ++ 189, 189, 189, 189, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 190, 0, ++ 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 191, 192, ++ 193, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, +- 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +- 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, ++ 58, 194, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, ++ 20, 20, 20, 20, 20, 0, 0, 0, 40, 115, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, ++ 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 119, 119, 119, 120, 0, + 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, + 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, +@@ -300,23 +301,21 @@ hb_use_u8[3345] = + VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, + VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, + FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, +- CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, +- VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, +- VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv, +- CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, +- SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, +- CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, +- FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, ++ CMAbv,CMAbv, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, ++ MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, ++ B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw, ++ VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, ++ H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, ++ MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, ++ B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, + IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, + O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, +- VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, +- IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, +- J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, +- VBlw, ++ VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, ++ IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, ++ G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, + }; +-static const uint16_t +-hb_use_u16[856] = ++static const uint16_t hb_use_u16[864]= + { + 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, +@@ -330,66 +329,65 @@ hb_use_u16[856] = + 73, 74, 75, 76, 77, 0, 0, 0, 10, 10, 78, 79, 80, 81, 82, 83, + 84, 85, 0, 0, 0, 0, 0, 0, 10, 86, 10, 87, 10, 88, 89, 90, + 10, 10, 10, 91, 92, 93, 2, 0, 94, 0, 10, 10, 10, 10, 10, 95, +- 96, 10, 97, 0, 0, 0, 0, 0, 98, 99,100,101, 31, 10,102,103, +- 10, 10,104, 10,105,106, 0, 0, 10,107, 10, 10, 10,108,109,110, +- 2, 2, 0, 0, 0, 0, 0, 0,111, 10, 10,112,113, 2,114,115, +- 116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122, 0, 0, 0, +- 0, 0, 0, 0, 0,123,124,125, 0, 0, 0, 0, 0, 0, 0,126, +- 127,128,129, 0, 0, 0,130,131,132, 0, 0, 0, 0, 0, 0,133, +- 0, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0,135, 0, +- 0, 0, 0, 10, 10, 10,136,137, 0, 0,138, 0, 0, 0, 0, 0, +- 139, 10,140, 0, 10, 10, 10,141,142, 10, 10,143,144, 2,145,146, +- 10, 10,147, 10,148,149, 0, 0,150, 10, 10,151,152, 2,153, 99, +- 10, 10,154,155,156, 2, 10,157, 10, 10, 10,158,159, 0,160,161, +- 0, 0, 0, 0, 10, 10,162, 2,163, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, +- 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, +- 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, +- 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 9, 10,176, 10, +- 177, 0, 0, 0, 0, 0, 0, 0, 10, 10,178,173, 0, 0, 0, 0, +- 0, 0, 0, 10,179,180, 0, 10,181, 0, 0,182,183, 0, 0, 0, +- 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0, 0, 0, +- 193, 10,194,195,196, 10, 10,197,190, 10, 10,198,199,106,200,103, +- 10, 34,201,202,203, 0, 0, 0,204,205, 95, 10, 10,206,207, 2, +- 208, 21, 22,209,210,211,212,213,214, 10, 10,215,216,217,218, 0, +- 10, 10, 10,219,220,221,222, 0,200, 10, 10,223,224, 2, 0, 0, +- 10, 10,225,226,227,228, 0, 0, 10, 10, 10,229,230, 2, 0, 0, +- 10, 10,231,232, 2, 10,141, 0, 10,233,234,104,235, 0, 0, 0, +- 10, 10,236,237, 0, 0, 0, 0,238,239, 10,240,241, 2, 0, 0, +- 0, 0,242, 10, 10,243,244, 0,245, 10, 10,246,247,248, 10, 10, +- 249,250, 0, 0, 0, 0, 0, 0, 22, 10,225,251, 8, 10, 71, 19, +- 10,252, 74,253, 0, 0, 0, 0,254, 10, 10,255,256, 2,257, 10, +- 258,259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,260, +- 261, 49, 10,262,263,264, 0, 0,265,265,265,265,265,265,265,265, +- 265,265,265,266,267,268,265,265,265,265,265,265,265,265,265,269, +- 10,270,271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, +- 10, 10, 10,272, 0, 0, 0, 0, 0, 0, 0, 0,273, 10,274, 2, +- 10, 10, 10, 10,275,276,277,277,278,279, 0, 0, 0, 0,280, 0, +- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,177, 0,281, +- 10, 10, 10, 10, 10, 10,106, 71, 95,282, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0,283, 10, 10, 71,284,285, 0, 0, 0, +- 0, 10,286, 0, 10, 10,287, 2, 0, 0, 0, 0, 0, 10,288, 2, +- 0, 0, 0, 0, 0, 10,289,106, 10, 10, 10, 10,290, 2, 0, 0, +- 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, +- 163,163,163,163,163,163,163,130, ++ 96, 10, 97, 0, 0, 0, 0, 0, 10, 98, 99,100, 31, 10,101,102, ++ 10, 10,103, 10,104,105, 0, 0, 10,106, 10, 10, 10,107,108,109, ++ 2, 2, 0, 0, 0, 0, 0, 0,110, 10, 10,111,112, 2,113,114, ++ 115, 10,116, 10, 10, 10,117,118, 10, 10,119,120,121, 0, 0, 0, ++ 0, 0, 0, 0, 0,122,123,124, 0, 0, 0, 0, 0, 0, 0,125, ++ 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, ++ 0, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 0, 0,134, 0, ++ 0, 0, 0, 10, 10, 10,135,136, 0, 0,137, 0, 0, 0, 0, 0, ++ 138, 10,139, 0, 10, 10, 10,140,141, 10, 10,142,143, 2,144,145, ++ 10, 10,146, 10,147,148, 0, 0,149, 10, 10,150,151, 2,152, 98, ++ 10, 10,153,154,155, 2, 10,156, 10, 10, 10,157,158, 0,159,160, ++ 0, 0, 0, 0, 10, 10,161, 2,162, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 0,164, ++ 0, 0, 0, 0, 0, 0, 0,165,165,166, 34,167, 0, 0, 0, 0, ++ 168,169, 10,170, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,171, 0, ++ 10,172,173, 0, 0, 0, 0, 0, 10, 10,174, 2, 9, 10,175, 10, ++ 176, 0, 0, 0, 0, 0, 0, 0, 10, 10,177,172, 0, 0, 0, 0, ++ 0, 0, 0, 10,178,179, 0, 10,180, 0, 0,181,182, 0, 0, 0, ++ 183, 10, 10,184,185,186,187,188,189, 10, 10,190,191, 0, 0, 0, ++ 192, 10,193,194,195, 10, 10,196,189, 10, 10,197,198,105,199,102, ++ 10, 34,200,201,202, 0, 0, 0,203,204, 95, 10, 10,205,206, 2, ++ 207, 21, 22,208,209,210,211,212,213, 10, 10,214,215,216,217, 0, ++ 10, 10, 10,218,219,220,221, 0,199, 10, 10,222,223, 2, 0, 0, ++ 10, 10,224,225,226,227, 0, 0, 10, 10, 10,228,229, 2, 0, 0, ++ 10, 10,230,231, 2, 10,140, 0, 10,232,233,103,234, 0, 0, 0, ++ 10, 10,235,236, 0, 0, 0, 0,237,238, 10,239,240, 2, 0, 0, ++ 0, 0,241, 10, 10,242,243, 0,244, 10, 10,245,246,247, 10, 10, ++ 248,249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 0, ++ 22, 10,224,251, 8, 10, 71, 19, 10,252, 74,253, 0, 0, 0, 0, ++ 254, 10, 10,255,256, 2,257, 10,258,259, 2, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 10,260,261, 49, 10,262,263,264, 0, 0, ++ 265,265,265,265,265,265,265,265,265,265,265,266,267,268,265,265, ++ 265,265,265,265,265,265,265,269, 10,270,271, 2, 0, 0, 0, 0, ++ 0, 0, 0, 0, 2, 0, 0, 0, 10, 10, 10,272, 0, 0, 0, 0, ++ 0, 0, 0, 0,273, 10,274, 2, 10, 10, 10, 10,275,276,277,277, ++ 278,279, 0, 0, 0, 0,280, 0, 10, 10, 10, 10, 10, 10, 10, 10, ++ 10, 10, 10, 10, 10,176, 0,281, 10, 10, 10, 10, 10, 10,105, 71, ++ 95,282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,283, ++ 10, 10, 71,284,285, 0, 0, 0, 0, 10,286, 0, 10, 10,287, 2, ++ 0, 0, 0, 0, 0, 10,288, 2, 0, 0, 0, 0, 0, 10,289,105, ++ 10, 10, 10, 10,290, 2, 0, 0,129,129,129,129,129,129,129,129, ++ 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,129, + }; + +-static inline unsigned +-hb_use_b4 (const uint8_t* a, unsigned i) ++static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) + { +- return (a[i>>1]>>((i&1u)<<2))&15u; ++ return (a[i>>1]>>((i&1)<<2))&15; + } +-static inline uint_fast8_t +-hb_use_get_category (unsigned u) ++static inline uint8_t hb_use_get_category (unsigned u) + { +- return u<921600u?hb_use_u8[2953+(((hb_use_u8[625+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]: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; + } + + + #else + +-static const uint8_t +-hb_use_u8[3657] = ++#include ++ ++static const uint8_t hb_use_u8[3663]= + { + 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, +@@ -405,16 +403,16 @@ hb_use_u8[3657] = + 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, + 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, +- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, +- 51, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, +- 52, 52, 52, 52, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 58, 1, +- 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60, 61, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 1, +- 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 64, 65, 1, 66, 67, 1, 1, 1, 68, 1, 1, 1, 1, 1, +- 1, 69, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, +- 69, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, ++ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, ++ 52, 53, 53, 53, 53, 54, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, ++ 53, 53, 53, 53, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 57, 58, 1, 59, 1, ++ 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 61, 62, 1, 1, ++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 63, 1, 1, ++ 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 1, 1, 65, 66, 1, 67, 68, 1, 1, 1, 69, 1, 1, 1, 1, 1, ++ 1, 70, 71, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, ++ 70, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, + 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +@@ -438,120 +436,120 @@ hb_use_u8[3657] = + 0, 0, 0, 0, 0, 56, 179, 180, 0, 56, 181, 182, 0, 56, 183, 184, + 185, 186, 187, 188, 0, 0, 0, 0, 0, 56, 189, 0, 0, 0, 0, 0, + 0, 190, 191, 192, 0, 0, 193, 194, 195, 196, 197, 198, 56, 199, 0, 0, +- 0, 200, 201, 202, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 67, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 211, 212, 213, 214, 0, 0, 0, 0, +- 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 217, 215, 215, 215, 215, +- 215, 215, 215, 215, 215, 215, 215, 215, 218, 219, 220, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 221, 0, 0, 0, 0, 0, +- 0, 0, 0, 222, 223, 0, 0, 0, 0, 56, 56, 224, 225, 226, 0, 0, +- 227, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 228, +- 229, 56, 56, 56, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, +- 0, 56, 233, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 235, 56, +- 236, 0, 0, 0, 0, 0, 0, 101, 237, 0, 0, 0, 0, 0, 0, 101, +- 238, 56, 56, 239, 0, 0, 0, 0, 0, 240, 240, 240, 240, 240, 240, 240, +- 240, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, +- 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, +- 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 10, 11, 11, 11, 11, 0, 0, 0, 9, 12, +- 0, 2, 2, 2, 2, 13, 14, 0, 0, 11, 15, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, +- 25, 12, 26, 27, 20, 2, 2, 2, 2, 2, 20, 0, 2, 2, 2, 2, +- 2, 0, 2, 2, 2, 2, 2, 2, 2, 28, 29, 30, 2, 2, 2, 9, +- 30, 9, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, +- 2, 9, 9, 0, 2, 2, 0, 17, 18, 19, 20, 31, 32, 33, 32, 34, +- 0, 0, 0, 0, 35, 0, 0, 2, 30, 2, 0, 0, 0, 0, 0, 9, +- 36, 12, 15, 30, 2, 2, 9, 0, 30, 9, 2, 30, 9, 2, 0, 37, +- 18, 19, 31, 0, 27, 38, 27, 39, 0, 40, 0, 0, 0, 30, 2, 9, +- 9, 0, 0, 0, 2, 2, 2, 2, 2, 41, 42, 43, 0, 0, 0, 0, +- 0, 12, 15, 30, 2, 2, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, +- 2, 9, 2, 30, 2, 2, 0, 17, 18, 19, 20, 21, 27, 22, 35, 24, +- 0, 0, 0, 0, 0, 30, 41, 41, 44, 12, 29, 30, 2, 2, 2, 9, +- 30, 9, 2, 30, 2, 2, 0, 17, 45, 0, 0, 27, 22, 0, 0, 2, +- 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 46, 30, 2, 2, 9, 0, +- 2, 9, 2, 2, 0, 30, 9, 9, 2, 0, 30, 9, 0, 2, 9, 0, +- 2, 2, 2, 2, 2, 2, 0, 0, 23, 16, 47, 0, 48, 33, 48, 34, +- 0, 0, 0, 0, 35, 0, 0, 0, 0, 15, 29, 49, 2, 2, 2, 9, +- 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 17, +- 22, 16, 23, 47, 22, 38, 22, 39, 0, 0, 0, 27, 31, 2, 9, 0, +- 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, +- 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, +- 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, +- 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, +- 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, +- 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, +- 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, +- 0, 2, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, +- 0, 2, 2, 56, 56, 57, 0, 0, 18, 2, 2, 2, 2, 30, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 9, 0, 58, 21, 59, 22, 22, 20, 20, +- 46, 21, 11, 31, 11, 2, 2, 60, 61, 61, 61, 61, 61, 62, 61, 61, +- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 63, +- 0, 0, 0, 0, 64, 0, 0, 0, 0, 2, 2, 2, 2, 2, 65, 45, +- 59, 66, 22, 22, 67, 68, 69, 70, 71, 2, 2, 2, 2, 2, 1, 0, +- 5, 2, 2, 2, 23, 20, 2, 2, 72, 71, 73, 74, 65, 73, 29, 29, +- 2, 52, 22, 53, 2, 2, 2, 2, 2, 2, 75, 76, 77, 29, 29, 78, +- 79, 2, 2, 2, 2, 2, 29, 45, 0, 2, 59, 80, 0, 0, 0, 0, +- 30, 2, 59, 47, 0, 0, 0, 0, 0, 2, 59, 0, 0, 0, 0, 0, +- 0, 2, 2, 2, 2, 2, 2, 9, 2, 9, 59, 0, 0, 0, 0, 0, +- 0, 2, 2, 81, 45, 22, 59, 20, 48, 48, 48, 48, 15, 82, 83, 84, +- 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, +- 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, +- 2, 2, 2, 2, 2, 13, 9, 0, 0, 93, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 94, 61, 0, +- 0, 95, 96, 95, 95, 97, 98, 0, 0, 2, 2, 2, 2, 2, 2, 2, ++ 0, 0, 0, 0, 200, 0, 0, 0, 0, 201, 202, 203, 204, 205, 206, 0, ++ 0, 207, 208, 209, 210, 211, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 212, 213, 214, 215, 0, 0, 0, 0, 0, 216, 216, 216, 216, 216, 216, 216, ++ 216, 216, 217, 218, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, ++ 219, 220, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, ++ 0, 56, 222, 0, 0, 0, 0, 0, 0, 0, 0, 223, 224, 0, 0, 0, ++ 0, 56, 56, 225, 226, 227, 0, 0, 228, 56, 56, 56, 56, 56, 56, 56, ++ 56, 56, 56, 56, 56, 56, 56, 229, 230, 56, 56, 56, 231, 232, 0, 0, ++ 0, 0, 0, 0, 233, 0, 0, 0, 0, 56, 234, 235, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 101, 236, 56, 237, 0, 0, 0, 0, 0, 0, 101, ++ 238, 0, 0, 0, 0, 0, 0, 101, 239, 56, 56, 240, 0, 0, 0, 0, ++ 0, 241, 241, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, ++ 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ++ 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, ++ 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 11, ++ 11, 11, 11, 0, 0, 0, 9, 12, 0, 2, 2, 2, 2, 13, 14, 0, ++ 0, 11, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 17, ++ 18, 19, 20, 21, 22, 16, 23, 24, 25, 12, 26, 27, 20, 2, 2, 2, ++ 2, 2, 20, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, ++ 2, 28, 29, 30, 2, 2, 2, 9, 30, 9, 30, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 9, 0, 2, 2, 0, 17, ++ 18, 19, 20, 31, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 2, ++ 30, 2, 0, 0, 0, 0, 0, 9, 36, 12, 15, 30, 2, 2, 9, 0, ++ 30, 9, 2, 30, 9, 2, 0, 37, 18, 19, 31, 0, 27, 38, 27, 39, ++ 0, 40, 0, 0, 0, 30, 2, 9, 9, 0, 0, 0, 2, 2, 2, 2, ++ 2, 41, 42, 43, 0, 0, 0, 0, 0, 12, 15, 30, 2, 2, 2, 2, ++ 30, 2, 30, 2, 2, 2, 2, 2, 2, 9, 2, 30, 2, 2, 0, 17, ++ 18, 19, 20, 21, 27, 22, 35, 24, 0, 0, 0, 0, 0, 30, 41, 41, ++ 44, 12, 29, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 0, 17, ++ 45, 0, 0, 27, 22, 0, 0, 2, 30, 30, 0, 0, 0, 0, 0, 0, ++ 0, 0, 46, 30, 2, 2, 9, 0, 2, 9, 2, 2, 0, 30, 9, 9, ++ 2, 0, 30, 9, 0, 2, 9, 0, 2, 2, 2, 2, 2, 2, 0, 0, ++ 23, 16, 47, 0, 48, 33, 48, 34, 0, 0, 0, 0, 35, 0, 0, 0, ++ 0, 15, 29, 49, 2, 2, 2, 9, 2, 9, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 0, 17, 22, 16, 23, 47, 22, 38, 22, 39, ++ 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, ++ 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, ++ 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, ++ 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34, ++ 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, ++ 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, ++ 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, ++ 25, 0, 23, 0, 0, 0, 0, 0, 0, 2, 0, 2, 9, 0, 0, 0, ++ 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 2, 56, 56, 57, 0, 0, ++ 18, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, ++ 0, 58, 21, 59, 22, 22, 20, 20, 46, 21, 11, 31, 11, 2, 2, 60, ++ 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, ++ 61, 61, 61, 61, 61, 61, 61, 63, 0, 0, 0, 0, 64, 0, 0, 0, ++ 0, 2, 2, 2, 2, 2, 65, 45, 59, 66, 22, 22, 67, 68, 69, 70, ++ 71, 2, 2, 2, 2, 2, 1, 0, 5, 2, 2, 2, 23, 20, 2, 2, ++ 72, 71, 73, 74, 65, 73, 29, 29, 2, 52, 22, 53, 2, 2, 2, 2, ++ 2, 2, 75, 76, 77, 29, 29, 78, 79, 2, 2, 2, 2, 2, 29, 45, ++ 0, 2, 59, 80, 0, 0, 0, 0, 30, 2, 59, 47, 0, 0, 0, 0, ++ 0, 2, 59, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 9, ++ 2, 9, 59, 0, 0, 0, 0, 0, 0, 2, 2, 81, 45, 22, 59, 20, ++ 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, ++ 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, ++ 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, ++ 0, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 93, 61, 0, ++ 0, 94, 95, 94, 94, 96, 97, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, +- 0, 2, 2, 2, 52, 99, 45, 0, 0, 2, 2, 100, 101, 102, 103, 61, +- 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, +- 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, +- 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, +- 110, 110, 110, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, +- 2, 60, 61, 59, 25, 22, 111, 61, 2, 2, 2, 2, 107, 22, 23, 45, +- 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, +- 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, +- 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, +- 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, +- 0, 0, 0, 0, 0, 0, 6, 119, 120, 42, 42, 5, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, +- 120, 0, 0, 122, 0, 0, 0, 0, 0, 0, 7, 122, 0, 0, 0, 0, ++ 0, 2, 2, 2, 52, 98, 45, 0, 0, 2, 2, 99, 100, 101, 102, 61, ++ 63, 103, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 104, 46, ++ 40, 11, 105, 74, 2, 2, 2, 2, 2, 2, 2, 106, 22, 20, 20, 22, ++ 48, 48, 22, 107, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 108, 109, ++ 109, 109, 109, 0, 0, 0, 0, 0, 0, 105, 74, 2, 2, 2, 2, 2, ++ 2, 60, 61, 59, 25, 22, 110, 61, 2, 2, 2, 2, 106, 22, 23, 45, ++ 45, 101, 111, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 112, ++ 101, 101, 101, 113, 114, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, ++ 2, 11, 46, 115, 115, 115, 11, 115, 115, 15, 115, 115, 115, 26, 0, 40, ++ 0, 0, 0, 116, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 117, 0, ++ 0, 0, 0, 0, 0, 0, 6, 118, 119, 42, 42, 5, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 119, 119, 120, 119, 119, 119, 119, 119, 119, 119, ++ 119, 0, 0, 121, 0, 0, 0, 0, 0, 0, 7, 121, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, +- 0, 0, 0, 0, 123, 123, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, +- 30, 0, 0, 0, 0, 0, 0, 0, 124, 0, 123, 123, 0, 0, 0, 0, +- 0, 2, 53, 2, 108, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, ++ 0, 0, 0, 0, 122, 122, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, ++ 30, 0, 0, 0, 0, 0, 0, 0, 123, 0, 122, 122, 0, 0, 0, 0, ++ 0, 2, 53, 2, 107, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 125, 23, 23, 23, 23, 23, 23, 23, 126, 0, 0, 0, 0, ++ 2, 2, 2, 124, 23, 23, 23, 23, 23, 23, 23, 125, 0, 0, 0, 0, + 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, +- 52, 2, 2, 2, 22, 22, 127, 116, 0, 2, 2, 2, 128, 20, 59, 20, +- 113, 102, 129, 0, 0, 0, 0, 0, 0, 11, 130, 2, 2, 2, 2, 2, +- 2, 2, 131, 23, 22, 20, 48, 132, 133, 134, 0, 0, 0, 0, 0, 0, ++ 52, 2, 2, 2, 22, 22, 126, 115, 0, 2, 2, 2, 127, 20, 59, 20, ++ 112, 101, 128, 0, 0, 0, 0, 0, 0, 11, 129, 2, 2, 2, 2, 2, ++ 2, 2, 130, 23, 22, 20, 48, 131, 132, 133, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, +- 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, +- 0, 30, 2, 42, 5, 0, 79, 15, 2, 53, 22, 140, 52, 53, 2, 2, +- 105, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, ++ 98, 76, 134, 135, 136, 0, 0, 0, 0, 2, 137, 2, 2, 2, 2, 138, ++ 0, 30, 2, 42, 5, 0, 79, 15, 2, 139, 20, 53, 127, 139, 2, 2, ++ 140, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, + 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, + 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, +- 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, ++ 6, 119, 119, 119, 119, 120, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, + 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, +- 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, ++ 0, 127, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, + 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, + 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, + 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, +- 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, ++ 0, 2, 2, 2, 115, 115, 115, 115, 115, 148, 2, 9, 0, 0, 0, 0, + 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, + 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 134, 0, 0, 0, ++ 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 133, 0, 0, 0, + 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, + 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, + 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, +- 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 154, ++ 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 20, 22, 154, + 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, + 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, +- 22, 108, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, ++ 22, 107, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, +- 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, ++ 49, 127, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, + 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, + 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, +@@ -559,70 +557,69 @@ hb_use_u8[3657] = + 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, + 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, +- 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, ++ 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 125, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, +- 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 168, 9, 0, 0, 0, 0, ++ 0, 18, 19, 20, 20, 66, 98, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, + 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, +- 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, ++ 0, 2, 2, 2, 2, 2, 9, 43, 135, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, +- 19, 20, 21, 22, 105, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, ++ 19, 20, 21, 22, 104, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, + 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, +- 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, +- 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 174, 175, 11, 15, 176, 61, +- 177, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, +- 2, 2, 2, 158, 158, 158, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, +- 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, +- 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, +- 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 180, 181, 0, 0, 0, +- 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, +- 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, +- 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, +- 48, 16, 143, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 156, 0, +- 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, +- 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, +- 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, +- 22, 22, 22, 22, 22, 22, 192, 193, 194, 11, 11, 11, 46, 0, 0, 0, +- 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, +- 0, 2, 2, 2, 2, 2, 9, 0, 58, 195, 20, 20, 20, 20, 20, 20, +- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, +- 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 2, 2, 2, 0, 58, +- 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, +- 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, +- 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, +- 22, 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, 44, 44, 44, 92, 0, +- 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, +- FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, +- VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, +- VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, +- O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, +- H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, +- O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, B, R, O, HVM, +- O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, +- O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, +- B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B, +- VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, +- FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, +- FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, +- SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, +- IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, +- CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, +- VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, +- MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, +- O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, +- B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, +- VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, +- CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw, +- VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, +- VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, +- O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, ++ 2, 65, 25, 20, 20, 0, 22, 23, 29, 107, 0, 33, 0, 0, 0, 0, ++ 0, 52, 20, 22, 22, 22, 139, 2, 2, 2, 174, 140, 11, 15, 175, 61, ++ 176, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, ++ 2, 2, 2, 158, 158, 158, 177, 177, 177, 177, 177, 177, 15, 178, 0, 30, ++ 0, 16, 20, 16, 16, 0, 0, 0, 0, 22, 20, 20, 31, 22, 22, 11, ++ 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, ++ 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, ++ 27, 11, 159, 179, 180, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, ++ 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, ++ 0, 2, 181, 66, 47, 0, 0, 0, 0, 11, 182, 2, 2, 2, 2, 2, ++ 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, ++ 0, 2, 2, 2, 2, 2, 156, 0, 0, 183, 183, 183, 183, 183, 183, 183, ++ 183, 184, 184, 184, 185, 186, 184, 183, 183, 187, 183, 183, 188, 189, 189, 189, ++ 189, 189, 189, 189, 0, 0, 0, 0, 0, 183, 183, 183, 183, 183, 190, 0, ++ 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 191, 192, ++ 193, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, ++ 58, 194, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, ++ 20, 20, 20, 20, 20, 0, 0, 0, 40, 115, 26, 0, 0, 0, 0, 0, ++ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 119, 119, 119, 120, 0, ++ 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, ++ 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, ++ 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, ++ 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, ++ SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, ++ VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, ++ VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, ++ VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, ++ VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, ++ MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS, ++ VMPst, B, VAbv, VAbv, B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, ++ VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv, ++ VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, ++ VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, ++ FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, ++ CMAbv,CMAbv, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, ++ MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, ++ B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw, ++ VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, ++ H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, ++ MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, ++ B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, ++ IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, ++ IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, ++ O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, ++ VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, ++ IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, ++ G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, + }; +-static const uint16_t +-hb_use_u16[486] = ++static const uint16_t hb_use_u16[488]= + { + 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, + 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, +@@ -633,43 +630,43 @@ hb_use_u16[486] = + 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77, 0, + 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88, + 89, 90, 10, 91, 92, 93, 2, 0, 94, 0, 10, 95, 96, 10, 97, 0, +- 98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108, +- 109,110, 2, 2,111, 10, 10,112,113, 2,114,115,116, 10,117, 10, +- 118,119,120,121,122, 0, 0,123,124,125, 0,126,127,128,129, 0, +- 130,131,132, 0, 0,133,134, 0,135, 0, 0, 10,136,137,138, 0, +- 139, 10,140, 0, 10,141,142, 10, 10,143,144, 2,145,146,147, 10, +- 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, +- 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, +- 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, +- 175, 2,176, 10,177, 0,178,173,179,180,181, 0, 0,182,183, 0, +- 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0,193, 10, +- 194,195,196, 10, 10,197, 10,198,199,106,200,103, 10, 34,201,202, +- 203, 0,204,205, 95, 10, 10,206,207, 2,208, 21, 22,209,210,211, +- 212,213,214, 10, 10,215,216,217,218, 0, 10,219,220,221,222, 0, +- 200, 10, 10,223,224, 2,225,226,227,228, 10,229,230, 2,231,232, +- 2, 10,141, 0, 10,233,234,104,235, 0,236,237,238,239, 10,240, +- 241, 2,242, 10, 10,243,244, 0,245, 10, 10,246,247,248,249,250, +- 22, 10,225,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, 10,255, +- 256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264,265,265, +- 265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10,274, 2, +- 275,276,277,277,278,279,280, 0, 10,177, 0,281,106, 71, 95,282, +- 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,106,290, 2, +- 130,130,163,163,163,130, ++ 10, 98, 99,100, 31, 10,101,102,103, 10,104,105, 10,106, 10,107, ++ 108,109, 2, 2,110, 10, 10,111,112, 2,113,114,115, 10,116, 10, ++ 117,118,119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0, ++ 129,130,131, 0, 0,132,133, 0,134, 0, 0, 10,135,136,137, 0, ++ 138, 10,139, 0, 10,140,141, 10, 10,142,143, 2,144,145,146, 10, ++ 147,148,149, 10, 10,150,151, 2,152, 98,153,154,155, 2, 10,156, ++ 10,157,158, 0,159,160,161, 2,162, 0, 0,163, 0,164, 0,165, ++ 165,166, 34,167,168,169, 10,170, 95, 0,171, 0, 10,172,173, 0, ++ 174, 2,175, 10,176, 0,177,172,178,179,180, 0, 0,181,182, 0, ++ 183, 10, 10,184,185,186,187,188,189, 10, 10,190,191, 0,192, 10, ++ 193,194,195, 10, 10,196, 10,197,198,105,199,102, 10, 34,200,201, ++ 202, 0,203,204, 95, 10, 10,205,206, 2,207, 21, 22,208,209,210, ++ 211,212,213, 10, 10,214,215,216,217, 0, 10,218,219,220,221, 0, ++ 199, 10, 10,222,223, 2,224,225,226,227, 10,228,229, 2,230,231, ++ 2, 10,140, 0, 10,232,233,103,234, 0,235,236,237,238, 10,239, ++ 240, 2,241, 10, 10,242,243, 0,244, 10, 10,245,246,247,248,249, ++ 250, 0, 22, 10,224,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, ++ 10,255,256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264, ++ 265,265,265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10, ++ 274, 2,275,276,277,277,278,279,280, 0, 10,176, 0,281,105, 71, ++ 95,282, 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,105, ++ 290, 2,129,129,162,162,162,129, + }; + +-static inline unsigned +-hb_use_b4 (const uint8_t* a, unsigned i) ++static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) + { +- return (a[i>>1]>>((i&1u)<<2))&15u; ++ return (a[i>>1]>>((i&1)<<2))&15; + } +-static inline uint_fast8_t +-hb_use_get_category (unsigned u) ++static inline uint8_t hb_use_get_category (unsigned u) + { +- return u<921600u?hb_use_u8[3265+(((hb_use_u8[937+(((hb_use_u16[((hb_use_u8[369+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; ++ return u<921600 ? hb_use_u8[3273u+((hb_use_u8[945u+((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 +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc +index 4a112e1c289..bb586a68ce5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc +@@ -10,8 +10,8 @@ + * # Date: 2015-03-12, 21:17:00 GMT [AG] + * # Date: 2019-11-08, 23:22:00 GMT [AG] + * +- * # Scripts-16.0.0.txt +- * # Date: 2024-04-30, 21:48:40 GMT ++ * # Scripts-17.0.0.txt ++ * # Date: 2025-07-24, 13:28:55 GMT + */ + + #include "hb.hh" +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh +index 48cd5296ffd..9993507e360 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh +@@ -396,6 +396,12 @@ hb_ot_shaper_categorize (hb_script_t script, + case HB_SCRIPT_TODHRI: + case HB_SCRIPT_TULU_TIGALARI: + ++ /* Unicode-17.0 additions */ ++ case HB_SCRIPT_BERIA_ERFE: ++ case HB_SCRIPT_SIDETIC: ++ case HB_SCRIPT_TAI_YO: ++ case HB_SCRIPT_TOLONG_SIKI: ++ + /* If the designer designed the font for the 'DFLT' script, + * (or we ended up arbitrarily pick 'latn'), use the default shaper. + * Otherwise, use the specific shaper. +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh +index 10165f57b75..28bc23d8f01 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh +@@ -352,7 +352,7 @@ struct AxisValue + { + float get_value (unsigned int axis_index) const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: hb_barrier (); return u.format1.get_value (); + case 2: hb_barrier (); return u.format2.get_value (); +@@ -364,7 +364,7 @@ struct AxisValue + + unsigned int get_axis_index () const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: hb_barrier (); return u.format1.get_axis_index (); + case 2: hb_barrier (); return u.format2.get_axis_index (); +@@ -376,7 +376,7 @@ struct AxisValue + + hb_ot_name_id_t get_value_name_id () const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: hb_barrier (); return u.format1.get_value_name_id (); + case 2: hb_barrier (); return u.format2.get_value_name_id (); +@@ -389,9 +389,9 @@ struct AxisValue + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { +- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); +- TRACE_DISPATCH (this, u.format); +- switch (u.format) { ++ if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); ++ TRACE_DISPATCH (this, u.format.v); ++ switch (u.format.v) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); +@@ -403,7 +403,7 @@ struct AxisValue + bool keep_axis_value (const hb_array_t axis_records, + hb_hashmap_t *user_axes_location) const + { +- switch (u.format) ++ switch (u.format.v) + { + case 1: hb_barrier (); return u.format1.keep_axis_value (axis_records, user_axes_location); + case 2: hb_barrier (); return u.format2.keep_axis_value (axis_records, user_axes_location); +@@ -420,7 +420,7 @@ struct AxisValue + return_trace (false); + hb_barrier (); + +- switch (u.format) ++ switch (u.format.v) + { + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); +@@ -433,14 +433,14 @@ struct AxisValue + protected: + union + { +- HBUINT16 format; ++ struct { HBUINT16 v; } format; + AxisValueFormat1 format1; + AxisValueFormat2 format2; + AxisValueFormat3 format3; + AxisValueFormat4 format4; + } u; + public: +- DEFINE_SIZE_UNION (2, format); ++ DEFINE_SIZE_UNION (2, format.v); + }; + + struct AxisValueOffsetArray: UnsizedArrayOf> +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh +index 50ddf5f6967..4933e661371 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh +@@ -6,8 +6,8 @@ + * + * on files with these headers: + * +- * +- * File-Date: 2025-01-21 ++ * ++ * File-Date: 2025-08-25 + */ + + #ifndef HB_OT_TAG_TABLE_HH +@@ -704,7 +704,7 @@ static const LangTag ot_languages3[] = { + /*{HB_TAG('g','u','z',' '), HB_TAG('G','U','Z',' ')},*/ /* Gusii */ + {HB_TAG('g','w','i',' '), HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ + {HB_TAG('g','y','n',' '), HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */ +- {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ ++ {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Hän -> Athapaskan */ + {HB_TAG('h','a','e',' '), HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ + {HB_TAG('h','a','i',' '), HB_TAG('H','A','I','0')}, /* Haida [macrolanguage] */ + {HB_TAG('h','a','k',' '), HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */ +@@ -921,7 +921,7 @@ static const LangTag ot_languages3[] = { + {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ + {HB_TAG('k','v','u',' '), HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */ + {HB_TAG('k','v','y',' '), HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */ +-/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakiutl -> Kwakʼwala */ ++/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakʼwala */ + {HB_TAG('k','w','w',' '), HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */ + {HB_TAG('k','w','y',' '), HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ + {HB_TAG('k','x','c',' '), HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh +index e26687c34ed..8a9307d6933 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh +@@ -143,10 +143,13 @@ struct AxisValueMap + + struct SegmentMaps : Array16Of + { +- int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const ++ float map_float (float value, unsigned int from_offset = 0, unsigned int to_offset = 1) const + { +-#define fromCoord coords[from_offset].to_int () +-#define toCoord coords[to_offset].to_int () ++#define fromCoord coords[from_offset].to_float () ++#define toCoord coords[to_offset].to_float () ++ ++ const auto *map = arrayZ; ++ + /* The following special-cases are not part of OpenType, which requires + * that at least -1, 0, and +1 must be mapped. But we include these as + * part of a better error recovery scheme. */ +@@ -155,47 +158,98 @@ struct SegmentMaps : Array16Of + if (!len) + return value; + else /* len == 1*/ +- return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; ++ return value - map[0].fromCoord + map[0].toCoord; + } + +- if (value <= arrayZ[0].fromCoord) +- return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; ++ // At least two mappings now. ++ ++ /* CoreText is wild... ++ * PingFangUI avar needs all this special-casing... ++ * So we implement an extended version of the spec here, ++ * which is more robust and more likely to be compatible with ++ * the wild. */ ++ ++ unsigned start = 0; ++ unsigned end = len; ++ if (map[start].fromCoord == -1 && map[start].toCoord == -1 && map[start+1].fromCoord == -1) ++ start++; ++ if (map[end-1].fromCoord == +1 && map[end-1].toCoord == +1 && map[end-2].fromCoord == +1) ++ end--; ++ ++ /* Look for exact match first, and do lots of special-casing. */ ++ unsigned i; ++ for (i = start; i < end; i++) ++ if (value == map[i].fromCoord) ++ break; ++ if (i < end) ++ { ++ // There's at least one exact match. See if there are more. ++ unsigned j = i; ++ for (; j + 1 < end; j++) ++ if (value != map[j + 1].fromCoord) ++ break; ++ ++ // [i,j] inclusive are all exact matches: ++ ++ // If there's only one, return it. This is the only spec-compliant case. ++ if (i == j) ++ return map[i].toCoord; ++ // If there's exactly three, return the middle one. ++ if (i + 2 == j) ++ return map[i + 1].toCoord; ++ ++ // Ignore the middle ones. Return the one mapping closer to 0. ++ if (value < 0) return map[j].toCoord; ++ if (value > 0) return map[i].toCoord; ++ ++ // Mapping 0? CoreText seems confused. It seems to prefer 0 here... ++ // So we'll just return the smallest one. lol ++ return fabsf (map[i].toCoord) < fabsf (map[j].toCoord) ? map[i].toCoord : map[j].toCoord; ++ ++ // Mapping 0? Return one not mapping to 0. ++ if (map[i].toCoord == 0) ++ return map[j].toCoord; ++ else ++ return map[i].toCoord; ++ } + +- unsigned int i; +- unsigned int count = len - 1; +- for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) +- ; ++ /* There's at least two and we're not an exact match. Prepare to lerp. */ + +- if (value >= arrayZ[i].fromCoord) +- return value - arrayZ[i].fromCoord + arrayZ[i].toCoord; ++ // Find the segment we're in. ++ for (i = start; i < end; i++) ++ if (value < map[i].fromCoord) ++ break; + +- if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord)) +- return arrayZ[i-1].toCoord; ++ if (i == 0) ++ { ++ // Value before all segments; Shift. ++ return value - map[0].fromCoord + map[0].toCoord; ++ } ++ if (i == end) ++ { ++ // Value after all segments; Shift. ++ return value - map[end - 1].fromCoord + map[end - 1].toCoord; ++ } ++ ++ // Actually interpolate. ++ auto &before = map[i-1]; ++ auto &after = map[i]; ++ float denom = after.fromCoord - before.fromCoord; // Can't be zero by now. ++ return before.toCoord + ((after.toCoord - before.toCoord) * (value - before.fromCoord)) / denom; + +- int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; +- return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) * +- (value - arrayZ[i-1].fromCoord)) / denom); + #undef toCoord + #undef fromCoord + } + +- int unmap (int value) const { return map (value, 1, 0); } ++ float unmap_float (float value) const { return map_float (value, 1, 0); } + ++ ++ // TODO Kill this. + Triple unmap_axis_range (const Triple& axis_range) const + { +- F2DOT14 val, unmapped_val; +- +- val.set_float (axis_range.minimum); +- unmapped_val.set_int (unmap (val.to_int ())); +- float unmapped_min = unmapped_val.to_float (); +- +- val.set_float (axis_range.middle); +- unmapped_val.set_int (unmap (val.to_int ())); +- float unmapped_middle = unmapped_val.to_float (); +- +- val.set_float (axis_range.maximum); +- unmapped_val.set_int (unmap (val.to_int ())); +- float unmapped_max = unmapped_val.to_float (); ++ float unmapped_min = unmap_float (axis_range.minimum); ++ float unmapped_middle = unmap_float (axis_range.middle); ++ float unmapped_max = unmap_float (axis_range.maximum); + + return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max}; + } +@@ -203,6 +257,11 @@ struct SegmentMaps : Array16Of + bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const + { + TRACE_SUBSET (this); ++ ++ /* This function cannot work on avar2 table (and currently doesn't). ++ * We should instead keep the design coords in the shape plan and use ++ * those. unmap_axis_range needs to be killed. */ ++ + /* avar mapped normalized axis range*/ + Triple *axis_range; + if (!c->plan->axes_location.has (axis_tag, &axis_range)) +@@ -304,14 +363,14 @@ struct avar + return_trace (true); + } + +- void map_coords (int *coords, unsigned int coords_length) const ++ void map_coords_16_16 (int *coords, unsigned int coords_length) const + { + unsigned int count = hb_min (coords_length, axisCount); + + const SegmentMaps *map = &firstAxisSegmentMaps; + for (unsigned int i = 0; i < count; i++) + { +- coords[i] = map->map (coords[i]); ++ coords[i] = roundf (map->map_float (coords[i] / 65536.f) * 65536.f); + map = &StructAfter (*map); + } + +@@ -329,15 +388,20 @@ struct avar + const auto &var_store = this+v2.varStore; + auto *var_store_cache = var_store.create_cache (); + ++ hb_vector_t 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 out; + out.alloc (coords_length); + for (unsigned i = 0; i < coords_length; i++) + { + int v = coords[i]; + uint32_t varidx = varidx_map.map (i); +- float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache); +- v += roundf (delta); +- v = hb_clamp (v, -(1<<14), +(1<<14)); ++ 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); + } + for (unsigned i = 0; i < coords_length; i++) +@@ -347,16 +411,54 @@ struct avar + #endif + } + +- void unmap_coords (int *coords, unsigned int coords_length) const ++ bool has_v2_data () const { return version.major > 1; } ++ ++ // axis normalization is done in 2.14 here ++ // TODO: deprecate this API once fonttools is updated to use 16.16 normalization ++ bool map_coords_2_14 (float *coords, unsigned int coords_length) const + { ++ hb_vector_t coords_2_14; ++ if (!coords_2_14.resize (coords_length)) return false; + unsigned int count = hb_min (coords_length, axisCount); + + const SegmentMaps *map = &firstAxisSegmentMaps; + for (unsigned int i = 0; i < count; i++) + { +- coords[i] = map->unmap (coords[i]); ++ int v = roundf (map->map_float (coords[i]) * 16384.f); ++ coords_2_14[i] = v; ++ coords[i] = v / 16384.f; + map = &StructAfter (*map); + } ++ ++#ifndef HB_NO_AVAR2 ++ if (version.major < 2) ++ return true; ++ hb_barrier (); ++ ++ for (; count < axisCount; count++) ++ map = &StructAfter (*map); ++ ++ const auto &v2 = * (const avarV2Tail *) map; ++ ++ const auto &varidx_map = this+v2.varIdxMap; ++ const auto &var_store = this+v2.varStore; ++ auto *var_store_cache = var_store.create_cache (); ++ ++ for (unsigned i = 0; i < coords_length; i++) ++ { ++ int v = coords_2_14[i]; ++ uint32_t varidx = varidx_map.map (i); ++ float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache); ++ v += roundf (delta); ++ v = hb_clamp (v, -(1<<16), +(1<<16)); ++ coords[i] = v / 16384.f; ++ } ++ ++ OT::ItemVariationStore::destroy_cache (var_store_cache); ++ return true; ++#else ++ return version.major < 2; ++#endif + } + + bool subset (hb_subset_context_t *c) const +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh +index 72deddef213..d0a4224c9b0 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh +@@ -27,24 +27,35 @@ + #define HB_OT_VAR_COMMON_HH + + #include "hb-ot-layout-common.hh" ++#include "hb-alloc-pool.hh" + #include "hb-priority-queue.hh" + #include "hb-subset-instancer-iup.hh" + + + namespace OT { + ++using rebase_tent_result_scratch_t = hb_pair_t; + + /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ + struct TupleVariationHeader + { + friend struct tuple_delta_t; +- unsigned get_size (unsigned axis_count) const +- { return min_size + get_all_tuples (axis_count).get_size (); } ++ unsigned get_size (unsigned axis_count_times_2) const ++ { ++ // This function is super hot in mega-var-fonts with hundreds of masters. ++ unsigned ti = tupleIndex; ++ if (unlikely ((ti & (TupleIndex::EmbeddedPeakTuple | TupleIndex::IntermediateRegion)))) ++ { ++ unsigned count = ((ti & TupleIndex::EmbeddedPeakTuple) != 0) + ((ti & TupleIndex::IntermediateRegion) != 0) * 2; ++ return min_size + count * axis_count_times_2; ++ } ++ return min_size; ++ } + + unsigned get_data_size () const { return varDataSize; } + +- const TupleVariationHeader &get_next (unsigned axis_count) const +- { return StructAtOffset (this, get_size (axis_count)); } ++ const TupleVariationHeader &get_next (unsigned axis_count_times_2) const ++ { return StructAtOffset (this, get_size (axis_count_times_2)); } + + bool unpack_axis_tuples (unsigned axis_count, + const hb_array_t shared_tuples, +@@ -53,7 +64,7 @@ struct TupleVariationHeader + { + const F2DOT14 *peak_tuple = nullptr; + if (has_peak ()) +- peak_tuple = get_peak_tuple (axis_count).arrayZ; ++ peak_tuple = get_peak_tuple (axis_count); + else + { + unsigned int index = get_index (); +@@ -68,8 +79,8 @@ struct TupleVariationHeader + + if (has_interm) + { +- start_tuple = get_start_tuple (axis_count).arrayZ; +- end_tuple = get_end_tuple (axis_count).arrayZ; ++ start_tuple = get_start_tuple (axis_count); ++ end_tuple = get_end_tuple (axis_count); + } + + for (unsigned i = 0; i < axis_count; i++) +@@ -98,88 +109,109 @@ struct TupleVariationHeader + return true; + } + ++ HB_ALWAYS_INLINE + double calculate_scalar (hb_array_t coords, unsigned int coord_count, + const hb_array_t shared_tuples, +- const hb_vector_t> *shared_tuple_active_idx = nullptr) const ++ hb_scalar_cache_t *shared_tuple_scalar_cache = nullptr) const + { ++ unsigned tuple_index = tupleIndex; ++ + const F2DOT14 *peak_tuple; + +- unsigned start_idx = 0; +- unsigned end_idx = coord_count; +- unsigned step = 1; ++ bool has_interm = tuple_index & TupleIndex::IntermediateRegion; // Inlined for performance + +- if (has_peak ()) +- peak_tuple = get_peak_tuple (coord_count).arrayZ; ++ if (unlikely (tuple_index & TupleIndex::EmbeddedPeakTuple)) // Inlined for performance ++ { ++ peak_tuple = get_peak_tuple (coord_count); ++ shared_tuple_scalar_cache = nullptr; ++ } + else + { +- unsigned int index = get_index (); +- if (unlikely ((index + 1) * coord_count > shared_tuples.length)) +- return 0.0; +- peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; ++ unsigned int index = tuple_index & TupleIndex::TupleIndexMask; // Inlined for performance + +- if (shared_tuple_active_idx) ++ float scalar; ++ if (shared_tuple_scalar_cache && ++ shared_tuple_scalar_cache->get (index, &scalar)) + { +- if (unlikely (index >= shared_tuple_active_idx->length)) +- return 0.0; +- auto _ = (*shared_tuple_active_idx).arrayZ[index]; +- if (_.second != -1) +- { +- start_idx = _.first; +- end_idx = _.second + 1; +- step = _.second - _.first; +- } +- else if (_.first != -1) +- { +- start_idx = _.first; +- end_idx = start_idx + 1; +- } ++ if (has_interm && (scalar != 0 && scalar != 1.f)) ++ shared_tuple_scalar_cache = nullptr; ++ else ++ return (double) scalar; + } ++ ++ if (unlikely ((index + 1) * coord_count > shared_tuples.length)) ++ return 0.0; ++ peak_tuple = shared_tuples.arrayZ + (coord_count * index); ++ + } + + const F2DOT14 *start_tuple = nullptr; + const F2DOT14 *end_tuple = nullptr; +- bool has_interm = has_intermediate (); ++ + if (has_interm) + { +- start_tuple = get_start_tuple (coord_count).arrayZ; +- end_tuple = get_end_tuple (coord_count).arrayZ; ++ start_tuple = get_start_tuple (coord_count); ++ end_tuple = get_end_tuple (coord_count); + } + + double scalar = 1.0; +- for (unsigned int i = start_idx; i < end_idx; i += step) ++#ifndef HB_OPTIMIZE_SIZE ++#if HB_FAST_NUM_ACCESS ++ bool skip = coord_count >= 16; ++#endif ++#endif ++ for (unsigned int i = 0; i < coord_count; i++) + { ++#ifndef HB_OPTIMIZE_SIZE ++#if HB_FAST_NUM_ACCESS ++ if (skip) ++ { ++ while (i + 4 <= coord_count && * (HBUINT64LE *) &peak_tuple[i] == 0) ++ i += 4; ++ while (i < coord_count && peak_tuple[i].to_int () == 0) ++ i += 1; ++ if (i >= coord_count) ++ break; ++ } ++#endif ++#endif ++ + int peak = peak_tuple[i].to_int (); + if (!peak) continue; + + int v = coords[i]; ++ if (!v) { scalar = 0.0; break; } + if (v == peak) continue; + + if (has_interm) + { ++ shared_tuple_scalar_cache = nullptr; + int start = start_tuple[i].to_int (); + int end = end_tuple[i].to_int (); + if (unlikely (start > peak || peak > end || + (start < 0 && end > 0 && peak))) continue; +- if (v < start || v > end) return 0.0; ++ if (v < start || v > end) { scalar = 0.0; break; } + if (v < peak) + { if (peak != start) scalar *= (double) (v - start) / (peak - start); } + else + { if (peak != end) scalar *= (double) (end - v) / (end - peak); } + } +- else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.0; ++ else if (v < hb_min (0, peak) || v > hb_max (0, peak)) { scalar = 0.0; break; } + else + scalar *= (double) v / peak; + } ++ if (shared_tuple_scalar_cache) ++ shared_tuple_scalar_cache->set (get_index (), scalar); + return scalar; + } + +- bool has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; } +- bool has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; } +- bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; } +- unsigned get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; } ++ bool has_peak () const { return tupleIndex & TupleIndex::EmbeddedPeakTuple; } ++ bool has_intermediate () const { return tupleIndex & TupleIndex::IntermediateRegion; } ++ bool has_private_points () const { return tupleIndex & TupleIndex::PrivatePointNumbers; } ++ unsigned get_index () const { return tupleIndex & TupleIndex::TupleIndexMask; } + + protected: +- struct TuppleIndex : HBUINT16 ++ struct TupleIndex : HBUINT16 + { + enum Flags { + EmbeddedPeakTuple = 0x8000u, +@@ -188,22 +220,24 @@ struct TupleVariationHeader + TupleIndexMask = 0x0FFFu + }; + +- TuppleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } ++ TupleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } + DEFINE_SIZE_STATIC (2); + }; + + hb_array_t get_all_tuples (unsigned axis_count) const + { return StructAfter> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); } +- hb_array_t get_peak_tuple (unsigned axis_count) const +- { return get_all_tuples (axis_count).sub_array (0, axis_count); } +- hb_array_t get_start_tuple (unsigned axis_count) const +- { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); } +- hb_array_t get_end_tuple (unsigned axis_count) const +- { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); } ++ const F2DOT14* get_all_tuples_base (unsigned axis_count) const ++ { return StructAfter> (tupleIndex).arrayZ; } ++ const F2DOT14* get_peak_tuple (unsigned axis_count) const ++ { return get_all_tuples_base (axis_count); } ++ const F2DOT14* get_start_tuple (unsigned axis_count) const ++ { return get_all_tuples_base (axis_count) + has_peak () * axis_count; } ++ const F2DOT14* get_end_tuple (unsigned axis_count) const ++ { return get_all_tuples_base (axis_count) + has_peak () * axis_count + axis_count; } + + HBUINT16 varDataSize; /* The size in bytes of the serialized + * data for this tuple variation table. */ +- TuppleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). ++ TupleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). + The low 12 bits are an index into a shared tuple + records array. */ + /* UnsizedArrayOf peakTuple - optional */ +@@ -221,6 +255,21 @@ struct TupleVariationHeader + DEFINE_SIZE_MIN (4); + }; + ++struct optimize_scratch_t ++{ ++ iup_scratch_t iup; ++ hb_vector_t opt_indices; ++ hb_vector_t rounded_x_deltas; ++ hb_vector_t rounded_y_deltas; ++ hb_vector_t opt_deltas_x; ++ hb_vector_t opt_deltas_y; ++ hb_vector_t opt_point_data; ++ hb_vector_t opt_deltas_data; ++ hb_vector_t point_data; ++ hb_vector_t deltas_data; ++ hb_vector_t rounded_deltas; ++}; ++ + struct tuple_delta_t + { + static constexpr bool realloc_move = true; // Watch out when adding new members! +@@ -241,11 +290,12 @@ struct tuple_delta_t + hb_vector_t compiled_tuple_header; + hb_vector_t compiled_deltas; + +- /* compiled peak coords, empty for non-gvar tuples */ +- hb_vector_t compiled_peak_coords; ++ hb_vector_t compiled_peak_coords; ++ hb_vector_t compiled_interm_coords; + +- tuple_delta_t () = default; ++ tuple_delta_t (hb_alloc_pool_t *pool = nullptr) {} + tuple_delta_t (const tuple_delta_t& o) = default; ++ tuple_delta_t& operator = (const tuple_delta_t& o) = default; + + friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept + { +@@ -267,6 +317,18 @@ struct tuple_delta_t + return *this; + } + ++ void copy_from (const tuple_delta_t& o, hb_alloc_pool_t *pool = nullptr) ++ { ++ axis_tuples = o.axis_tuples; ++ indices.duplicate_vector_from_pool (pool, o.indices); ++ deltas_x.duplicate_vector_from_pool (pool, o.deltas_x); ++ deltas_y.duplicate_vector_from_pool (pool, o.deltas_y); ++ compiled_tuple_header.duplicate_vector_from_pool (pool, o.compiled_tuple_header); ++ compiled_deltas.duplicate_vector_from_pool (pool, o.compiled_deltas); ++ compiled_peak_coords.duplicate_vector_from_pool (pool, o.compiled_peak_coords); ++ compiled_interm_coords.duplicate_vector_from_pool (pool, o.compiled_interm_coords); ++ } ++ + void remove_axis (hb_tag_t axis_tag) + { axis_tuples.del (axis_tag); } + +@@ -321,31 +383,44 @@ struct tuple_delta_t + return *this; + } + +- hb_vector_t change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, +- TripleDistances axis_triple_distances) const ++ void change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, ++ TripleDistances axis_triple_distances, ++ hb_vector_t& out, ++ rebase_tent_result_scratch_t &scratch, ++ hb_alloc_pool_t *pool = nullptr) + { +- hb_vector_t out; ++ // May move *this out. ++ ++ out.reset (); + Triple *tent; + if (!axis_tuples.has (axis_tag, &tent)) + { +- out.push (*this); +- return out; ++ out.push (std::move (*this)); ++ return; + } + + if ((tent->minimum < 0.0 && tent->maximum > 0.0) || + !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) +- return out; ++ return; + + if (tent->middle == 0.0) + { +- out.push (*this); +- return out; ++ out.push (std::move (*this)); ++ return; + } + +- rebase_tent_result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); +- for (auto &t : solutions) ++ rebase_tent_result_t &solutions = scratch.first; ++ rebase_tent (*tent, axis_limit, axis_triple_distances, solutions, scratch.second); ++ for (unsigned i = 0; i < solutions.length; i++) + { +- tuple_delta_t new_var = *this; ++ auto &t = solutions.arrayZ[i]; ++ ++ tuple_delta_t new_var; ++ if (i < solutions.length - 1) ++ new_var.copy_from (*this, pool); ++ else ++ new_var = std::move (*this); ++ + if (t.second == Triple ()) + new_var.remove_axis (axis_tag); + else +@@ -354,38 +429,76 @@ struct tuple_delta_t + new_var *= t.first; + out.push (std::move (new_var)); + } +- +- return out; + } + +- bool compile_peak_coords (const hb_map_t& axes_index_map, +- const hb_map_t& axes_old_index_tag_map) ++ bool compile_coords (const hb_map_t& axes_index_map, ++ const hb_map_t& axes_old_index_tag_map, ++ hb_alloc_pool_t *pool= nullptr) + { +- unsigned axis_count = axes_index_map.get_population (); +- if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size))) ++ unsigned cur_axis_count = axes_index_map.get_population (); ++ if (pool) ++ { ++ if (unlikely (!compiled_peak_coords.allocate_from_pool (pool, cur_axis_count))) ++ return false; ++ } ++ else if (unlikely (!compiled_peak_coords.resize (cur_axis_count))) + return false; + ++ hb_array_t start_coords, end_coords; ++ + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); ++ unsigned j = 0; + for (unsigned i = 0; i < orig_axis_count; i++) + { + if (!axes_index_map.has (i)) + continue; + + hb_tag_t axis_tag = axes_old_index_tag_map.get (i); +- Triple *coords; +- F2DOT14 peak_coord; ++ Triple *coords = nullptr; + if (axis_tuples.has (axis_tag, &coords)) +- peak_coord.set_float (coords->middle); +- else +- peak_coord.set_int (0); ++ { ++ float min_val = coords->minimum; ++ float val = coords->middle; ++ float max_val = coords->maximum; ++ ++ compiled_peak_coords.arrayZ[j].set_float (val); ++ ++ if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) ++ { ++ if (!compiled_interm_coords) ++ { ++ if (pool) ++ { ++ if (unlikely (!compiled_interm_coords.allocate_from_pool (pool, 2 * cur_axis_count))) ++ return false; ++ } ++ else if (unlikely (!compiled_interm_coords.resize (2 * cur_axis_count))) ++ return false; ++ start_coords = compiled_interm_coords.as_array ().sub_array (0, cur_axis_count); ++ end_coords = compiled_interm_coords.as_array ().sub_array (cur_axis_count); ++ ++ for (unsigned k = 0; k < j; k++) ++ { ++ signed peak = compiled_peak_coords.arrayZ[k].to_int (); ++ if (!peak) continue; ++ start_coords.arrayZ[k].set_int (hb_min (peak, 0)); ++ end_coords.arrayZ[k].set_int (hb_max (peak, 0)); ++ } ++ } ++ ++ } ++ ++ if (compiled_interm_coords) ++ { ++ start_coords.arrayZ[j].set_float (min_val); ++ end_coords.arrayZ[j].set_float (max_val); ++ } ++ } + +- /* push F2DOT14 value into char vector */ +- int16_t val = peak_coord.to_int (); +- compiled_peak_coords.push (static_cast (val >> 8)); +- compiled_peak_coords.push (static_cast (val & 0xFF)); ++ j++; + } + +- return !compiled_peak_coords.in_error (); ++ return !compiled_peak_coords.in_error () && !compiled_interm_coords.in_error (); + } + + /* deltas should be compiled already before we compile tuple +@@ -394,7 +507,8 @@ struct tuple_delta_t + bool compile_tuple_var_header (const hb_map_t& axes_index_map, + unsigned points_data_length, + const hb_map_t& axes_old_index_tag_map, +- const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) ++ const hb_hashmap_t*, unsigned>* shared_tuples_idx_map, ++ hb_alloc_pool_t *pool = nullptr) + { + /* compiled_deltas could be empty after iup delta optimization, we can skip + * compiling this tuple and return true */ +@@ -403,7 +517,7 @@ struct tuple_delta_t + unsigned cur_axis_count = axes_index_map.get_population (); + /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ + unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4; +- if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false; ++ if (unlikely (!compiled_tuple_header.allocate_from_pool (pool, alloc_len, false))) return false; + + unsigned flag = 0; + /* skip the first 4 header bytes: variationDataSize+tupleIndex */ +@@ -411,6 +525,9 @@ struct tuple_delta_t + F2DOT14* end = reinterpret_cast (compiled_tuple_header.end ()); + hb_array_t coords (p, end - p); + ++ if (!shared_tuples_idx_map) ++ compile_coords (axes_index_map, axes_old_index_tag_map); // non-gvar tuples do not have compiled coords yet ++ + /* encode peak coords */ + unsigned peak_count = 0; + unsigned *shared_tuple_idx; +@@ -421,16 +538,16 @@ struct tuple_delta_t + } + else + { +- peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); ++ peak_count = encode_peak_coords(coords, flag); + if (!peak_count) return false; + } + + /* encode interim coords, it's optional so returned num could be 0 */ +- unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); ++ unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag); + + /* pointdata length = 0 implies "use shared points" */ + if (points_data_length) +- flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; ++ flag |= TupleVariationHeader::TupleIndex::PrivatePointNumbers; + + unsigned serialized_data_size = points_data_length + compiled_deltas.length; + TupleVariationHeader *o = reinterpret_cast (compiled_tuple_header.begin ()); +@@ -438,105 +555,63 @@ struct tuple_delta_t + o->tupleIndex = flag; + + unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size); +- return compiled_tuple_header.resize (total_header_len); ++ compiled_tuple_header.shrink_back_to_pool (pool, total_header_len); ++ return true; + } + + unsigned encode_peak_coords (hb_array_t peak_coords, +- unsigned& flag, +- const hb_map_t& axes_index_map, +- const hb_map_t& axes_old_index_tag_map) const ++ unsigned& flag) const + { +- unsigned orig_axis_count = axes_old_index_tag_map.get_population (); +- auto it = peak_coords.iter (); +- unsigned count = 0; +- for (unsigned i = 0; i < orig_axis_count; i++) +- { +- if (!axes_index_map.has (i)) /* axis pinned */ +- continue; +- hb_tag_t axis_tag = axes_old_index_tag_map.get (i); +- Triple *coords; +- if (!axis_tuples.has (axis_tag, &coords)) +- (*it).set_int (0); +- else +- (*it).set_float (coords->middle); +- it++; +- count++; +- } +- flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple; +- return count; ++ hb_memcpy (&peak_coords[0], &compiled_peak_coords[0], compiled_peak_coords.length * sizeof (compiled_peak_coords[0])); ++ flag |= TupleVariationHeader::TupleIndex::EmbeddedPeakTuple; ++ return compiled_peak_coords.length; + } + + /* if no need to encode intermediate coords, then just return p */ + unsigned encode_interm_coords (hb_array_t coords, +- unsigned& flag, +- const hb_map_t& axes_index_map, +- const hb_map_t& axes_old_index_tag_map) const ++ unsigned& flag) const + { +- unsigned orig_axis_count = axes_old_index_tag_map.get_population (); +- unsigned cur_axis_count = axes_index_map.get_population (); +- +- auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter (); +- auto end_coords_iter = coords.sub_array (cur_axis_count).iter (); +- bool encode_needed = false; +- unsigned count = 0; +- for (unsigned i = 0; i < orig_axis_count; i++) ++ if (compiled_interm_coords) + { +- if (!axes_index_map.has (i)) /* axis pinned */ +- continue; +- hb_tag_t axis_tag = axes_old_index_tag_map.get (i); +- Triple *coords; +- float min_val = 0.f, val = 0.f, max_val = 0.f; +- if (axis_tuples.has (axis_tag, &coords)) +- { +- min_val = coords->minimum; +- val = coords->middle; +- max_val = coords->maximum; +- } +- +- (*start_coords_iter).set_float (min_val); +- (*end_coords_iter).set_float (max_val); +- +- start_coords_iter++; +- end_coords_iter++; +- count += 2; +- if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) +- encode_needed = true; +- } +- +- if (encode_needed) +- { +- flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion; +- return count; ++ hb_memcpy (&coords[0], &compiled_interm_coords[0], compiled_interm_coords.length * sizeof (compiled_interm_coords[0])); ++ flag |= TupleVariationHeader::TupleIndex::IntermediateRegion; + } +- return 0; ++ return compiled_interm_coords.length; + } + +- bool compile_deltas () +- { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } ++ bool compile_deltas (hb_vector_t &rounded_deltas_scratch, ++ hb_alloc_pool_t *pool = nullptr) ++ { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas, rounded_deltas_scratch, pool); } + + static bool compile_deltas (hb_array_t point_indices, + hb_array_t x_deltas, + hb_array_t y_deltas, +- hb_vector_t &compiled_deltas /* OUT */) ++ hb_vector_t &compiled_deltas, /* OUT */ ++ hb_vector_t &rounded_deltas, /* scratch */ ++ hb_alloc_pool_t *pool = nullptr) + { +- hb_vector_t rounded_deltas; +- if (unlikely (!rounded_deltas.alloc (point_indices.length))) ++ if (unlikely (!rounded_deltas.resize_dirty (point_indices.length))) + return false; + ++ unsigned j = 0; + for (unsigned i = 0; i < point_indices.length; i++) + { + if (!point_indices[i]) continue; +- int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); +- rounded_deltas.push (rounded_delta); ++ rounded_deltas.arrayZ[j++] = (int) roundf (x_deltas.arrayZ[i]); + } ++ rounded_deltas.resize (j); + + if (!rounded_deltas) return true; +- /* allocate enough memories 5 * num_deltas */ +- unsigned alloc_len = 5 * rounded_deltas.length; ++ /* Allocate enough memory: this is the correct bound: ++ * Worst case scenario is that each delta has to be encoded in 4 bytes, and there ++ * are runs of 64 items each. Any delta encoded in less than 4 bytes (2, 1, or 0) ++ * is still smaller than the 4-byte encoding even with their control byte. ++ * The initial 2 is to handle length==0, for both x and y deltas. */ ++ unsigned alloc_len = 2 + 4 * rounded_deltas.length + (rounded_deltas.length + 63) / 64; + if (y_deltas) + alloc_len *= 2; + +- if (unlikely (!compiled_deltas.resize (alloc_len))) return false; ++ if (unlikely (!compiled_deltas.allocate_from_pool (pool, alloc_len, false))) return false; + + unsigned encoded_len = compile_deltas (compiled_deltas, rounded_deltas); + +@@ -557,28 +632,30 @@ struct tuple_delta_t + if (j != rounded_deltas.length) return false; + encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); + } +- return compiled_deltas.resize (encoded_len); ++ compiled_deltas.shrink_back_to_pool (pool, encoded_len); ++ return true; + } + + static unsigned compile_deltas (hb_array_t encoded_bytes, + hb_array_t deltas) + { +- return TupleValues::compile (deltas, encoded_bytes); ++ return TupleValues::compile_unsafe (deltas, encoded_bytes); + } + +- bool calc_inferred_deltas (const contour_point_vector_t& orig_points) ++ bool calc_inferred_deltas (const contour_point_vector_t& orig_points, ++ hb_vector_t &scratch) + { + unsigned point_count = orig_points.length; + if (point_count != indices.length) + return false; + + unsigned ref_count = 0; +- hb_vector_t end_points; ++ ++ hb_vector_t &end_points = scratch.reset (); + + for (unsigned i = 0; i < point_count; i++) + { +- if (indices.arrayZ[i]) +- ref_count++; ++ ref_count += indices.arrayZ[i]; + if (orig_points.arrayZ[i].is_end_point) + end_points.push (i); + } +@@ -587,7 +664,7 @@ struct tuple_delta_t + return true; + if (unlikely (end_points.in_error ())) return false; + +- hb_set_t inferred_idxes; ++ hb_bit_set_t inferred_idxes; + unsigned start_point = 0; + for (unsigned end_point : end_points) + { +@@ -661,6 +738,7 @@ struct tuple_delta_t + + bool optimize (const contour_point_vector_t& contour_points, + bool is_composite, ++ optimize_scratch_t &scratch, + double tolerance = 0.5 + 1e-10) + { + unsigned count = contour_points.length; +@@ -668,22 +746,21 @@ struct tuple_delta_t + deltas_y.length != count) + return false; + +- hb_vector_t opt_indices; +- hb_vector_t rounded_x_deltas, rounded_y_deltas; ++ hb_vector_t &opt_indices = scratch.opt_indices.reset (); ++ hb_vector_t &rounded_x_deltas = scratch.rounded_x_deltas; ++ hb_vector_t &rounded_y_deltas = scratch.rounded_y_deltas; + +- if (unlikely (!rounded_x_deltas.alloc (count) || +- !rounded_y_deltas.alloc (count))) ++ if (unlikely (!rounded_x_deltas.resize_dirty (count) || ++ !rounded_y_deltas.resize_dirty (count))) + return false; + + for (unsigned i = 0; i < count; i++) + { +- int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); +- int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); +- rounded_x_deltas.push (rounded_x_delta); +- rounded_y_deltas.push (rounded_y_delta); ++ rounded_x_deltas.arrayZ[i] = (int) roundf (deltas_x.arrayZ[i]); ++ rounded_y_deltas.arrayZ[i] = (int) roundf (deltas_y.arrayZ[i]); + } + +- if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) ++ if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, scratch.iup, tolerance)) + return false; + + unsigned ref_count = 0; +@@ -692,7 +769,8 @@ struct tuple_delta_t + + if (ref_count == count) return true; + +- hb_vector_t opt_deltas_x, opt_deltas_y; ++ hb_vector_t &opt_deltas_x = scratch.opt_deltas_x.reset (); ++ hb_vector_t &opt_deltas_y = scratch.opt_deltas_y.reset (); + bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); + if (is_comp_glyph_wo_deltas) + { +@@ -705,34 +783,31 @@ struct tuple_delta_t + opt_indices.arrayZ[i] = false; + } + +- hb_vector_t opt_point_data; ++ hb_vector_t &opt_point_data = scratch.opt_point_data.reset (); + if (!compile_point_set (opt_indices, opt_point_data)) + return false; +- hb_vector_t opt_deltas_data; ++ hb_vector_t &opt_deltas_data = scratch.opt_deltas_data.reset (); + if (!compile_deltas (opt_indices, + is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, + is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, +- opt_deltas_data)) ++ opt_deltas_data, ++ scratch.rounded_deltas)) + return false; + +- hb_vector_t point_data; ++ hb_vector_t &point_data = scratch.point_data.reset (); + if (!compile_point_set (indices, point_data)) + return false; +- hb_vector_t deltas_data; +- if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) ++ hb_vector_t &deltas_data = scratch.deltas_data.reset (); ++ if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data, scratch.rounded_deltas)) + return false; + + if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) + { +- indices.fini (); + indices = std::move (opt_indices); + + if (is_comp_glyph_wo_deltas) + { +- deltas_x.fini (); + deltas_x = std::move (opt_deltas_x); +- +- deltas_y.fini (); + deltas_y = std::move (opt_deltas_y); + } + } +@@ -757,7 +832,7 @@ struct tuple_delta_t + + /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ + unsigned num_bytes = 2 + 3 *num_points; +- if (unlikely (!compiled_points.resize (num_bytes, false))) ++ if (unlikely (!compiled_points.resize_dirty (num_bytes))) + return false; + + unsigned pos = 0; +@@ -821,7 +896,7 @@ struct tuple_delta_t + else + compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; + } +- return compiled_points.resize (pos, false); ++ return compiled_points.resize_dirty (pos); + } + + static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta) +@@ -852,15 +927,15 @@ struct TupleVariationData + return_trace (c->check_struct (this)); + } + +- unsigned get_size (unsigned axis_count) const ++ unsigned get_size (unsigned axis_count_times_2) const + { + unsigned total_size = min_size; + unsigned count = tupleVarCount.get_count (); + const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header()); + for (unsigned i = 0; i < count; i++) + { +- total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size (); +- tuple_var_header = &tuple_var_header->get_next (axis_count); ++ total_size += tuple_var_header->get_size (axis_count_times_2) + tuple_var_header->get_data_size (); ++ tuple_var_header = &tuple_var_header->get_next (axis_count_times_2); + } + + return total_size; +@@ -925,8 +1000,12 @@ struct TupleVariationData + const hb_map_t *axes_old_index_tag_map, + const hb_vector_t &shared_indices, + const hb_array_t shared_tuples, +- bool is_composite_glyph) ++ hb_alloc_pool_t *pool = nullptr, ++ bool is_composite_glyph = false) + { ++ hb_vector_t private_indices; ++ hb_vector_t deltas_x; ++ hb_vector_t deltas_y; + do + { + const HBUINT8 *p = iterator.get_serialized_data (); +@@ -939,7 +1018,7 @@ struct TupleVariationData + || axis_tuples.is_empty ()) + return false; + +- hb_vector_t private_indices; ++ private_indices.reset (); + bool has_private_points = iterator.current_tuple->has_private_points (); + const HBUINT8 *end = p + length; + if (has_private_points && +@@ -950,27 +1029,24 @@ struct TupleVariationData + bool apply_to_all = (indices.length == 0); + unsigned num_deltas = apply_to_all ? point_count : indices.length; + +- hb_vector_t deltas_x; +- +- if (unlikely (!deltas_x.resize (num_deltas, false) || ++ if (unlikely (!deltas_x.resize_dirty (num_deltas) || + !TupleVariationData::decompile_deltas (p, deltas_x, end))) + return false; + +- hb_vector_t deltas_y; + if (is_gvar) + { +- if (unlikely (!deltas_y.resize (num_deltas, false) || ++ if (unlikely (!deltas_y.resize_dirty (num_deltas) || + !TupleVariationData::decompile_deltas (p, deltas_y, end))) + return false; + } + + tuple_delta_t var; + var.axis_tuples = std::move (axis_tuples); +- if (unlikely (!var.indices.resize (point_count) || +- !var.deltas_x.resize (point_count, false))) ++ if (unlikely (!var.indices.allocate_from_pool (pool, point_count) || ++ !var.deltas_x.allocate_from_pool (pool, point_count, false))) + return false; + +- if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) ++ if (is_gvar && unlikely (!var.deltas_y.allocate_from_pool (pool, point_count, false))) + return false; + + for (unsigned i = 0; i < num_deltas; i++) +@@ -1012,8 +1088,8 @@ struct TupleVariationData + /* In VarData, deltas are organized in rows, convert them into + * column(region) based tuples, resize deltas_x first */ + tuple_delta_t tuple; +- if (!tuple.deltas_x.resize (item_count, false) || +- !tuple.indices.resize (item_count, false)) ++ if (!tuple.deltas_x.resize_dirty (item_count) || ++ !tuple.indices.resize_dirty (item_count)) + return false; + + for (unsigned i = 0; i < item_count; i++) +@@ -1041,7 +1117,8 @@ struct TupleVariationData + } + + bool change_tuple_variations_axis_limits (const hb_hashmap_t& normalized_axes_location, +- const hb_hashmap_t& axes_triple_distances) ++ const hb_hashmap_t& axes_triple_distances, ++ hb_alloc_pool_t *pool = nullptr) + { + /* sort axis_tag/axis_limits, make result deterministic */ + hb_vector_t axis_tags; +@@ -1050,6 +1127,10 @@ struct TupleVariationData + for (auto t : normalized_axes_location.keys ()) + axis_tags.push (t); + ++ // Reused vectors for reduced malloc pressure. ++ rebase_tent_result_scratch_t scratch; ++ hb_vector_t out; ++ + axis_tags.qsort (_cmp_axis_tag); + for (auto axis_tag : axis_tags) + { +@@ -1061,9 +1142,10 @@ struct TupleVariationData + axis_triple_distances = axes_triple_distances.get (axis_tag); + + hb_vector_t new_vars; +- for (const tuple_delta_t& var : tuple_vars) ++ for (tuple_delta_t& var : tuple_vars) + { +- hb_vector_t out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances); ++ // This may move var out. ++ var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances, out, scratch, pool); + if (!out) continue; + + unsigned new_len = new_vars.length + out.length; +@@ -1074,7 +1156,6 @@ struct TupleVariationData + for (unsigned i = 0; i < out.length; i++) + new_vars.push (std::move (out[i])); + } +- tuple_vars.fini (); + tuple_vars = std::move (new_vars); + } + return true; +@@ -1085,9 +1166,12 @@ struct TupleVariationData + bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) + { + hb_vector_t new_vars; ++ // The pre-allocation is essential for address stability of pointers ++ // we store in the hashmap. ++ if (unlikely (!new_vars.alloc (tuple_vars.length))) ++ return false; + hb_hashmap_t*, unsigned> m; +- unsigned i = 0; +- for (const tuple_delta_t& var : tuple_vars) ++ for (tuple_delta_t& var : tuple_vars) + { + /* if all axes are pinned, drop the tuple variation */ + if (var.axis_tuples.is_empty ()) +@@ -1107,13 +1191,17 @@ struct TupleVariationData + } + else + { +- new_vars.push (var); +- if (!m.set (&(var.axis_tuples), i)) ++ auto *new_var = new_vars.push (); ++ if (unlikely (new_vars.in_error ())) ++ return false; ++ hb_swap (*new_var, var); ++ if (unlikely (!m.set (&(new_var->axis_tuples), new_vars.length - 1))) + return false; +- i++; + } + } +- tuple_vars.fini (); ++ m.fini (); // Just in case, since it points into new_vars data. ++ // Shouldn't be necessary though, since we only move new_vars, not its ++ // contents. + tuple_vars = std::move (new_vars); + return true; + } +@@ -1173,20 +1261,22 @@ struct TupleVariationData + } + } + +- bool calc_inferred_deltas (const contour_point_vector_t& contour_points) ++ bool calc_inferred_deltas (const contour_point_vector_t& contour_points, ++ hb_vector_t &scratch) + { + for (tuple_delta_t& var : tuple_vars) +- if (!var.calc_inferred_deltas (contour_points)) ++ if (!var.calc_inferred_deltas (contour_points, scratch)) + return false; + + return true; + } + +- bool iup_optimize (const contour_point_vector_t& contour_points) ++ bool iup_optimize (const contour_point_vector_t& contour_points, ++ optimize_scratch_t &scratch) + { + for (tuple_delta_t& var : tuple_vars) + { +- if (!var.optimize (contour_points, is_composite)) ++ if (!var.optimize (contour_points, is_composite, scratch)) + return false; + } + return true; +@@ -1195,16 +1285,21 @@ struct TupleVariationData + public: + bool instantiate (const hb_hashmap_t& normalized_axes_location, + const hb_hashmap_t& axes_triple_distances, ++ optimize_scratch_t &scratch, ++ hb_alloc_pool_t *pool = nullptr, + contour_point_vector_t* contour_points = nullptr, + bool optimize = false) + { + if (!tuple_vars) return true; +- if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) ++ if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances, pool)) + return false; + /* compute inferred deltas only for gvar */ + if (contour_points) +- if (!calc_inferred_deltas (*contour_points)) ++ { ++ hb_vector_t scratch; ++ if (!calc_inferred_deltas (*contour_points, scratch)) + return false; ++ } + + /* if iup delta opt is on, contour_points can't be null */ + if (optimize && !contour_points) +@@ -1213,7 +1308,7 @@ struct TupleVariationData + if (!merge_tuple_variations (optimize ? contour_points : nullptr)) + return false; + +- if (optimize && !iup_optimize (*contour_points)) return false; ++ if (optimize && !iup_optimize (*contour_points, scratch)) return false; + return !tuple_vars.in_error (); + } + +@@ -1221,7 +1316,8 @@ struct TupleVariationData + const hb_map_t& axes_old_index_tag_map, + bool use_shared_points, + bool is_gvar = false, +- const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr) ++ const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr, ++ hb_alloc_pool_t *pool = nullptr) + { + // return true for empty glyph + if (!tuple_vars) +@@ -1241,6 +1337,7 @@ struct TupleVariationData + if (shared_points_bytes) + compiled_byte_size += shared_points_bytes->length; + } ++ hb_vector_t rounded_deltas_scratch; + // compile delta and tuple var header for each tuple variation + for (auto& tuple: tuple_vars) + { +@@ -1254,12 +1351,13 @@ struct TupleVariationData + * this tuple */ + if (!points_data->length) + continue; +- if (!tuple.compile_deltas ()) ++ if (!tuple.compile_deltas (rounded_deltas_scratch, pool)) + return false; + + unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; + if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, +- shared_tuples_idx_map)) ++ shared_tuples_idx_map, ++ pool)) + return false; + compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; + } +@@ -1330,8 +1428,9 @@ struct TupleVariationData + { + var_data_bytes = var_data_bytes_; + var_data = var_data_bytes_.as (); +- index = 0; ++ tuples_left = var_data->tupleVarCount.get_count (); + axis_count = axis_count_; ++ axis_count_times_2 = axis_count_ * 2; + current_tuple = &var_data->get_tuple_var_header (); + data_offset = 0; + table_base = table_base_; +@@ -1349,30 +1448,42 @@ struct TupleVariationData + return true; + } + +- bool is_valid () const ++ bool is_valid () + { +- return (index < var_data->tupleVarCount.get_count ()) && +- var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) && +- var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), +- current_tuple->get_size (axis_count))); ++ if (unlikely (tuples_left <= 0)) ++ return false; ++ ++ current_tuple_size = TupleVariationHeader::min_size; ++ if (unlikely (!var_data_bytes.check_end ((const char *) current_tuple + current_tuple_size))) ++ return false; ++ ++ current_tuple_size = current_tuple->get_size (axis_count_times_2); ++ if (unlikely (!var_data_bytes.check_end ((const char *) current_tuple + current_tuple_size))) ++ return false; ++ ++ return true; + } + ++ HB_ALWAYS_INLINE + bool move_to_next () + { + data_offset += current_tuple->get_data_size (); +- current_tuple = ¤t_tuple->get_next (axis_count); +- index++; ++ current_tuple = &StructAtOffset (current_tuple, current_tuple_size); ++ tuples_left--; + return is_valid (); + } + ++ // TODO: Make it return (sanitized) hb_bytes_t + const HBUINT8 *get_serialized_data () const + { return &(table_base+var_data->data) + data_offset; } + + private: ++ signed tuples_left; + const TupleVariationData *var_data; +- unsigned int index; + unsigned int axis_count; ++ unsigned int axis_count_times_2; + unsigned int data_offset; ++ unsigned int current_tuple_size; + const void *table_base; + + public: +@@ -1411,7 +1522,7 @@ struct TupleVariationData + if (unlikely (p + 1 > end)) return false; + count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; + } +- if (unlikely (!points.resize (count, false))) return false; ++ if (unlikely (!points.resize_dirty (count))) return false; + + unsigned n = 0; + unsigned i = 0; +@@ -1446,12 +1557,14 @@ struct TupleVariationData + } + + template ++ HB_ALWAYS_INLINE + static bool decompile_deltas (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &deltas /* IN/OUT */, + const HBUINT8 *end, +- bool consume_all = false) ++ bool consume_all = false, ++ unsigned start = 0) + { +- return TupleValues::decompile (p, deltas, end, consume_all); ++ return TupleValues::decompile (p, deltas, end, consume_all, start); + } + + bool has_data () const { return tupleVarCount; } +@@ -1463,6 +1576,7 @@ struct TupleVariationData + const hb_vector_t &shared_indices, + const hb_array_t shared_tuples, + tuple_variations_t& tuple_variations, /* OUT */ ++ hb_alloc_pool_t *pool = nullptr, + bool is_composite_glyph = false) const + { + return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, +@@ -1470,6 +1584,7 @@ struct TupleVariationData + axes_old_index_tag_map, + shared_indices, + shared_tuples, ++ pool, + is_composite_glyph); + } + +@@ -1634,8 +1749,9 @@ struct item_variations_t + bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, + const hb_hashmap_t& axes_triple_distances) + { ++ optimize_scratch_t scratch; + for (tuple_variations_t& tuple_vars : vars) +- if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances)) ++ if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances, scratch)) + return false; + + if (!build_region_list ()) return false; +@@ -1720,30 +1836,28 @@ struct item_variations_t + + struct combined_gain_idx_tuple_t + { +- int gain; +- unsigned idx_1; +- unsigned idx_2; ++ uint64_t encoded; + + combined_gain_idx_tuple_t () = default; +- combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j) +- :gain (gain_), idx_1 (i), idx_2 (j) {} ++ combined_gain_idx_tuple_t (unsigned gain, unsigned i, unsigned j) ++ : encoded ((uint64_t (0xFFFFFF - gain) << 40) | (uint64_t (i) << 20) | uint64_t (j)) ++ { ++ assert (gain < 0xFFFFFF); ++ assert (i < 0xFFFFFFF && j < 0xFFFFFFF); ++ } + + bool operator < (const combined_gain_idx_tuple_t& o) + { +- if (gain != o.gain) +- return gain < o.gain; +- +- if (idx_1 != o.idx_1) +- return idx_1 < o.idx_1; +- +- return idx_2 < o.idx_2; ++ return encoded < o.encoded; + } + + bool operator <= (const combined_gain_idx_tuple_t& o) + { +- if (*this < o) return true; +- return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2; ++ return encoded <= o.encoded; + } ++ ++ unsigned idx_1 () const { return (encoded >> 20) & 0xFFFFF; }; ++ unsigned idx_2 () const { return encoded & 0xFFFFF; }; + }; + + bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) +@@ -1765,9 +1879,9 @@ struct item_variations_t + hb_hashmap_t*> front_mapping; + unsigned start_row = 0; + hb_vector_t encoding_objs; +- hb_hashmap_t, unsigned> chars_idx_map; + + /* delta_rows map, used for filtering out duplicate rows */ ++ hb_vector_t *> major_rows; + hb_hashmap_t*, unsigned> delta_rows_map; + for (unsigned major = 0; major < vars.length; major++) + { +@@ -1775,6 +1889,9 @@ struct item_variations_t + * (row based) delta */ + const tuple_variations_t& tuples = vars[major]; + unsigned num_rows = var_data_num_rows[major]; ++ ++ if (!num_rows) continue; ++ + for (const tuple_delta_t& tuple: tuples.tuple_vars) + { + if (tuple.deltas_x.length != num_rows) +@@ -1789,24 +1906,11 @@ struct item_variations_t + { + int rounded_delta = roundf (tuple.deltas_x[i]); + delta_rows[start_row + i][*col_idx] += rounded_delta; +- if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535)) +- has_long = true; ++ has_long |= rounded_delta < -65536 || rounded_delta > 65535; + } + } + +- if (!optimize) +- { +- /* assemble a delta_row_encoding_t for this subtable, skip optimization so +- * chars is not initialized, we only need delta rows for serialization */ +- delta_row_encoding_t obj; +- for (unsigned r = start_row; r < start_row + num_rows; r++) +- obj.add_row (&(delta_rows.arrayZ[r])); +- +- encodings.push (std::move (obj)); +- start_row += num_rows; +- continue; +- } +- ++ major_rows.reset (); + for (unsigned minor = 0; minor < num_rows; minor++) + { + const hb_vector_t& row = delta_rows[start_row + minor]; +@@ -1828,42 +1932,40 @@ struct item_variations_t + if (!front_mapping.set ((major<<16) + minor, &row)) + return false; + +- hb_vector_t chars = delta_row_encoding_t::get_row_chars (row); +- if (!chars) return false; +- + if (delta_rows_map.has (&row)) + continue; + + delta_rows_map.set (&row, 1); +- unsigned *obj_idx; +- if (chars_idx_map.has (chars, &obj_idx)) +- { +- delta_row_encoding_t& obj = encoding_objs[*obj_idx]; +- if (!obj.add_row (&row)) +- return false; +- } +- else +- { +- if (!chars_idx_map.set (chars, encoding_objs.length)) +- return false; +- delta_row_encoding_t obj (std::move (chars), &row); +- encoding_objs.push (std::move (obj)); +- } ++ ++ major_rows.push (&row); + } + ++ if (major_rows) ++ encoding_objs.push (delta_row_encoding_t (std::move (major_rows), num_cols)); ++ + start_row += num_rows; + } + + /* return directly if no optimization, maintain original VariationIndex so + * varidx_map would be empty */ +- if (!optimize) return !encodings.in_error (); ++ if (!optimize) ++ { ++ encodings = std::move (encoding_objs); ++ return !encodings.in_error (); ++ } ++ ++ /* NOTE: Fonttools instancer always optimizes VarStore from scratch. This ++ * is too costly for large fonts. So, instead, we retain the encodings of ++ * the original VarStore, and just try to combine them if possible. This ++ * is a compromise between optimization and performance and practically ++ * works very well. */ + +- /* sort encoding_objs */ ++ // This produces slightly smaller results in some cases. + encoding_objs.qsort (); + +- /* main algorithm: repeatedly pick 2 best encodings to combine, and combine +- * them */ +- hb_priority_queue_t queue; ++ /* main algorithm: repeatedly pick 2 best encodings to combine, and combine them */ ++ using item_t = hb_priority_queue_t::item_t; ++ hb_vector_t queue_items; + unsigned num_todos = encoding_objs.length; + for (unsigned i = 0; i < num_todos; i++) + { +@@ -1871,16 +1973,18 @@ struct item_variations_t + { + int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]); + if (combining_gain > 0) +- queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0); ++ queue_items.push (item_t (combined_gain_idx_tuple_t (combining_gain, i, j), 0)); + } + } + +- hb_set_t removed_todo_idxes; ++ hb_priority_queue_t queue (std::move (queue_items)); ++ ++ hb_bit_set_t removed_todo_idxes; + while (queue) + { + auto t = queue.pop_minimum ().first; +- unsigned i = t.idx_1; +- unsigned j = t.idx_2; ++ unsigned i = t.idx_1 (); ++ unsigned j = t.idx_2 (); + + if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j)) + continue; +@@ -1891,40 +1995,36 @@ struct item_variations_t + removed_todo_idxes.add (i); + removed_todo_idxes.add (j); + +- hb_vector_t combined_chars; +- if (!combined_chars.alloc (encoding.chars.length)) +- return false; +- +- for (unsigned idx = 0; idx < encoding.chars.length; idx++) +- { +- uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]); +- combined_chars.push (v); +- } +- +- delta_row_encoding_t combined_encoding_obj (std::move (combined_chars)); +- for (const auto& row : hb_concat (encoding.items, other_encoding.items)) +- combined_encoding_obj.add_row (row); ++ encoding.merge (other_encoding); + + for (unsigned idx = 0; idx < encoding_objs.length; idx++) + { + if (removed_todo_idxes.has (idx)) continue; + + const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx]; +- if (obj.chars == combined_chars) ++ // In the unlikely event that the same encoding exists already, combine it. ++ if (obj.width == encoding.width && obj.chars == encoding.chars) + { ++ // This is straight port from fonttools algorithm. I added this branch there ++ // because I thought it can happen. But looks like we never get in here in ++ // practice. I'm not confident enough to remove it though; in theory it can ++ // happen. I think it's just that our tests are not extensive enough to hit ++ // this path. ++ + for (const auto& row : obj.items) +- combined_encoding_obj.add_row (row); ++ encoding.add_row (row); + + removed_todo_idxes.add (idx); + continue; + } + +- int combined_gain = combined_encoding_obj.gain_from_merging (obj); ++ int combined_gain = encoding.gain_from_merging (obj); + if (combined_gain > 0) +- queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0); ++ queue.insert (combined_gain_idx_tuple_t (combined_gain, idx, encoding_objs.length), 0); + } + +- encoding_objs.push (std::move (combined_encoding_obj)); ++ auto moved_encoding = std::move (encoding); ++ encoding_objs.push (moved_encoding); + } + + int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population (); +@@ -1937,9 +2037,6 @@ struct item_variations_t + encodings.push (std::move (encoding_objs.arrayZ[i])); + } + +- /* sort again based on width, make result deterministic */ +- encodings.qsort (delta_row_encoding_t::cmp_width); +- + return compile_varidx_map (front_mapping); + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh +index 3dc4ebaebd8..d8f497d5346 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh +@@ -84,7 +84,7 @@ struct cvar + if (!coords) return true; + hb_vector_t shared_indices; + TupleVariationData<>::tuple_iterator_t iterator; +- unsigned var_data_length = tuple_var_data->get_size (axis_count); ++ unsigned var_data_length = tuple_var_data->get_size (axis_count * 2); + hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast (tuple_var_data), var_data_length); + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base, + shared_indices, &iterator)) +@@ -113,7 +113,7 @@ struct cvar + + bool apply_to_all = (indices.length == 0); + unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; +- if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; ++ if (unlikely (!unpacked_deltas.resize_dirty (num_deltas))) return false; + if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; + + for (unsigned int i = 0; i < num_deltas; i++) +@@ -158,7 +158,8 @@ struct cvar + tuple_variations)) + return_trace (false); + +- if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) ++ optimize_scratch_t scratch; ++ if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances, scratch)) + return_trace (false); + + if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map, +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh +index f2725eaa282..74d392de9b7 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh +@@ -179,7 +179,7 @@ struct AxisRecord + + hb_tag_t get_axis_tag () const { return axisTag; } + +- int normalize_axis_value (float v) const ++ float normalize_axis_value (float v) const + { + float min_value, default_value, max_value; + get_coordinates (min_value, default_value, max_value); +@@ -189,23 +189,9 @@ struct AxisRecord + if (v == default_value) + return 0; + else if (v < default_value) +- v = (v - default_value) / (default_value - min_value); ++ return (v - default_value) / (default_value - min_value); + else +- v = (v - default_value) / (max_value - default_value); +- return roundf (v * 16384.f); +- } +- +- float unnormalize_axis_value (int v) const +- { +- float min_value, default_value, max_value; +- get_coordinates (min_value, default_value, max_value); +- +- if (v == 0) +- return default_value; +- else if (v < 0) +- return v * (default_value - min_value) / 16384.f + default_value; +- else +- return v * (max_value - default_value) / 16384.f + default_value; ++ return (v - default_value) / (max_value - default_value); + } + + hb_ot_name_id_t get_name_id () const { return axisNameID; } +@@ -341,12 +327,9 @@ struct fvar + return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true); + } + +- int normalize_axis_value (unsigned int axis_index, float v) const ++ float normalize_axis_value (unsigned int axis_index, float v) const + { return get_axes ()[axis_index].normalize_axis_value (v); } + +- float unnormalize_axis_value (unsigned int axis_index, int v) const +- { return get_axes ()[axis_index].unnormalize_axis_value (v); } +- + unsigned int get_instance_count () const { return instanceCount; } + + hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh +index 9f9b5be3cbe..7c42f548456 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh +@@ -66,12 +66,14 @@ struct glyph_variations_t + + hb_vector_t glyph_variations; + +- hb_vector_t compiled_shared_tuples; ++ hb_vector_t compiled_shared_tuples; + private: + unsigned shared_tuples_count = 0; + + /* shared coords-> index map after instantiation */ +- hb_hashmap_t*, unsigned> shared_tuples_idx_map; ++ hb_hashmap_t*, unsigned> shared_tuples_idx_map; ++ ++ hb_alloc_pool_t pool; + + public: + unsigned compiled_shared_tuples_count () const +@@ -128,6 +130,7 @@ struct glyph_variations_t + iterator, &(plan->axes_old_index_tag_map), + shared_indices, shared_tuples, + tuple_vars, /* OUT */ ++ &pool, + is_composite_glyph)) + return false; + glyph_variations.push (std::move (tuple_vars)); +@@ -139,6 +142,7 @@ struct glyph_variations_t + { + unsigned count = plan->new_to_old_gid_list.length; + bool iup_optimize = false; ++ optimize_scratch_t scratch; + iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; + for (unsigned i = 0; i < count; i++) + { +@@ -146,7 +150,7 @@ struct glyph_variations_t + contour_point_vector_t *all_points; + if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) + return false; +- if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) ++ if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, scratch, &pool, all_points, iup_optimize)) + return false; + } + return true; +@@ -161,7 +165,8 @@ struct glyph_variations_t + if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, + true, /* use shared points*/ + true, +- &shared_tuples_idx_map)) ++ &shared_tuples_idx_map, ++ &pool)) + return false; + + return true; +@@ -172,20 +177,21 @@ struct glyph_variations_t + { + /* key is pointer to compiled_peak_coords inside each tuple, hashing + * function will always deref pointers first */ +- hb_hashmap_t*, unsigned> coords_count_map; ++ hb_hashmap_t*, unsigned> coords_count_map; + + /* count the num of shared coords */ + for (tuple_variations_t& vars: glyph_variations) + { + for (tuple_delta_t& var : vars.tuple_vars) + { +- if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map)) ++ if (!var.compile_coords (axes_index_map, axes_old_index_tag_map, &pool)) + return false; +- unsigned* count; +- if (coords_count_map.has (&(var.compiled_peak_coords), &count)) +- coords_count_map.set (&(var.compiled_peak_coords), *count + 1); ++ unsigned *count; ++ unsigned hash = hb_hash (&var.compiled_peak_coords); ++ if (coords_count_map.has_with_hash (&(var.compiled_peak_coords), hash, &count)) ++ (*count)++; + else +- coords_count_map.set (&(var.compiled_peak_coords), 1); ++ coords_count_map.set_with_hash (&(var.compiled_peak_coords), hash, 1); + } + } + +@@ -193,66 +199,45 @@ struct glyph_variations_t + return false; + + /* add only those coords that are used more than once into the vector and sort */ +- hb_vector_t*> shared_coords; +- if (unlikely (!shared_coords.alloc (coords_count_map.get_population ()))) +- return false; +- +- for (const auto _ : coords_count_map.iter ()) +- { +- if (_.second == 1) continue; +- shared_coords.push (_.first); +- } ++ hb_vector_t*, unsigned>> shared_coords { ++ + hb_iter (coords_count_map) ++ | hb_filter ([] (const hb_pair_t*, unsigned>& p) { return p.second > 1; }) ++ }; ++ if (unlikely (shared_coords.in_error ())) return false; + + /* no shared tuples: no coords are used more than once */ + if (!shared_coords) return true; + /* sorting based on the coords frequency first (high to low), then compare + * the coords bytes */ +- hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t*), _cmp_coords, (void *) (&coords_count_map)); ++ shared_coords.qsort (_cmp_coords); + + /* build shared_coords->idx map and shared tuples byte array */ + + shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length); +- unsigned len = shared_tuples_count * (shared_coords[0]->length); ++ unsigned len = shared_tuples_count * (shared_coords[0].first->length); + if (unlikely (!compiled_shared_tuples.alloc (len))) + return false; + + for (unsigned i = 0; i < shared_tuples_count; i++) + { +- shared_tuples_idx_map.set (shared_coords[i], i); ++ shared_tuples_idx_map.set (shared_coords[i].first, i); + /* add a concat() in hb_vector_t? */ +- for (char c : shared_coords[i]->iter ()) ++ for (auto c : shared_coords[i].first->iter ()) + compiled_shared_tuples.push (c); + } + + return true; + } + +- static int _cmp_coords (const void *pa, const void *pb, void *arg) ++ static int _cmp_coords (const void *pa, const void *pb) + { +- const hb_hashmap_t*, unsigned>* coords_count_map = +- reinterpret_cast*, unsigned>*> (arg); +- +- /* shared_coords is hb_vector_t*> so casting pa/pb +- * to be a pointer to a pointer */ +- const hb_vector_t** a = reinterpret_cast**> (const_cast(pa)); +- const hb_vector_t** b = reinterpret_cast**> (const_cast(pb)); +- +- bool has_a = coords_count_map->has (*a); +- bool has_b = coords_count_map->has (*b); +- +- if (has_a && has_b) +- { +- unsigned a_num = coords_count_map->get (*a); +- unsigned b_num = coords_count_map->get (*b); ++ const hb_pair_t *, unsigned> *a = (const hb_pair_t *, unsigned> *) pa; ++ const hb_pair_t *, unsigned> *b = (const hb_pair_t *, unsigned> *) pb; + +- if (a_num != b_num) +- return b_num - a_num; ++ if (a->second != b->second) ++ return b->second - a->second; // high to low + +- return (*b)->as_array().cmp ((*a)->as_array ()); +- } +- else if (has_a) return -1; +- else if (has_b) return 1; +- else return 0; ++ return b->first->as_array().cmp (a->first->as_array ()); + } + + templatesharedTuples = 0; + else + { +- hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); ++ hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); + if (!shared_tuples.arrayZ) return_trace (false); +- out->sharedTuples = shared_tuples.arrayZ - (char *) out; ++ out->sharedTuples = (const char *) shared_tuples.arrayZ - (char *) out; + } + + char *glyph_var_data = c->start_embed (); +@@ -463,10 +448,18 @@ struct gvar_GVAR + if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + it++; + unsigned int subset_data_size = 0; ++ unsigned padding_size = 0; + for (auto &_ : it) + { + hb_codepoint_t old_gid = _.second; +- subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; ++ unsigned glyph_data_size = get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; ++ if (glyph_data_size % 2) ++ { ++ glyph_data_size++; ++ padding_size++; ++ } ++ ++ subset_data_size += glyph_data_size; + } + + /* According to the spec: If the short format (Offset16) is used for offsets, +@@ -495,6 +488,8 @@ struct gvar_GVAR + + /* This ordering relative to the shared tuples array, which puts the glyphVariationData + last in the table, is required when HB_SUBSET_FLAGS_IFTB_REQUIREMENTS is set */ ++ if (long_offset) ++ subset_data_size -= padding_size; + char *subset_data = c->serializer->allocate_size (subset_data_size, false); + if (!subset_data) return_trace (false); + out->dataZ = subset_data - (char *) out; +@@ -533,8 +528,16 @@ struct gvar_GVAR + old_gid); + + hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); +- subset_data += var_data_bytes.length; +- glyph_offset += var_data_bytes.length; ++ unsigned glyph_data_size = var_data_bytes.length; ++ subset_data += glyph_data_size; ++ glyph_offset += glyph_data_size; ++ ++ if (!long_offset && (glyph_data_size % 2)) ++ { ++ *subset_data = 0; ++ subset_data++; ++ glyph_offset++; ++ } + + if (long_offset) + ((HBUINT32 *) subset_offsets)[gid] = glyph_offset; +@@ -582,6 +585,17 @@ struct gvar_GVAR + public: + struct accelerator_t + { ++ ++ hb_scalar_cache_t *create_cache () const ++ { ++ return hb_scalar_cache_t::create (table->sharedTupleCount); ++ } ++ ++ static void destroy_cache (hb_scalar_cache_t *cache) ++ { ++ hb_scalar_cache_t::destroy (cache); ++ } ++ + bool has_data () const { return table->has_data (); } + + accelerator_t (hb_face_t *face) +@@ -589,36 +603,6 @@ struct gvar_GVAR + table = hb_sanitize_context_t ().reference_table (face); + /* If sanitize failed, set glyphCount to 0. */ + glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; +- +- /* For shared tuples that only have one or two axes active, shared the index +- * of that axis as a cache. This will speed up caclulate_scalar() a lot +- * for fonts with lots of axes and many "monovar" or "duovar" tuples. */ +- hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); +- unsigned count = table->sharedTupleCount; +- if (unlikely (!shared_tuple_active_idx.resize (count, false))) return; +- unsigned axis_count = table->axisCount; +- for (unsigned i = 0; i < count; i++) +- { +- hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count); +- int idx1 = -1, idx2 = -1; +- for (unsigned j = 0; j < axis_count; j++) +- { +- const F2DOT14 &peak = tuple.arrayZ[j]; +- if (peak.to_int () != 0) +- { +- if (idx1 == -1) +- idx1 = j; +- else if (idx2 == -1) +- idx2 = j; +- else +- { +- idx1 = idx2 = -1; +- break; +- } +- } +- } +- shared_tuple_active_idx.arrayZ[i] = {idx1, idx2}; +- } + } + ~accelerator_t () { table.destroy (); } + +@@ -655,6 +639,7 @@ struct gvar_GVAR + hb_array_t coords, + const hb_array_t points, + hb_glyf_scratch_t &scratch, ++ hb_scalar_cache_t *gvar_cache = nullptr, + bool phantom_only = false) const + { + if (unlikely (glyph >= glyphCount)) return true; +@@ -690,10 +675,12 @@ struct gvar_GVAR + + unsigned count = points.length; + bool flush = false; ++ + do + { + float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples, +- &shared_tuple_active_idx); ++ gvar_cache); ++ + if (scalar == 0.f) continue; + const HBUINT8 *p = iterator.get_serialized_data (); + unsigned int length = iterator.current_tuple->get_data_size (); +@@ -702,7 +689,7 @@ struct gvar_GVAR + + if (!deltas) + { +- if (unlikely (!deltas_vec.resize (count, false))) return false; ++ if (unlikely (!deltas_vec.resize_dirty (count))) return false; + deltas = deltas_vec.as_array (); + hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, + (phantom_only ? 4 : count) * sizeof (deltas[0])); +@@ -717,11 +704,12 @@ struct gvar_GVAR + const hb_array_t &indices = has_private_points ? private_indices : shared_indices; + + bool apply_to_all = (indices.length == 0); +- unsigned int num_deltas = apply_to_all ? points.length : indices.length; +- if (unlikely (!x_deltas.resize (num_deltas, false))) return false; +- if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end))) return false; +- if (unlikely (!y_deltas.resize (num_deltas, false))) return false; +- if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end))) return false; ++ unsigned num_deltas = apply_to_all ? points.length : indices.length; ++ unsigned start_deltas = (apply_to_all && phantom_only && num_deltas >= 4 ? num_deltas - 4 : 0); ++ if (unlikely (!x_deltas.resize_dirty (num_deltas))) return false; ++ if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end, false, start_deltas))) return false; ++ if (unlikely (!y_deltas.resize_dirty (num_deltas))) return false; ++ if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end, false, start_deltas))) return false; + + if (!apply_to_all) + { +@@ -884,7 +872,6 @@ struct gvar_GVAR + private: + hb_blob_ptr_t table; + unsigned glyphCount; +- hb_vector_t> shared_tuple_active_idx; + }; + + protected: +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh +index 40a85a62b78..652d738e7b5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh +@@ -42,57 +42,62 @@ struct index_map_subset_plan_t + VORG_INDEX + }; + +- void init (const DeltaSetIndexMap &index_map, ++ void init (const DeltaSetIndexMap *index_map, + hb_inc_bimap_t &outer_map, + hb_vector_t &inner_sets, + const hb_subset_plan_t *plan, + bool bypass_empty = true) + { + map_count = 0; +- outer_bit_count = 0; +- inner_bit_count = 1; + max_inners.init (); + output_map.init (); + +- if (bypass_empty && !index_map.get_map_count ()) return; ++ if (bypass_empty && (!index_map || !index_map->get_map_count ())) return; + + unsigned int last_val = (unsigned int)-1; + hb_codepoint_t last_gid = HB_CODEPOINT_INVALID; + +- outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); + max_inners.resize (inner_sets.length); + for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; + + /* Search backwards for a map value different from the last map value */ + auto &new_to_old_gid_list = plan->new_to_old_gid_list; + unsigned count = new_to_old_gid_list.length; +- for (unsigned j = count; j; j--) ++ if (!index_map) + { +- hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; +- hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; +- +- unsigned int v = index_map.map (old_gid); +- if (last_gid == HB_CODEPOINT_INVALID) ++ map_count = new_to_old_gid_list.tail ().first + 1; ++ } ++ else ++ { ++ for (unsigned j = count; j; j--) + { ++ hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; ++ hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; ++ ++ unsigned int v = index_map->map (old_gid); ++ if (last_gid == HB_CODEPOINT_INVALID) ++ { + last_val = v; + last_gid = gid; + continue; +- } +- if (v != last_val) ++ } ++ if (v != last_val) + break; + +- last_gid = gid; ++ last_gid = gid; ++ } ++ ++ if (unlikely (last_gid == (hb_codepoint_t)-1)) return; ++ map_count = last_gid + 1; + } + +- if (unlikely (last_gid == (hb_codepoint_t)-1)) return; +- map_count = last_gid + 1; + for (auto _ : plan->new_to_old_gid_list) + { + hb_codepoint_t gid = _.first; + if (gid >= map_count) break; + + hb_codepoint_t old_gid = _.second; +- unsigned int v = index_map.map (old_gid); ++ unsigned int v = index_map ? index_map->map (old_gid): old_gid; + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + outer_map.add (outer); +@@ -113,6 +118,9 @@ struct index_map_subset_plan_t + const hb_vector_t &inner_maps, + const hb_subset_plan_t *plan) + { ++ outer_bit_count = 1; ++ inner_bit_count = 1; ++ + for (unsigned int i = 0; i < max_inners.length; i++) + { + if (inner_maps[i].get_population () == 0) continue; +@@ -128,9 +136,13 @@ struct index_map_subset_plan_t + + if (unlikely (new_gid >= map_count)) break; + +- uint32_t v = input_map->map (old_gid); +- unsigned int outer = v >> 16; +- output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); ++ uint32_t v = input_map? input_map->map (old_gid) : old_gid; ++ unsigned outer = v >> 16; ++ unsigned new_outer = outer_map[outer]; ++ unsigned bit_count = (new_outer == 0) ? 1 : hb_bit_storage (new_outer); ++ outer_bit_count = hb_max (bit_count, outer_bit_count); ++ ++ output_map.arrayZ[new_gid] = (new_outer << 16) | (inner_maps[outer][v & 0xFFFF]); + } + } + +@@ -204,8 +216,8 @@ struct hvarvvar_subset_plan_t + if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return; + + bool retain_adv_map = false; +- index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false); +- if (index_maps[0] == &Null (DeltaSetIndexMap)) ++ index_map_plans[0].init (index_maps[0], outer_map, inner_sets, plan, false); ++ if (!index_maps[0]) + { + retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; + outer_map.add (0); +@@ -215,7 +227,7 @@ struct hvarvvar_subset_plan_t + } + + for (unsigned int i = 1; i < index_maps.length; i++) +- index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan); ++ index_map_plans[i].init (index_maps[i], outer_map, inner_sets, plan); + + outer_map.sort (); + +@@ -284,6 +296,8 @@ struct HVARVVAR + static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; + static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; + ++ bool has_data () const { return version.major != 0; } ++ + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); +@@ -301,9 +315,14 @@ struct HVARVVAR + + void listup_index_maps (hb_vector_t &index_maps) const + { +- index_maps.push (&(this+advMap)); +- index_maps.push (&(this+lsbMap)); +- index_maps.push (&(this+rsbMap)); ++ if (advMap) index_maps.push (&(this+advMap)); ++ else index_maps.push (nullptr); ++ ++ if (lsbMap) index_maps.push (&(this+lsbMap)); ++ else index_maps.push (nullptr); ++ ++ if (rsbMap) index_maps.push (&(this+rsbMap)); ++ else index_maps.push (nullptr); + } + + bool serialize_index_maps (hb_serialize_context_t *c, +@@ -382,9 +401,10 @@ struct HVARVVAR + hvar_plan.index_map_plans.as_array ())); + } + ++ HB_ALWAYS_INLINE + float get_advance_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, +- ItemVariationStore::cache_t *store_cache = nullptr) const ++ hb_scalar_cache_t *store_cache = nullptr) const + { + uint32_t varidx = (this+advMap).map (glyph); + return (this+varStore).get_delta (varidx, +@@ -392,16 +412,6 @@ struct HVARVVAR + store_cache); + } + +- bool get_lsb_delta_unscaled (hb_codepoint_t glyph, +- const int *coords, unsigned int coord_count, +- float *lsb) const +- { +- if (!lsbMap) return false; +- uint32_t varidx = (this+lsbMap).map (glyph); +- *lsb = (this+varStore).get_delta (varidx, coords, coord_count); +- return true; +- } +- + public: + FixedVersion<>version; /* Version of the metrics variation table + * initially set to 0x00010000u */ +@@ -435,7 +445,8 @@ struct VVAR : HVARVVAR { + void listup_index_maps (hb_vector_t &index_maps) const + { + HVARVVAR::listup_index_maps (index_maps); +- index_maps.push (&(this+vorgMap)); ++ if (vorgMap) index_maps.push (&(this+vorgMap)); ++ else index_maps.push (nullptr); + } + + bool serialize_index_maps (hb_serialize_context_t *c, +@@ -454,14 +465,16 @@ struct VVAR : HVARVVAR { + + bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset (c); } + +- bool get_vorg_delta_unscaled (hb_codepoint_t glyph, +- const int *coords, unsigned int coord_count, +- float *delta) const ++ HB_ALWAYS_INLINE ++ float get_vorg_delta_unscaled (hb_codepoint_t glyph, ++ const int *coords, unsigned int coord_count, ++ hb_scalar_cache_t *store_cache = nullptr) const + { +- if (!vorgMap) return false; ++ if (!vorgMap) return 0.f; + uint32_t varidx = (this+vorgMap).map (glyph); +- *delta = (this+varStore).get_delta (varidx, coords, coord_count); +- return true; ++ return (this+varStore).get_delta (varidx, ++ coords, coord_count, ++ store_cache); + } + + protected: +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc +index 8c695c41e24..4d594d587d8 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc +@@ -286,10 +286,14 @@ hb_ot_var_normalize_variations (hb_face_t *face, + hb_ot_var_axis_info_t info; + if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && + info.axis_index < coords_length) +- coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); ++ coords[info.axis_index] = roundf (fvar.normalize_axis_value (info.axis_index, variations[i].value) * 65536.0f); + } + +- face->table.avar->map_coords (coords, coords_length); ++ face->table.avar->map_coords_16_16 (coords, coords_length); ++ ++ // Round to 2.14 ++ for (unsigned i = 0; i < coords_length; i++) ++ coords[i] = (coords[i] + 2) >> 2; + } + + /** +@@ -309,6 +313,10 @@ hb_ot_var_normalize_variations (hb_face_t *face, + * Any additional scaling defined in the face's `avar` table is also + * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar + * ++ * Note: @coords_length must be the same as the number of axes in the face, as ++ * for example returned by hb_ot_var_get_axis_count(). ++ * Otherwise, the behavior is undefined. ++ * + * Since: 1.4.2 + **/ + void +@@ -319,9 +327,13 @@ hb_ot_var_normalize_coords (hb_face_t *face, + { + const OT::fvar &fvar = *face->table.fvar; + for (unsigned int i = 0; i < coords_length; i++) +- normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); ++ normalized_coords[i] = roundf (fvar.normalize_axis_value (i, design_coords[i]) * 65536.0f); ++ ++ face->table.avar->map_coords_16_16 (normalized_coords, coords_length); + +- face->table.avar->map_coords (normalized_coords, coords_length); ++ // Round to 2.14 ++ for (unsigned i = 0; i < coords_length; i++) ++ normalized_coords[i] = (normalized_coords[i] + 2) >> 2; + } + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh +index b2300a327da..ff7ce678e4e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh +@@ -61,6 +61,7 @@ struct VORG + + bool has_data () const { return version.to_int (); } + ++ HB_ALWAYS_INLINE + int get_y_origin (hb_codepoint_t glyph) const + { + unsigned int i; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-outline.cc b/src/java.desktop/share/native/libharfbuzz/hb-outline.cc +index 85ffc793678..12963fe46e3 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-outline.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-outline.cc +@@ -84,6 +84,15 @@ void hb_outline_t::replay (hb_draw_funcs_t *pen, void *pen_data) const + } + } + ++void hb_outline_t::translate (float dx, float dy) ++{ ++ for (auto &p : points) ++ { ++ p.x += dx; ++ p.y += dy; ++ } ++} ++ + void hb_outline_t::slant (float slant_xy) + { + for (auto &p : points) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-outline.hh b/src/java.desktop/share/native/libharfbuzz/hb-outline.hh +index c5b68c05dd7..9e394a68d9c 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-outline.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-outline.hh +@@ -69,6 +69,7 @@ struct hb_outline_t + + HB_INTERNAL void replay (hb_draw_funcs_t *pen, void *pen_data) const; + HB_INTERNAL float control_area () const; ++ HB_INTERNAL void translate (float dx, float dy); + HB_INTERNAL void slant (float slant_xy); + HB_INTERNAL void embolden (float x_strength, float y_strength, + float x_shift, float y_shift); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc +index bc08c5a9e14..e867f37f3c5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc +@@ -49,7 +49,7 @@ hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED, + { + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + +- c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy}); ++ c->push_transform (hb_transform_t<> {xx, yx, xy, yy, dx, dy}); + } + + static void +@@ -71,7 +71,7 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, + { + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + +- hb_extents_t extents; ++ hb_extents_t<> extents; + hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs (); + hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); + c->push_clip (extents); +@@ -85,7 +85,7 @@ hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, + { + hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + +- hb_extents_t extents = {xmin, ymin, xmax, ymax}; ++ hb_extents_t<> extents = {xmin, ymin, xmax, ymax}; + c->push_clip (extents); + } + +@@ -136,10 +136,10 @@ hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, + if (!glyph_extents) + return false; // Happens with SVG images. + +- hb_extents_t extents = {(float) glyph_extents->x_bearing, +- (float) glyph_extents->y_bearing + glyph_extents->height, +- (float) glyph_extents->x_bearing + glyph_extents->width, +- (float) glyph_extents->y_bearing}; ++ hb_extents_t<> extents = {(float) glyph_extents->x_bearing, ++ (float) glyph_extents->y_bearing + glyph_extents->height, ++ (float) glyph_extents->x_bearing + glyph_extents->width, ++ (float) glyph_extents->y_bearing}; + c->push_clip (extents); + c->paint (); + c->pop_clip (); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh +index 60374eaa2d2..531eb3c7c52 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh +@@ -41,9 +41,9 @@ struct hb_paint_extents_context_t + clips.clear (); + groups.clear (); + +- transforms.push (hb_transform_t{}); +- clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED}); +- groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); ++ transforms.push (hb_transform_t<>{}); ++ clips.push (hb_bounds_t<>{hb_bounds_t<>::UNBOUNDED}); ++ groups.push (hb_bounds_t<>{hb_bounds_t<>::EMPTY}); + } + + hb_paint_extents_context_t () +@@ -51,19 +51,19 @@ struct hb_paint_extents_context_t + clear (); + } + +- hb_extents_t get_extents () ++ hb_extents_t<> get_extents () + { + return groups.tail().extents; + } + + bool is_bounded () + { +- return groups.tail().status != hb_bounds_t::UNBOUNDED; ++ return groups.tail().status != hb_bounds_t<>::UNBOUNDED; + } + +- void push_transform (const hb_transform_t &trans) ++ void push_transform (const hb_transform_t<> &trans) + { +- hb_transform_t t = transforms.tail (); ++ hb_transform_t<> t = transforms.tail (); + t.multiply (trans); + transforms.push (t); + } +@@ -73,13 +73,13 @@ struct hb_paint_extents_context_t + transforms.pop (); + } + +- void push_clip (hb_extents_t extents) ++ void push_clip (hb_extents_t<> extents) + { + /* Transform extents and push a new clip. */ +- const hb_transform_t &t = transforms.tail (); ++ const hb_transform_t<> &t = transforms.tail (); + t.transform_extents (extents); + +- auto bounds = hb_bounds_t {extents}; ++ auto bounds = hb_bounds_t<> {extents}; + bounds.intersect (clips.tail ()); + + clips.push (bounds); +@@ -92,19 +92,19 @@ struct hb_paint_extents_context_t + + void push_group () + { +- groups.push (hb_bounds_t {hb_bounds_t::EMPTY}); ++ groups.push (hb_bounds_t<> {hb_bounds_t<>::EMPTY}); + } + + void pop_group (hb_paint_composite_mode_t mode) + { +- const hb_bounds_t src_bounds = groups.pop (); +- hb_bounds_t &backdrop_bounds = groups.tail (); ++ const hb_bounds_t<> src_bounds = groups.pop (); ++ hb_bounds_t<> &backdrop_bounds = groups.tail (); + + // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite + switch ((int) mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: +- backdrop_bounds.status = hb_bounds_t::EMPTY; ++ backdrop_bounds.status = hb_bounds_t<>::EMPTY; + break; + case HB_PAINT_COMPOSITE_MODE_SRC: + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: +@@ -125,16 +125,16 @@ struct hb_paint_extents_context_t + + void paint () + { +- const hb_bounds_t &clip = clips.tail (); +- hb_bounds_t &group = groups.tail (); ++ const hb_bounds_t<> &clip = clips.tail (); ++ hb_bounds_t<> &group = groups.tail (); + + group.union_ (clip); + } + + protected: +- hb_vector_t transforms; +- hb_vector_t clips; +- hb_vector_t groups; ++ hb_vector_t> transforms; ++ hb_vector_t> clips; ++ hb_vector_t> groups; + }; + + HB_INTERNAL hb_paint_funcs_t * +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh +index 2abadebab3c..aedbcbdcbe2 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh +@@ -28,6 +28,7 @@ + #include "hb.hh" + #include "hb-face.hh" + #include "hb-font.hh" ++#include "hb-geometry.hh" + + #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ + HB_PAINT_FUNC_IMPLEMENT (push_transform) \ +@@ -72,7 +73,11 @@ struct hb_paint_funcs_t + float xx, float yx, + float xy, float yy, + float dx, float dy) +- { func.push_transform (this, paint_data, ++ { ++ // Handle -0.f to avoid -0.f == 0.f in the transform matrix. ++ if (dx == -0.f) dx = 0.f; ++ if (dy == -0.f) dy = 0.f; ++ func.push_transform (this, paint_data, + xx, yx, xy, yy, dx, dy, + !user_data ? nullptr : user_data->push_transform); } + void pop_transform (void *paint_data) +@@ -182,54 +187,59 @@ struct hb_paint_funcs_t + 0, 0); + } + +- HB_NODISCARD +- bool push_translate (void *paint_data, +- float dx, float dy) ++ void push_transform (void *paint_data, hb_transform_t t) + { +- if (!dx && !dy) +- return false; ++ push_transform (paint_data, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0); ++ } + ++ void push_translate (void *paint_data, ++ float dx, float dy) ++ { + push_transform (paint_data, +- 1.f, 0.f, 0.f, 1.f, dx, dy); +- return true; ++ hb_transform_t::translation (dx, dy)); + } + +- HB_NODISCARD +- bool push_scale (void *paint_data, ++ void push_scale (void *paint_data, + float sx, float sy) + { +- if (sx == 1.f && sy == 1.f) +- return false; +- + push_transform (paint_data, +- sx, 0.f, 0.f, sy, 0.f, 0.f); +- return true; ++ hb_transform_t::scaling (sx, sy)); ++ } ++ void push_scale_around_center (void *paint_data, ++ float sx, float sy, ++ float cx, float cy) ++ { ++ push_transform (paint_data, ++ hb_transform_t::scaling_around_center (sx, sy, cx, cy)); + } + +- HB_NODISCARD +- bool push_rotate (void *paint_data, ++ void push_rotate (void *paint_data, + float a) + { +- if (!a) +- return false; ++ push_transform (paint_data, ++ hb_transform_t::rotation (a * HB_PI)); ++ } + +- float cc = cosf (a * HB_PI); +- float ss = sinf (a * HB_PI); +- push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f); +- return true; ++ void push_rotate_around_center (void *paint_data, ++ float a, ++ float cx, float cy) ++ { ++ push_transform (paint_data, ++ hb_transform_t::rotation_around_center (a * HB_PI, cx, cy)); + } + +- HB_NODISCARD +- bool push_skew (void *paint_data, ++ void push_skew (void *paint_data, + float sx, float sy) + { +- if (!sx && !sy) +- return false; +- +- float x = tanf (-sx * HB_PI); +- float y = tanf (+sy * HB_PI); +- push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f); +- return true; ++ push_transform (paint_data, ++ hb_transform_t::skewing (-sx * HB_PI, sy * HB_PI)); ++ } ++ void push_skew_around_center (void *paint_data, ++ float sx, float sy, ++ float cx, float cy) ++ { ++ push_transform (paint_data, ++ hb_transform_t::skewing_around_center (-sx * HB_PI, sy * HB_PI, cx, cy)); + } + }; + DECLARE_NULL_INSTANCE (hb_paint_funcs_t); +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh +index 274d5df4c54..753e86b8ca6 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh +@@ -45,12 +45,22 @@ + template + struct hb_priority_queue_t + { +- private: ++ public: + typedef hb_pair_t item_t; ++ ++ private: + hb_vector_t heap; + + public: + ++ hb_priority_queue_t () = default; ++ hb_priority_queue_t (hb_vector_t&& other) : heap (std::move (other)) ++ { ++ // Heapify the vector. ++ for (int i = (heap.length / 2) - 1; i >= 0; i--) ++ bubble_down (i); ++ } ++ + void reset () { heap.resize (0); } + + bool in_error () const { return heap.in_error (); } +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh +index cb4fdeead2e..7d118b52169 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh +@@ -217,11 +217,17 @@ bool _try_isolating_subgraphs (const hb_vector_t& over + unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u); + if (roots_to_isolate.get_population () > maximum_to_move) { + // Only move at most half of the roots in a space at a time. +- unsigned extra = roots_to_isolate.get_population () - maximum_to_move; +- while (extra--) { +- uint32_t root = HB_SET_VALUE_INVALID; +- roots_to_isolate.previous (&root); +- roots_to_isolate.del (root); ++ // ++ // Note: this was ported from non-stable ids to stable ids. So to retain the same behaviour ++ // with regards to which roots are removed from the set we need to remove them in the topological ++ // order, not the object id order. ++ int extra = roots_to_isolate.get_population () - maximum_to_move; ++ for (unsigned id : sorted_graph.ordering_) { ++ if (!extra) break; ++ if (roots_to_isolate.has(id)) { ++ roots_to_isolate.del(id); ++ extra--; ++ } + } + } + +@@ -266,7 +272,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf + result = sorted_graph.duplicate(&parents, r.child); + } + +- if (result == (unsigned) -1) return result; ++ if (result == (unsigned) -1) return false; + + if (parents.get_population() > 1) { + // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. +@@ -283,7 +289,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf + sorted_graph.vertices_[result].give_max_priority(); + } + +- return result; ++ return true; + } + + static inline +@@ -302,8 +308,11 @@ bool _process_overflows (const hb_vector_t& overflows, + { + // The child object is shared, we may be able to eliminate the overflow + // by duplicating it. +- if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; +- return true; ++ if (_resolve_shared_overflow(overflows, i, sorted_graph)) ++ return true; ++ ++ // Sometimes we can't duplicate a node which looks shared because it's not actually shared ++ // (eg. all links from the same parent) in this case continue on to other resolution options. + } + + if (child.is_leaf () && !priority_bumped_parents.has (r.parent)) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh +index 1f8ba32bae2..1e9ee9ba960 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh +@@ -64,9 +64,6 @@ + * + * - Cast blob content to T*, call sanitize() method of it, + * - If sanitize succeeded, return blob. +- * - Otherwise, if blob is not writable, try making it writable, +- * or copy if cannot be made writable in-place, +- * - Call sanitize() again. Return blob if sanitize succeeded. + * - Return empty blob otherwise. + * + * +@@ -98,6 +95,12 @@ + * structure is so complicated that by checking all offsets at sanitize() time, + * we make the code much simpler in other methods, as offsets and referenced + * objects do not need to be validated at each use site. ++ * ++ * Note: ++ * Sanitize was named so because it used to try to recover from errors by ++ * modifying the data to make it valid. This is no longer the case, as it ++ * could make HarfBuzz hallucinate new rules if there was aliasing in the ++ * data. However, the name stuck. See: https://behdad.github.io/harfbust/ + */ + + /* This limits sanitizing time on really broken fonts. */ +@@ -120,12 +123,12 @@ + struct hb_sanitize_context_t : + hb_dispatch_context_t + { +- hb_sanitize_context_t () : +- start (nullptr), end (nullptr), ++ hb_sanitize_context_t (const char *start_ = nullptr, const char *end_ = nullptr) : ++ start (start_), end (end_), + length (0), + max_ops (0), max_subtables (0), + recursion_depth (0), +- writable (false), edit_count (0), ++ writable (false), + blob (nullptr), + num_glyphs (65536), + num_glyphs_set (false), +@@ -212,14 +215,22 @@ struct hb_sanitize_context_t : + + void reset_object () + { +- this->start = this->blob->data; +- this->end = this->start + this->blob->length; ++ if (this->blob) ++ { ++ this->start = this->blob->data; ++ this->end = this->start + this->blob->length; ++ } + this->length = this->end - this->start; + assert (this->start <= this->end); /* Must not overflow. */ + } + +- void start_processing () ++ void start_processing (const char *start_ = nullptr, const char *end_ = nullptr) + { ++ if (start_) ++ { ++ this->start = start_; ++ this->end = end_; ++ } + reset_object (); + unsigned m; + if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m))) +@@ -228,7 +239,6 @@ struct hb_sanitize_context_t : + this->max_ops = hb_clamp (m, + (unsigned) HB_SANITIZE_MAX_OPS_MIN, + (unsigned) HB_SANITIZE_MAX_OPS_MAX); +- this->edit_count = 0; + this->debug_depth = 0; + this->recursion_depth = 0; + +@@ -241,8 +251,8 @@ struct hb_sanitize_context_t : + void end_processing () + { + DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, +- "end [%p..%p] %u edit requests", +- this->start, this->end, this->edit_count); ++ "end [%p..%p]", ++ this->start, this->end); + + hb_blob_destroy (this->blob); + this->blob = nullptr; +@@ -250,9 +260,6 @@ struct hb_sanitize_context_t : + this->length = 0; + } + +- unsigned get_edit_count () { return edit_count; } +- +- + bool check_ops(unsigned count) + { + /* Avoid underflow */ +@@ -396,35 +403,6 @@ struct hb_sanitize_context_t : + return likely (this->check_point ((const char *) obj + obj->min_size)); + } + +- bool may_edit (const void *base, unsigned int len) +- { +- if (this->edit_count >= HB_SANITIZE_MAX_EDITS) +- return false; +- +- const char *p = (const char *) base; +- this->edit_count++; +- +- DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, +- "may_edit(%u) [%p..%p] (%u bytes) in [%p..%p] -> %s", +- this->edit_count, +- p, p + len, len, +- this->start, this->end, +- this->writable ? "GRANTED" : "DENIED"); +- +- return this->writable; +- } +- +- template +- bool try_set (const Type *obj, const ValueType &v) +- { +- if (this->may_edit (obj, hb_static_size (Type))) +- { +- * const_cast (obj) = v; +- return true; +- } +- return false; +- } +- + template + hb_blob_t *sanitize_blob (hb_blob_t *blob) + { +@@ -432,7 +410,6 @@ struct hb_sanitize_context_t : + + init (blob); + +- retry: + DEBUG_MSG_FUNC (SANITIZE, start, "start"); + + start_processing (); +@@ -446,36 +423,6 @@ struct hb_sanitize_context_t : + Type *t = reinterpret_cast (const_cast (start)); + + sane = t->sanitize (this); +- if (sane) +- { +- if (edit_count) +- { +- DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %u edits; going for second round", edit_count); +- +- /* sanitize again to ensure no toe-stepping */ +- edit_count = 0; +- sane = t->sanitize (this); +- if (edit_count) { +- DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count); +- sane = false; +- } +- } +- } +- else +- { +- if (edit_count && !writable) { +- start = hb_blob_get_data_writable (blob, nullptr); +- end = start + blob->length; +- +- if (start) +- { +- writable = true; +- /* ok, we made it writable by relocating. try again */ +- DEBUG_MSG_FUNC (SANITIZE, start, "retry"); +- goto retry; +- } +- } +- } + + end_processing (); + +@@ -506,7 +453,6 @@ struct hb_sanitize_context_t : + private: + int recursion_depth; + bool writable; +- unsigned int edit_count; + hb_blob_t *blob; + unsigned int num_glyphs; + bool num_glyphs_set; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-script-list.h b/src/java.desktop/share/native/libharfbuzz/hb-script-list.h +index f811dbc3408..16347b9d84e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-script-list.h ++++ b/src/java.desktop/share/native/libharfbuzz/hb-script-list.h +@@ -223,6 +223,10 @@ HB_END_DECLS + * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 + * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 + * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 ++ * @HB_SCRIPT_BERIA_ERFE: `Berf`, Since: 11.5.0 ++ * @HB_SCRIPT_SIDETIC: `Sidt`, Since: 11.5.0 ++ * @HB_SCRIPT_TAI_YO: `Tayo`, Since: 11.5.0 ++ * @HB_SCRIPT_TOLONG_SIKI: `Tols`, Since: 11.5.0 + * @HB_SCRIPT_INVALID: No script set + * + * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding +@@ -461,6 +465,14 @@ typedef enum + HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ + HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + ++ /* ++ * Since 11.5.0 ++ */ ++ HB_SCRIPT_BERIA_ERFE = HB_TAG ('B','e','r','f'), /*17.0*/ ++ HB_SCRIPT_SIDETIC = HB_TAG ('S','i','d','t'), /*17.0*/ ++ HB_SCRIPT_TAI_YO = HB_TAG ('T','a','y','o'), /*17.0*/ ++ HB_SCRIPT_TOLONG_SIKI = HB_TAG ('T','o','l','s'), /*17.0*/ ++ + /* No script set. */ + HB_SCRIPT_INVALID = HB_TAG_NONE, + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh +index 704d0ffd12b..9fe99c85ea7 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh +@@ -34,7 +34,7 @@ + #include "hb.hh" + #include "hb-blob.hh" + #include "hb-map.hh" +-#include "hb-pool.hh" ++#include "hb-free-pool.hh" + + #include "hb-subset-serialize.h" + +@@ -724,7 +724,7 @@ struct hb_serialize_context_t + hb_requires (hb_is_iterator (Iterator)), + typename ...Ts> + void copy_all (Iterator it, Ts&&... ds) +- { for (decltype (*it) _ : it) copy (_, std::forward (ds)...); } ++ { for (decltype (*it) _ : it) copy (_, ds...); } + + template + hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } +@@ -794,7 +794,8 @@ struct hb_serialize_context_t + template + void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) + { +- auto &off = * ((BEInt *) (parent->head + link.position)); ++ // XXX We should stop assuming big-endian! ++ auto &off = * ((HBInt *) (parent->head + link.position)); + assert (0 == off); + check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); + } +@@ -814,7 +815,7 @@ struct hb_serialize_context_t + } + + /* Object memory pool. */ +- hb_pool_t object_pool; ++ hb_free_pool_t object_pool; + + /* Stack of currently under construction objects. */ + object_t *current; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh +index f0416d5fa1d..f8cb0998260 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh +@@ -55,11 +55,11 @@ + * - For each glyph, if it doesn't match the subtable digest, + * skip it. + * +- * The main filter we use is a combination of four bits-pattern ++ * The filter we use is a combination of three bits-pattern + * filters. A bits-pattern filter checks a number of bits (5 or 6) +- * of the input number (glyph-id in this case) and checks whether ++ * of the input number (glyph-id in most cases) and checks whether + * its pattern is amongst the patterns of any of the accepted values. +- * The accepted patterns are represented as a "long" integer. The ++ * The accepted patterns are represented as a "long" integer. Each + * check is done using four bitwise operations only. + */ + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc +index d14f577be00..a36fa14fb28 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc +@@ -149,14 +149,11 @@ hb_shape_full (hb_font_t *font, + + 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, +@@ -199,6 +196,7 @@ hb_shape (hb_font_t *font, + + + #ifdef HB_EXPERIMENTAL_API ++#ifndef HB_NO_VAR + + static float + buffer_advance (hb_buffer_t *buffer) +@@ -440,7 +438,7 @@ hb_shape_justify (hb_font_t *font, + + return true; + } +- ++#endif + #endif + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh +index f079caf4d35..cb386f26827 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh +@@ -57,6 +57,14 @@ HB_SHAPER_IMPLEMENT (directwrite) + HB_SHAPER_IMPLEMENT (coretext) + #endif + ++#ifdef HAVE_HARFRUST ++HB_SHAPER_IMPLEMENT (harfrust) ++#endif ++ ++#ifdef HAVE_KBTS ++HB_SHAPER_IMPLEMENT (kbts) ++#endif ++ + #ifndef HB_NO_FALLBACK_SHAPE + HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */ + #endif +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-static.cc b/src/java.desktop/share/native/libharfbuzz/hb-static.cc +index 4e70e413651..06cc80b5f38 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-static.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-static.cc +@@ -113,27 +113,4 @@ hb_face_t::load_upem () const + return ret; + } + +- +-#ifndef HB_NO_VAR +-bool +-_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, +- int *lsb) +-{ +- return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); +-} +- +-unsigned +-_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +-{ +- return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); +-} +-#endif +- +-bool +-_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb) +-{ +- return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb); +-} +- +- + #endif +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh +index 9d00cae6c32..51413b6da44 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-string-array.hh +@@ -45,25 +45,25 @@ static const union HB_STRING_ARRAY_TYPE_NAME { + * but C++ does not allow that. + * https://stackoverflow.com/q/28433862 + */ +-#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; ++#define HB_STR(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; + #include HB_STRING_ARRAY_LIST +-#undef _S ++#undef HB_STR + } st; + char str[HB_VAR_ARRAY]; + } + HB_STRING_ARRAY_POOL_NAME = + { + { +-#define _S(s) s, ++#define HB_STR(s) s, + #include HB_STRING_ARRAY_LIST +-#undef _S ++#undef HB_STR + } + }; + static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] = + { +-#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), ++#define HB_STR(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), + #include HB_STRING_ARRAY_LIST +-#undef _S ++#undef HB_STR + sizeof (HB_STRING_ARRAY_TYPE_NAME) + }; + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh +index e7bddaef723..843ad69f2f9 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh +@@ -861,8 +861,7 @@ struct subr_subsetter_t + { + // Hack to point vector to static string. + auto &b = buffArray.arrayZ[last]; +- b.length = 1; +- b.arrayZ = const_cast(endchar_str); ++ b.set_storage (const_cast(endchar_str), 1); + } + + last++; // Skip over gid +@@ -877,8 +876,7 @@ struct subr_subsetter_t + { + // Hack to point vector to static string. + auto &b = buffArray.arrayZ[last]; +- b.length = 1; +- b.arrayZ = const_cast(endchar_str); ++ b.set_storage (const_cast(endchar_str), 1); + } + + return true; +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh +index 01987bd258d..8ee02c07dbe 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh +@@ -26,12 +26,27 @@ + #define HB_SUBSET_INSTANCER_IUP_HH + + #include "hb-subset-plan.hh" ++ ++struct iup_scratch_t ++{ ++ hb_vector_t end_points; ++ hb_vector_t interp_x_deltas; ++ hb_vector_t interp_y_deltas; ++ hb_vector_t costs; ++ hb_vector_t chain; ++ hb_vector_t rot_indices; ++ hb_vector_t rot_x_deltas; ++ hb_vector_t rot_y_deltas; ++ contour_point_vector_t rot_points; ++}; ++ + /* given contour points and deltas, optimize a set of referenced points within error + * tolerance. Returns optimized referenced point indices */ + HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t& x_deltas, + const hb_vector_t& y_deltas, + hb_vector_t& opt_indices, /* OUT */ ++ iup_scratch_t &scratch, + double tolerance = 0.0); + + #endif /* HB_SUBSET_INSTANCER_IUP_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc +index c67fee421c2..15227bdab48 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc +@@ -62,9 +62,10 @@ static inline double supportScalar (double coord, const Triple &tent) + return (end - coord) / (end - peak); + } + +-static inline rebase_tent_result_t +-_solve (Triple tent, Triple axisLimit, bool negative = false) ++static inline void ++_solve (Triple tent, Triple axisLimit, rebase_tent_result_t &out, bool negative = false) + { ++ out.reset(); + double axisMin = axisLimit.minimum; + double axisDef = axisLimit.middle; + double axisMax = axisLimit.maximum; +@@ -75,14 +76,12 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) + // Mirror the problem such that axisDef <= peak + if (axisDef > peak) + { +- rebase_tent_result_t vec = _solve (_reverse_negate (tent), +- _reverse_negate (axisLimit), +- !negative); ++ _solve (_reverse_negate (tent), _reverse_negate (axisLimit), out, !negative); + +- for (auto &p : vec) ++ for (auto &p : out) + p = hb_pair (p.first, _reverse_negate (p.second)); + +- return vec; ++ return; + } + // axisDef <= peak + +@@ -98,7 +97,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) + * axisMin axisDef axisMax lower upper + */ + if (axisMax <= lower && axisMax < peak) +- return rebase_tent_result_t{}; // No overlap ++ return; // No overlap + + /* case 2: Only the peak and outermost bound fall outside the new limit; + * we keep the deltaset, update peak and outermost bound and scale deltas +@@ -133,18 +132,18 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) + double mult = supportScalar (axisMax, tent); + tent = Triple{lower, axisMax, axisMax}; + +- rebase_tent_result_t vec = _solve (tent, axisLimit); ++ _solve (tent, axisLimit, out); + +- for (auto &p : vec) ++ for (auto &p : out) + p = hb_pair (p.first * mult, p.second); + +- return vec; ++ return; + } + + // lower <= axisDef <= peak <= axisMax + + double gain = supportScalar (axisDef, tent); +- rebase_tent_result_t out {hb_pair (gain, Triple{})}; ++ out.push(hb_pair (gain, Triple{})); + + // First, the positive side + +@@ -362,8 +361,6 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) + out.push (hb_pair (scalar1 - gain, loc1)); + out.push (hb_pair (scalar2 - gain, loc2)); + } +- +- return out; + } + + static inline TripleDistances _reverse_triple_distances (const TripleDistances &v) +@@ -405,18 +402,21 @@ double renormalizeValue (double v, const Triple &triple, + return (-v_distance) /total_distance; + } + +-rebase_tent_result_t +-rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances) ++void ++rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances, ++ rebase_tent_result_t &out, ++ rebase_tent_result_t &scratch) + { + assert (-1.0 <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.0); + assert (-2.0 <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.0); + assert (tent.middle != 0.0); + +- rebase_tent_result_t sols = _solve (tent, axisLimit); ++ rebase_tent_result_t &sols = scratch; ++ _solve (tent, axisLimit, sols); + + auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; + +- rebase_tent_result_t out; ++ out.reset(); + for (auto &p : sols) + { + if (!p.first) continue; +@@ -429,6 +429,4 @@ rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distance + out.push (hb_pair (p.first, + Triple{n (t.minimum), n (t.middle), n (t.maximum)})); + } +- +- return out; + } +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh +index 9764dcc1725..574d58d53d8 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh +@@ -42,10 +42,9 @@ struct TripleDistances + double positive; + }; + +-struct Triple { +- +- Triple () : +- minimum (0.0), middle (0.0), maximum (0.0) {} ++struct Triple ++{ ++ Triple () = default; + + Triple (double minimum_, double middle_, double maximum_) : + minimum (minimum_), middle (middle_), maximum (maximum_) {} +@@ -81,10 +80,9 @@ struct Triple { + return current; + } + +- +- double minimum; +- double middle; +- double maximum; ++ double minimum = 0; ++ double middle = 0; ++ double maximum = 0; + }; + + using rebase_tent_result_item_t = hb_pair_t; +@@ -107,8 +105,10 @@ HB_INTERNAL double renormalizeValue (double v, const Triple &triple, + * If tent value is Triple{}, that is a special deltaset that should + * be always-enabled (called "gain"). + */ +-HB_INTERNAL rebase_tent_result_t rebase_tent (Triple tent, +- Triple axisLimit, +- TripleDistances axis_triple_distances); ++HB_INTERNAL void rebase_tent (Triple tent, ++ Triple axisLimit, ++ TripleDistances axis_triple_distances, ++ rebase_tent_result_t &out, ++ rebase_tent_result_t &scratch); + + #endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh +index ade8278c40f..398fe81eca9 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh +@@ -81,6 +81,10 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo + HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features) + HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features) + ++//active features(with duplicates) old index -> new index mapping ++HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features_w_duplicates) ++HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features_w_duplicates) ++ + //active feature variation records/condition index with variations + HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_feature_record_cond_idx_map) + HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_feature_record_cond_idx_map) +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc +index 3ba726d925e..8c3fd97899b 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc +@@ -418,7 +418,8 @@ _nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables) + { + #ifndef HB_NO_STYLE +- plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); ++ if (!drop_tables->has (HB_OT_TAG_STAT)) ++ plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); + #endif + #ifndef HB_NO_VAR + if (!plan->all_axes_pinned) +@@ -676,7 +677,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, + return; + + #ifndef HB_NO_VAR +- normalize_axes_location (face, this); ++ if (!check_success (normalize_axes_location (face, this))) ++ return; + #endif + + _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this); +@@ -697,6 +699,15 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, + return; + } + ++#ifdef HB_EXPERIMENTAL_API ++ if ((input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) && ++ (input->flags & HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS)) { ++ // We've been requested to maintain the num glyphs count from the ++ // input face. ++ _num_output_glyphs = source->get_num_glyphs (); ++ } ++#endif ++ + _create_glyph_map_gsub ( + &_glyphset_gsub, + glyph_map, +@@ -710,10 +721,10 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, + glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); + } + +- bounds_width_vec.resize (_num_output_glyphs, false); ++ bounds_width_vec.resize_dirty (_num_output_glyphs); + for (auto &v : bounds_width_vec) + v = 0xFFFFFFFF; +- bounds_height_vec.resize (_num_output_glyphs, false); ++ bounds_height_vec.resize_dirty (_num_output_glyphs); + for (auto &v : bounds_height_vec) + v = 0xFFFFFFFF; + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh +index 8a6574365ed..0362ed7292e 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh +@@ -300,6 +300,7 @@ struct hb_subset_plan_t + // compile times more reasonable: + // - hb-subset-plan.cc + // - hb-subset-plan-layout.cc ++// - hb-subset-plan-var.cc + // + // The functions below are those needed to connect the split files + // above together. +@@ -332,7 +333,7 @@ generate_varstore_inner_maps (const hb_set_t& varidx_set, + unsigned subtable_count, + hb_vector_t &inner_maps /* OUT */); + +-HB_INTERNAL void ++HB_INTERNAL bool + normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan); + + HB_INTERNAL void +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +index 079c94eddfe..51134ed09ce 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +@@ -25,65 +25,19 @@ + */ + + #include "hb.hh" ++ + #include "hb-open-type.hh" ++#include "hb-open-file.hh" + + #include "hb-subset.hh" ++#include "hb-subset-table.hh" ++#include "hb-subset-accelerator.hh" + +-#include "hb-open-file.hh" + #include "hb-ot-cmap-table.hh" +-#include "hb-ot-glyf-table.hh" +-#include "hb-ot-hdmx-table.hh" +-#include "hb-ot-head-table.hh" +-#include "hb-ot-hhea-table.hh" +-#include "hb-ot-hmtx-table.hh" +-#include "hb-ot-maxp-table.hh" +-#include "OT/Color/CBDT/CBDT.hh" +-#include "OT/Color/COLR/COLR.hh" +-#include "OT/Color/CPAL/CPAL.hh" +-#include "OT/Color/sbix/sbix.hh" +-#include "hb-ot-os2-table.hh" +-#include "hb-ot-post-table.hh" +-#include "hb-ot-post-table-v2subset.hh" +-#include "hb-ot-cff1-table.hh" +-#include "hb-ot-cff2-table.hh" +-#include "hb-ot-vorg-table.hh" +-#include "hb-ot-name-table.hh" +-#include "hb-ot-layout-base-table.hh" +-#include "hb-ot-layout-gsub-table.hh" +-#include "hb-ot-layout-gpos-table.hh" +-#include "hb-ot-var-avar-table.hh" + #include "hb-ot-var-cvar-table.hh" +-#include "hb-ot-var-fvar-table.hh" +-#include "hb-ot-var-gvar-table.hh" +-#include "hb-ot-var-hvar-table.hh" +-#include "hb-ot-var-mvar-table.hh" +-#include "hb-ot-math-table.hh" ++#include "hb-ot-head-table.hh" + #include "hb-ot-stat-table.hh" +-#include "hb-repacker.hh" +-#include "hb-subset-accelerator.hh" +- +-using OT::Layout::GSUB; +-using OT::Layout::GPOS; +- +- +-#ifndef HB_NO_SUBSET_CFF +-template<> +-struct hb_subset_plan_t::source_table_loader +-{ +- auto operator () (hb_subset_plan_t *plan) +- HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : +- plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : +- plan->cff1_accel) +-}; +-template<> +-struct hb_subset_plan_t::source_table_loader +-{ +- auto operator () (hb_subset_plan_t *plan) +- HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : +- plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : +- plan->cff2_accel) +-}; +-#endif ++#include "hb-ot-post-table-v2subset.hh" + + + /** +@@ -116,56 +70,56 @@ hb_user_data_key_t _hb_subset_accelerator_user_data_key = {}; + * if we are unable to list the tables in a face. + */ + static hb_tag_t known_tables[] { +- HB_TAG ('a', 'v', 'a', 'r'), +- HB_OT_TAG_BASE, +- HB_OT_TAG_CBDT, +- HB_OT_TAG_CBLC, +- HB_OT_TAG_CFF1, +- HB_OT_TAG_CFF2, +- HB_OT_TAG_cmap, +- HB_OT_TAG_COLR, +- HB_OT_TAG_CPAL, +- HB_TAG ('c', 'v', 'a', 'r'), +- HB_TAG ('c', 'v', 't', ' '), +- HB_TAG ('D', 'S', 'I', 'G'), +- HB_TAG ('E', 'B', 'D', 'T'), +- HB_TAG ('E', 'B', 'L', 'C'), +- HB_TAG ('E', 'B', 'S', 'C'), +- HB_TAG ('f', 'p', 'g', 'm'), +- HB_TAG ('f', 'v', 'a', 'r'), +- HB_TAG ('g', 'a', 's', 'p'), +- HB_OT_TAG_GDEF, +- HB_OT_TAG_glyf, +- HB_OT_TAG_GPOS, +- HB_OT_TAG_GSUB, +- HB_OT_TAG_gvar, +- HB_OT_TAG_hdmx, +- HB_OT_TAG_head, +- HB_OT_TAG_hhea, +- HB_OT_TAG_hmtx, +- HB_OT_TAG_HVAR, +- HB_OT_TAG_JSTF, +- HB_TAG ('k', 'e', 'r', 'n'), +- HB_OT_TAG_loca, +- HB_TAG ('L', 'T', 'S', 'H'), +- HB_OT_TAG_MATH, +- HB_OT_TAG_maxp, +- HB_TAG ('M', 'E', 'R', 'G'), +- HB_TAG ('m', 'e', 't', 'a'), +- HB_TAG ('M', 'V', 'A', 'R'), +- HB_TAG ('P', 'C', 'L', 'T'), +- HB_OT_TAG_post, +- HB_TAG ('p', 'r', 'e', 'p'), +- HB_OT_TAG_sbix, +- HB_TAG ('S', 'T', 'A', 'T'), +- HB_TAG ('S', 'V', 'G', ' '), +- HB_TAG ('V', 'D', 'M', 'X'), +- HB_OT_TAG_vhea, +- HB_OT_TAG_vmtx, +- HB_OT_TAG_VORG, +- HB_OT_TAG_VVAR, +- HB_OT_TAG_name, +- HB_OT_TAG_OS2 ++ HB_TAG('a','v','a','r'), ++ HB_TAG('B','A','S','E'), ++ HB_TAG('C','B','D','T'), ++ HB_TAG('C','B','L','C'), ++ HB_TAG('C','F','F',' '), ++ HB_TAG('C','F','F','2'), ++ HB_TAG('c','m','a','p'), ++ HB_TAG('C','O','L','R'), ++ HB_TAG('C','P','A','L'), ++ HB_TAG('c','v','a','r'), ++ HB_TAG('c','v','t',' '), ++ HB_TAG('D','S','I','G'), ++ HB_TAG('E','B','D','T'), ++ HB_TAG('E','B','L','C'), ++ HB_TAG('E','B','S','C'), ++ HB_TAG('f','p','g','m'), ++ HB_TAG('f','v','a','r'), ++ HB_TAG('g','a','s','p'), ++ HB_TAG('G','D','E','F'), ++ HB_TAG('g','l','y','f'), ++ HB_TAG('G','P','O','S'), ++ HB_TAG('G','S','U','B'), ++ HB_TAG('g','v','a','r'), ++ HB_TAG('h','d','m','x'), ++ HB_TAG('h','e','a','d'), ++ HB_TAG('h','h','e','a'), ++ HB_TAG('h','m','t','x'), ++ HB_TAG('H','V','A','R'), ++ HB_TAG('J','S','T','F'), ++ HB_TAG('k','e','r','n'), ++ HB_TAG('l','o','c','a'), ++ HB_TAG('L','T','S','H'), ++ HB_TAG('M','A','T','H'), ++ HB_TAG('m','a','x','p'), ++ HB_TAG('M','E','R','G'), ++ HB_TAG('m','e','t','a'), ++ HB_TAG('M','V','A','R'), ++ HB_TAG('P','C','L','T'), ++ HB_TAG('p','o','s','t'), ++ HB_TAG('p','r','e','p'), ++ HB_TAG('s','b','i','x'), ++ HB_TAG('S','T','A','T'), ++ HB_TAG('S','V','G',' '), ++ HB_TAG('V','D','M','X'), ++ HB_TAG('v','h','e','a'), ++ HB_TAG('v','m','t','x'), ++ HB_TAG('V','O','R','G'), ++ HB_TAG('V','V','A','R'), ++ HB_TAG('n','a','m','e'), ++ HB_TAG('O','S','/','2') + }; + + static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag) +@@ -213,169 +167,6 @@ _get_table_tags (const hb_subset_plan_t* plan, + } + + +-static unsigned +-_plan_estimate_subset_table_size (hb_subset_plan_t *plan, +- unsigned table_len, +- hb_tag_t table_tag) +-{ +- unsigned src_glyphs = plan->source->get_num_glyphs (); +- unsigned dst_glyphs = plan->glyphset ()->get_population (); +- +- unsigned bulk = 8192; +- /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's +- * because those are expensive to subset, so giving them more room is fine. */ +- bool same_size = table_tag == HB_OT_TAG_GSUB || +- table_tag == HB_OT_TAG_GPOS || +- table_tag == HB_OT_TAG_name; +- +- if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) +- { +- if (table_tag == HB_OT_TAG_CFF1) +- { +- /* Add some extra room for the CFF charset. */ +- bulk += src_glyphs * 16; +- } +- else if (table_tag == HB_OT_TAG_CFF2) +- { +- /* Just extra CharString offsets. */ +- bulk += src_glyphs * 4; +- } +- } +- +- if (unlikely (!src_glyphs) || same_size) +- return bulk + table_len; +- +- return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); +-} +- +-/* +- * Repack the serialization buffer if any offset overflows exist. +- */ +-static hb_blob_t* +-_repack (hb_tag_t tag, const hb_serialize_context_t& c) +-{ +- if (!c.offset_overflow ()) +- return c.copy_blob (); +- +- hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); +- +- if (unlikely (!result)) +- { +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", +- HB_UNTAG (tag)); +- return nullptr; +- } +- +- return result; +-} +- +-template +-static +-bool +-_try_subset (const TableType *table, +- hb_vector_t* buf, +- hb_subset_context_t* c /* OUT */) +-{ +- c->serializer->start_serialize (); +- if (c->serializer->in_error ()) return false; +- +- bool needed = table->subset (c); +- if (!c->serializer->ran_out_of_room ()) +- { +- c->serializer->end_serialize (); +- return needed; +- } +- +- unsigned buf_size = buf->allocated; +- buf_size = buf_size * 2 + 16; +- +- +- +- +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", +- HB_UNTAG (c->table_tag), buf_size); +- +- if (unlikely (buf_size > c->source_blob->length * 256 || +- !buf->alloc_exact (buf_size))) +- { +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", +- HB_UNTAG (c->table_tag), buf_size); +- return needed; +- } +- +- c->serializer->reset (buf->arrayZ, buf->allocated); +- return _try_subset (table, buf, c); +-} +- +-template +-static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) +- +-template +-static void _do_destroy (T &t, hb_priority<0>) {} +- +-template +-static bool +-_subset (hb_subset_plan_t *plan, hb_vector_t &buf) +-{ +- auto &&source_blob = plan->source_table (); +- auto *table = source_blob.get (); +- +- hb_tag_t tag = TableType::tableTag; +- hb_blob_t *blob = source_blob.get_blob(); +- if (unlikely (!blob || !blob->data)) +- { +- DEBUG_MSG (SUBSET, nullptr, +- "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); +- _do_destroy (source_blob, hb_prioritize); +- return false; +- } +- +- unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag); +- DEBUG_MSG (SUBSET, nullptr, +- "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); +- if (unlikely (!buf.alloc (buf_size))) +- { +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); +- _do_destroy (source_blob, hb_prioritize); +- return false; +- } +- +- bool needed = false; +- hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); +- { +- hb_subset_context_t c (blob, plan, &serializer, tag); +- needed = _try_subset (table, &buf, &c); +- } +- _do_destroy (source_blob, hb_prioritize); +- +- if (serializer.in_error () && !serializer.only_offset_overflow ()) +- { +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); +- return false; +- } +- +- if (!needed) +- { +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); +- return true; +- } +- +- bool result = false; +- hb_blob_t *dest_blob = _repack (tag, serializer); +- if (dest_blob) +- { +- DEBUG_MSG (SUBSET, nullptr, +- "OT::%c%c%c%c final subset table size: %u bytes.", +- HB_UNTAG (tag), dest_blob->length); +- result = plan->add_table (tag, dest_blob); +- hb_blob_destroy (dest_blob); +- } +- +- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", +- HB_UNTAG (tag), result ? "success" : "FAILED!"); +- return result; +-} +- + static bool + _is_table_present (hb_face_t *source, hb_tag_t tag) + { +@@ -407,34 +198,34 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) + + switch (tag) + { +- case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */ ++ case HB_TAG('c','v','a','r'): /* hint table, fallthrough */ + return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING); + +- case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */ +- case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */ +- case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ +- case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */ +- case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */ ++ case HB_TAG('c','v','t',' '): /* hint table, fallthrough */ ++ case HB_TAG('f','p','g','m'): /* hint table, fallthrough */ ++ case HB_TAG('p','r','e','p'): /* hint table, fallthrough */ ++ case HB_TAG('h','d','m','x'): /* hint table, fallthrough */ ++ case HB_TAG('V','D','M','X'): /* hint table, fallthrough */ + return plan->flags & HB_SUBSET_FLAGS_NO_HINTING; + + #ifdef HB_NO_SUBSET_LAYOUT + // Drop Layout Tables if requested. +- case HB_OT_TAG_GDEF: +- case HB_OT_TAG_GPOS: +- case HB_OT_TAG_GSUB: +- case HB_TAG ('m','o','r','x'): +- case HB_TAG ('m','o','r','t'): +- case HB_TAG ('k','e','r','x'): +- case HB_TAG ('k','e','r','n'): ++ case HB_TAG('G','D','E','F'): ++ case HB_TAG('G','P','O','S'): ++ case HB_TAG('G','S','U','B'): ++ case HB_TAG('m','o','r','x'): ++ case HB_TAG('m','o','r','t'): ++ case HB_TAG('k','e','r','x'): ++ case HB_TAG('k','e','r','n'): + return true; + #endif + +- case HB_TAG ('a','v','a','r'): +- case HB_TAG ('f','v','a','r'): +- case HB_TAG ('g','v','a','r'): +- case HB_OT_TAG_HVAR: +- case HB_OT_TAG_VVAR: +- case HB_TAG ('M','V','A','R'): ++ case HB_TAG('a','v','a','r'): ++ case HB_TAG('f','v','a','r'): ++ case HB_TAG('g','v','a','r'): ++ case HB_TAG('H','V','A','R'): ++ case HB_TAG('V','V','A','R'): ++ case HB_TAG('M','V','A','R'): + return plan->all_axes_pinned; + + default: +@@ -442,15 +233,6 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) + } + } + +-static bool +-_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) +-{ +- hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); +- bool result = plan->add_table (tag, source_table); +- hb_blob_destroy (source_table); +- return result; +-} +- + static bool + _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, + const hb_set_t &subsetted_tags, +@@ -458,13 +240,13 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, + { + switch (tag) + { +- case HB_OT_TAG_hmtx: +- case HB_OT_TAG_vmtx: +- case HB_OT_TAG_maxp: +- case HB_OT_TAG_OS2: +- return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); +- case HB_OT_TAG_GPOS: +- return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); ++ case HB_TAG('h','m','t','x'): ++ case HB_TAG('v','m','t','x'): ++ case HB_TAG('m','a','x','p'): ++ case HB_TAG('O','S','/','2'): ++ return !plan->normalized_coords || !pending_subset_tags.has (HB_TAG('g','l','y','f')); ++ case HB_TAG('G','P','O','S'): ++ return plan->all_axes_pinned || !pending_subset_tags.has (HB_TAG('G','D','E','F')); + default: + return true; + } +@@ -476,88 +258,48 @@ _subset_table (hb_subset_plan_t *plan, + hb_tag_t tag) + { + if (plan->no_subset_tables.has (tag)) { +- return _passthrough (plan, tag); ++ return _hb_subset_table_passthrough (plan, tag); + } + + DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag)); ++ ++ bool success; ++ if (_hb_subset_table_layout (plan, buf, tag, &success) || ++ _hb_subset_table_var (plan, buf, tag, &success) || ++ _hb_subset_table_cff (plan, buf, tag, &success) || ++ _hb_subset_table_color (plan, buf, tag, &success) || ++ _hb_subset_table_other (plan, buf, tag, &success)) ++ return success; ++ ++ + switch (tag) + { +- case HB_OT_TAG_glyf: return _subset (plan, buf); +- case HB_OT_TAG_hdmx: return _subset (plan, buf); +- case HB_OT_TAG_name: return _subset (plan, buf); +- case HB_OT_TAG_head: +- if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf)) ++ case HB_TAG('h','e','a','d'): ++ if (_is_table_present (plan->source, HB_TAG('g','l','y','f')) && !_should_drop_table (plan, HB_TAG('g','l','y','f'))) + return true; /* skip head, handled by glyf */ +- return _subset (plan, buf); +- case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */ +- case HB_OT_TAG_hmtx: return _subset (plan, buf); +- case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */ +- case HB_OT_TAG_vmtx: return _subset (plan, buf); +- case HB_OT_TAG_maxp: return _subset (plan, buf); +- case HB_OT_TAG_sbix: return _subset (plan, buf); +- case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */ +- case HB_OT_TAG_cmap: return _subset (plan, buf); +- case HB_OT_TAG_OS2 : return _subset (plan, buf); +- case HB_OT_TAG_post: return _subset (plan, buf); +- case HB_OT_TAG_COLR: return _subset (plan, buf); +- case HB_OT_TAG_CPAL: return _subset (plan, buf); +- case HB_OT_TAG_CBLC: return _subset (plan, buf); +- case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ +- case HB_OT_TAG_MATH: return _subset (plan, buf); +- case HB_OT_TAG_BASE: return _subset (plan, buf); +- +-#ifndef HB_NO_SUBSET_CFF +- case HB_OT_TAG_CFF1: return _subset (plan, buf); +- case HB_OT_TAG_CFF2: return _subset (plan, buf); +- case HB_OT_TAG_VORG: return _subset (plan, buf); +-#endif +- +-#ifndef HB_NO_SUBSET_LAYOUT +- case HB_OT_TAG_GDEF: return _subset (plan, buf); +- case HB_OT_TAG_GSUB: return _subset (plan, buf); +- case HB_OT_TAG_GPOS: return _subset (plan, buf); +- case HB_OT_TAG_gvar: return _subset (plan, buf); +- case HB_OT_TAG_HVAR: return _subset (plan, buf); +- case HB_OT_TAG_VVAR: return _subset (plan, buf); +-#endif +- +-#ifndef HB_NO_VAR +- case HB_OT_TAG_fvar: +- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); +- return _subset (plan, buf); +- case HB_OT_TAG_avar: +- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); +- return _subset (plan, buf); +- case HB_OT_TAG_cvar: +- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); +- return _subset (plan, buf); +- case HB_OT_TAG_MVAR: +- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); +- return _subset (plan, buf); +-#endif ++ return _hb_subset_table (plan, buf); + +- case HB_OT_TAG_STAT: +- if (!plan->user_axes_location.is_empty ()) return _subset (plan, buf); +- else return _passthrough (plan, tag); ++ case HB_TAG('S','T','A','T'): ++ if (!plan->user_axes_location.is_empty ()) return _hb_subset_table (plan, buf); ++ else return _hb_subset_table_passthrough (plan, tag); + +- case HB_TAG ('c', 'v', 't', ' '): ++ case HB_TAG('c','v','t',' '): + #ifndef HB_NO_VAR +- if (_is_table_present (plan->source, HB_OT_TAG_cvar) && ++ if (_is_table_present (plan->source, HB_TAG('c','v','a','r')) && + plan->normalized_coords && !plan->pinned_at_default) + { + auto &cvar = *plan->source->table.cvar; + return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar); + } + #endif +- return _passthrough (plan, tag); ++ return _hb_subset_table_passthrough (plan, tag); ++ } + +- default: +- if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) +- return _passthrough (plan, tag); ++ if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) ++ return _hb_subset_table_passthrough (plan, tag); + +- // Drop table +- return true; +- } ++ // Drop table ++ return true; + } + + static void _attach_accelerator_data (hb_subset_plan_t* plan, +@@ -707,108 +449,4 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) + + end: + return success ? hb_face_reference (plan->dest) : nullptr; +-} +- +- +-#ifdef HB_EXPERIMENTAL_API +- +-#include "hb-ot-cff1-table.hh" +- +-template +-static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { +- if (!accel.is_valid()) { +- return hb_blob_get_empty (); +- } +- +- hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; +- if (!bytes) { +- return hb_blob_get_empty (); +- } +- +- hb_blob_t* cff_blob = accel.get_blob(); +- uint32_t length; +- const char* cff_data = hb_blob_get_data(cff_blob, &length) ; +- +- long int offset = (const char*) bytes.arrayZ - cff_data; +- if (offset < 0 || offset > INT32_MAX) { +- return hb_blob_get_empty (); +- } +- +- return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); +-} +- +-template +-static hb_blob_t* get_charstrings_index(accel_t& accel) { +- if (!accel.is_valid()) { +- return hb_blob_get_empty (); +- } +- +- const char* charstrings_start = (const char*) accel.charStrings; +- unsigned charstrings_length = accel.charStrings->get_size(); +- +- hb_blob_t* cff_blob = accel.get_blob(); +- uint32_t length; +- const char* cff_data = hb_blob_get_data(cff_blob, &length) ; +- +- long int offset = charstrings_start - cff_data; +- if (offset < 0 || offset > INT32_MAX) { +- return hb_blob_get_empty (); +- } +- +- return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); +-} +- +-/** +- * hb_subset_cff_get_charstring_data: +- * @face: A face object +- * @glyph_index: Glyph index to get data for. +- * +- * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. +- * +- * XSince: EXPERIMENTAL +- **/ +-HB_EXTERN hb_blob_t* +-hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { +- return get_charstrings_data(*face->table.cff1, glyph_index); +-} +- +-/** +- * hb_subset_cff_get_charstrings_index: +- * @face: A face object +- * +- * Returns the raw CFF CharStrings INDEX from the CFF table. +- * +- * XSince: EXPERIMENTAL +- **/ +-HB_EXTERN hb_blob_t* +-hb_subset_cff_get_charstrings_index (hb_face_t* face) { +- return get_charstrings_index (*face->table.cff1); +-} +- +-/** +- * hb_subset_cff2_get_charstring_data: +- * @face: A face object +- * @glyph_index: Glyph index to get data for. +- * +- * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. +- * +- * XSince: EXPERIMENTAL +- **/ +-HB_EXTERN hb_blob_t* +-hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { +- return get_charstrings_data(*face->table.cff2, glyph_index); +-} +- +-/** +- * hb_subset_cff2_get_charstrings_index: +- * @face: A face object +- * +- * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. +- * +- * XSince: EXPERIMENTAL +- **/ +-HB_EXTERN hb_blob_t* +-hb_subset_cff2_get_charstrings_index (hb_face_t* face) { +- return get_charstrings_index (*face->table.cff2); +-} +-#endif +\ No newline at end of file ++} +\ No newline at end of file +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.h b/src/java.desktop/share/native/libharfbuzz/hb-subset.h +index 3eccd25738e..fd2908e8308 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset.h ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.h +@@ -80,6 +80,10 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; + * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset + * to allow it to be used with incremental font transfer IFTB patches. Primarily, + * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL ++ * @HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS: If this flag is set along side ++ * HB_SUBSET_FLAGS_RETAIN_GIDS then the number of glyphs in the font won't ++ * be reduced as a result of subsetting. If necessary empty glyphs will be ++ * included at the end of the font to keep the number of glyphs unchanged. + * + * List of boolean properties that can be configured on the subset input. + * +@@ -101,6 +105,7 @@ typedef enum { /*< flags >*/ + HB_SUBSET_FLAGS_NO_BIDI_CLOSURE = 0x00000800u, + #ifdef HB_EXPERIMENTAL_API + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00001000u, ++ HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS = 0x00002000u, + #endif + } hb_subset_flags_t; + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset.hh +index bc7c24c94de..009919764f5 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-subset.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.hh +@@ -70,5 +70,4 @@ struct hb_subset_context_t : + table_tag (table_tag_) {} + }; + +- + #endif /* HB_SUBSET_HH */ +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh +index 8731a0bcf8d..868428ab1e7 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh +@@ -2,9 +2,9 @@ + /* + * The following table is generated by running: + * +- * ./gen-ucd-table.py ucd.nounihan.grouped.xml ++ * ./gen-ucd-table.py ucd.nounihan.grouped.xml hb-script-list.h + * +- * on file with this description: Unicode 16.0.0 ++ * on file with this description: Unicode 17.0.0 + */ + + #ifndef HB_UCD_TABLE_HH +@@ -12,8 +12,9 @@ + + #include "hb.hh" + +-static const hb_script_t +-_hb_ucd_sc_map[172] = ++#include ++ ++static const hb_script_t _hb_ucd_sc_map[176]= + { + HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, + HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, +@@ -101,1040 +102,805 @@ _hb_ucd_sc_map[172] = + HB_SCRIPT_GURUNG_KHEMA, HB_SCRIPT_KIRAT_RAI, + HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, + HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, ++ HB_SCRIPT_BERIA_ERFE, HB_SCRIPT_SIDETIC, ++ HB_SCRIPT_TAI_YO, HB_SCRIPT_TOLONG_SIKI, + }; +-static const uint16_t +-_hb_ucd_dm1_p0_map[825] = ++static const uint16_t _hb_ucd_dm1_p0_map[825]= + { +- 0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u, +- 0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu, +- 0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu, +- 0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u, +- 0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu, +- 0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au, +- 0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u, +- 0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u, +- 0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u, +- 0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu, +- 0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu, +- 0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu, +- 0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u, +- 0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu, +- 0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu, +- 0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u, +- 0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du, +- 0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu, +- 0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u, +- 0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u, +- 0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu, +- 0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u, +- 0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu, +- 0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u, +- 0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u, +- 0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu, +- 0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u, +- 0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u, +- 0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u, +- 0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u, +- 0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu, +- 0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u, +- 0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u, +- 0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u, +- 0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu, +- 0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u, +- 0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u, +- 0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu, +- 0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u, +- 0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u, +- 0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au, +- 0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u, +- 0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u, +- 0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u, +- 0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu, +- 0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u, +- 0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u, +- 0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u, +- 0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u, +- 0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u, +- 0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u, +- 0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u, +- 0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu, +- 0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u, +- 0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au, +- 0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au, +- 0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu, +- 0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu, +- 0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu, +- 0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u, +- 0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u, +- 0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u, +- 0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u, +- 0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u, +- 0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u, +- 0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u, +- 0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu, +- 0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu, +- 0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u, +- 0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu, +- 0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u, +- 0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu, +- 0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u, +- 0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u, +- 0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au, +- 0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u, +- 0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u, +- 0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu, +- 0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u, +- 0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu, +- 0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u, +- 0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u, +- 0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u, +- 0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u, +- 0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu, +- 0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u, +- 0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u, +- 0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu, +- 0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu, +- 0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu, +- 0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u, +- 0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u, +- 0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u, +- 0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u, +- 0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u, +- 0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u, +- 0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u, +- 0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu, +- 0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u, +- 0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu, +- 0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u, +- 0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u, +- 0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu, +- 0x9F9Cu, ++ 0x003B, 0x004B, 0x0060, 0x00B4, 0x00B7, 0x00C5, 0x02B9, 0x0300, ++ 0x0301, 0x0313, 0x0385, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, ++ 0x038E, 0x038F, 0x0390, 0x03A9, 0x03AC, 0x03AD, 0x03AE, 0x03AF, ++ 0x03B0, 0x03B9, 0x03CC, 0x03CD, 0x03CE, 0x2002, 0x2003, 0x3008, ++ 0x3009, 0x349E, 0x34B9, 0x34BB, 0x34DF, 0x3515, 0x36EE, 0x36FC, ++ 0x3781, 0x382F, 0x3862, 0x387C, 0x38C7, 0x38E3, 0x391C, 0x393A, ++ 0x3A2E, 0x3A6C, 0x3AE4, 0x3B08, 0x3B19, 0x3B49, 0x3B9D, 0x3C18, ++ 0x3C4E, 0x3D33, 0x3D96, 0x3EAC, 0x3EB8, 0x3F1B, 0x3FFC, 0x4008, ++ 0x4018, 0x4039, 0x4046, 0x4096, 0x40E3, 0x412F, 0x4202, 0x4227, ++ 0x42A0, 0x4301, 0x4334, 0x4359, 0x43D5, 0x43D9, 0x440B, 0x446B, ++ 0x452B, 0x455D, 0x4561, 0x456B, 0x45D7, 0x45F9, 0x4635, 0x46BE, ++ 0x46C7, 0x4995, 0x49E6, 0x4A6E, 0x4A76, 0x4AB2, 0x4B33, 0x4BCE, ++ 0x4CCE, 0x4CED, 0x4CF8, 0x4D56, 0x4E0D, 0x4E26, 0x4E32, 0x4E38, ++ 0x4E39, 0x4E3D, 0x4E41, 0x4E82, 0x4E86, 0x4EAE, 0x4EC0, 0x4ECC, ++ 0x4EE4, 0x4F60, 0x4F80, 0x4F86, 0x4F8B, 0x4FAE, 0x4FBB, 0x4FBF, ++ 0x5002, 0x502B, 0x507A, 0x5099, 0x50CF, 0x50DA, 0x50E7, 0x5140, ++ 0x5145, 0x514D, 0x5154, 0x5164, 0x5167, 0x5168, 0x5169, 0x516D, ++ 0x5177, 0x5180, 0x518D, 0x5192, 0x5195, 0x5197, 0x51A4, 0x51AC, ++ 0x51B5, 0x51B7, 0x51C9, 0x51CC, 0x51DC, 0x51DE, 0x51F5, 0x5203, ++ 0x5207, 0x5217, 0x5229, 0x523A, 0x523B, 0x5246, 0x5272, 0x5277, ++ 0x5289, 0x529B, 0x52A3, 0x52B3, 0x52C7, 0x52C9, 0x52D2, 0x52DE, ++ 0x52E4, 0x52F5, 0x52FA, 0x5305, 0x5306, 0x5317, 0x533F, 0x5349, ++ 0x5351, 0x535A, 0x5373, 0x5375, 0x537D, 0x537F, 0x53C3, 0x53CA, ++ 0x53DF, 0x53E5, 0x53EB, 0x53F1, 0x5406, 0x540F, 0x541D, 0x5438, ++ 0x5442, 0x5448, 0x5468, 0x549E, 0x54A2, 0x54BD, 0x54F6, 0x5510, ++ 0x5553, 0x5555, 0x5563, 0x5584, 0x5587, 0x5599, 0x559D, 0x55AB, ++ 0x55B3, 0x55C0, 0x55C2, 0x55E2, 0x5606, 0x5651, 0x5668, 0x5674, ++ 0x56F9, 0x5716, 0x5717, 0x578B, 0x57CE, 0x57F4, 0x580D, 0x5831, ++ 0x5832, 0x5840, 0x585A, 0x585E, 0x58A8, 0x58AC, 0x58B3, 0x58D8, ++ 0x58DF, 0x58EE, 0x58F2, 0x58F7, 0x5906, 0x591A, 0x5922, 0x5944, ++ 0x5948, 0x5951, 0x5954, 0x5962, 0x5973, 0x59D8, 0x59EC, 0x5A1B, ++ 0x5A27, 0x5A62, 0x5A66, 0x5AB5, 0x5B08, 0x5B28, 0x5B3E, 0x5B85, ++ 0x5BC3, 0x5BD8, 0x5BE7, 0x5BEE, 0x5BF3, 0x5BFF, 0x5C06, 0x5C22, ++ 0x5C3F, 0x5C60, 0x5C62, 0x5C64, 0x5C65, 0x5C6E, 0x5C8D, 0x5CC0, ++ 0x5D19, 0x5D43, 0x5D50, 0x5D6B, 0x5D6E, 0x5D7C, 0x5DB2, 0x5DBA, ++ 0x5DE1, 0x5DE2, 0x5DFD, 0x5E28, 0x5E3D, 0x5E69, 0x5E74, 0x5EA6, ++ 0x5EB0, 0x5EB3, 0x5EB6, 0x5EC9, 0x5ECA, 0x5ED2, 0x5ED3, 0x5ED9, ++ 0x5EEC, 0x5EFE, 0x5F04, 0x5F22, 0x5F53, 0x5F62, 0x5F69, 0x5F6B, ++ 0x5F8B, 0x5F9A, 0x5FA9, 0x5FAD, 0x5FCD, 0x5FD7, 0x5FF5, 0x5FF9, ++ 0x6012, 0x601C, 0x6075, 0x6081, 0x6094, 0x60C7, 0x60D8, 0x60E1, ++ 0x6108, 0x6144, 0x6148, 0x614C, 0x614E, 0x6160, 0x6168, 0x617A, ++ 0x618E, 0x6190, 0x61A4, 0x61AF, 0x61B2, 0x61DE, 0x61F2, 0x61F6, ++ 0x6200, 0x6210, 0x621B, 0x622E, 0x6234, 0x625D, 0x62B1, 0x62C9, ++ 0x62CF, 0x62D3, 0x62D4, 0x62FC, 0x62FE, 0x633D, 0x6350, 0x6368, ++ 0x637B, 0x6383, 0x63A0, 0x63A9, 0x63C4, 0x63C5, 0x63E4, 0x641C, ++ 0x6422, 0x6452, 0x6469, 0x6477, 0x647E, 0x649A, 0x649D, 0x64C4, ++ 0x654F, 0x6556, 0x656C, 0x6578, 0x6599, 0x65C5, 0x65E2, 0x65E3, ++ 0x6613, 0x6649, 0x6674, 0x6688, 0x6691, 0x669C, 0x66B4, 0x66C6, ++ 0x66F4, 0x66F8, 0x6700, 0x6717, 0x671B, 0x6721, 0x674E, 0x6753, ++ 0x6756, 0x675E, 0x677B, 0x6785, 0x6797, 0x67F3, 0x67FA, 0x6817, ++ 0x681F, 0x6852, 0x6881, 0x6885, 0x688E, 0x68A8, 0x6914, 0x6942, ++ 0x69A3, 0x69EA, 0x6A02, 0x6A13, 0x6AA8, 0x6AD3, 0x6ADB, 0x6B04, ++ 0x6B21, 0x6B54, 0x6B72, 0x6B77, 0x6B79, 0x6B9F, 0x6BAE, 0x6BBA, ++ 0x6BBB, 0x6C4E, 0x6C67, 0x6C88, 0x6CBF, 0x6CCC, 0x6CCD, 0x6CE5, ++ 0x6D16, 0x6D1B, 0x6D1E, 0x6D34, 0x6D3E, 0x6D41, 0x6D69, 0x6D6A, ++ 0x6D77, 0x6D78, 0x6D85, 0x6DCB, 0x6DDA, 0x6DEA, 0x6DF9, 0x6E1A, ++ 0x6E2F, 0x6E6E, 0x6E9C, 0x6EBA, 0x6EC7, 0x6ECB, 0x6ED1, 0x6EDB, ++ 0x6F0F, 0x6F22, 0x6F23, 0x6F6E, 0x6FC6, 0x6FEB, 0x6FFE, 0x701B, ++ 0x701E, 0x7039, 0x704A, 0x7070, 0x7077, 0x707D, 0x7099, 0x70AD, ++ 0x70C8, 0x70D9, 0x7145, 0x7149, 0x716E, 0x719C, 0x71CE, 0x71D0, ++ 0x7210, 0x721B, 0x7228, 0x722B, 0x7235, 0x7250, 0x7262, 0x7280, ++ 0x7295, 0x72AF, 0x72C0, 0x72FC, 0x732A, 0x7375, 0x737A, 0x7387, ++ 0x738B, 0x73A5, 0x73B2, 0x73DE, 0x7406, 0x7409, 0x7422, 0x7447, ++ 0x745C, 0x7469, 0x7471, 0x7485, 0x7489, 0x7498, 0x74CA, 0x7506, ++ 0x7524, 0x753B, 0x753E, 0x7559, 0x7565, 0x7570, 0x75E2, 0x7610, ++ 0x761D, 0x761F, 0x7642, 0x7669, 0x76CA, 0x76DB, 0x76E7, 0x76F4, ++ 0x7701, 0x771E, 0x771F, 0x7740, 0x774A, 0x778B, 0x77A7, 0x784E, ++ 0x786B, 0x788C, 0x7891, 0x78CA, 0x78CC, 0x78FB, 0x792A, 0x793C, ++ 0x793E, 0x7948, 0x7949, 0x7950, 0x7956, 0x795D, 0x795E, 0x7965, ++ 0x797F, 0x798D, 0x798E, 0x798F, 0x79AE, 0x79CA, 0x79EB, 0x7A1C, ++ 0x7A40, 0x7A4A, 0x7A4F, 0x7A81, 0x7AB1, 0x7ACB, 0x7AEE, 0x7B20, ++ 0x7BC0, 0x7BC6, 0x7BC9, 0x7C3E, 0x7C60, 0x7C7B, 0x7C92, 0x7CBE, ++ 0x7CD2, 0x7CD6, 0x7CE3, 0x7CE7, 0x7CE8, 0x7D00, 0x7D10, 0x7D22, ++ 0x7D2F, 0x7D5B, 0x7D63, 0x7DA0, 0x7DBE, 0x7DC7, 0x7DF4, 0x7E02, ++ 0x7E09, 0x7E37, 0x7E41, 0x7E45, 0x7F3E, 0x7F72, 0x7F79, 0x7F7A, ++ 0x7F85, 0x7F95, 0x7F9A, 0x7FBD, 0x7FFA, 0x8001, 0x8005, 0x8046, ++ 0x8060, 0x806F, 0x8070, 0x807E, 0x808B, 0x80AD, 0x80B2, 0x8103, ++ 0x813E, 0x81D8, 0x81E8, 0x81ED, 0x8201, 0x8204, 0x8218, 0x826F, ++ 0x8279, 0x828B, 0x8291, 0x829D, 0x82B1, 0x82B3, 0x82BD, 0x82E5, ++ 0x82E6, 0x831D, 0x8323, 0x8336, 0x8352, 0x8353, 0x8363, 0x83AD, ++ 0x83BD, 0x83C9, 0x83CA, 0x83CC, 0x83DC, 0x83E7, 0x83EF, 0x83F1, ++ 0x843D, 0x8449, 0x8457, 0x84EE, 0x84F1, 0x84F3, 0x84FC, 0x8516, ++ 0x8564, 0x85CD, 0x85FA, 0x8606, 0x8612, 0x862D, 0x863F, 0x8650, ++ 0x865C, 0x8667, 0x8669, 0x8688, 0x86A9, 0x86E2, 0x870E, 0x8728, ++ 0x876B, 0x8779, 0x8786, 0x87BA, 0x87E1, 0x8801, 0x881F, 0x884C, ++ 0x8860, 0x8863, 0x88C2, 0x88CF, 0x88D7, 0x88DE, 0x88E1, 0x88F8, ++ 0x88FA, 0x8910, 0x8941, 0x8964, 0x8986, 0x898B, 0x8996, 0x8AA0, ++ 0x8AAA, 0x8ABF, 0x8ACB, 0x8AD2, 0x8AD6, 0x8AED, 0x8AF8, 0x8AFE, ++ 0x8B01, 0x8B39, 0x8B58, 0x8B80, 0x8B8A, 0x8C48, 0x8C55, 0x8CAB, ++ 0x8CC1, 0x8CC2, 0x8CC8, 0x8CD3, 0x8D08, 0x8D1B, 0x8D77, 0x8DBC, ++ 0x8DCB, 0x8DEF, 0x8DF0, 0x8ECA, 0x8ED4, 0x8F26, 0x8F2A, 0x8F38, ++ 0x8F3B, 0x8F62, 0x8F9E, 0x8FB0, 0x8FB6, 0x9023, 0x9038, 0x9072, ++ 0x907C, 0x908F, 0x9094, 0x90CE, 0x90DE, 0x90F1, 0x90FD, 0x9111, ++ 0x911B, 0x916A, 0x9199, 0x91B4, 0x91CC, 0x91CF, 0x91D1, 0x9234, ++ 0x9238, 0x9276, 0x927C, 0x92D7, 0x92D8, 0x9304, 0x934A, 0x93F9, ++ 0x9415, 0x958B, 0x95AD, 0x95B7, 0x962E, 0x964B, 0x964D, 0x9675, ++ 0x9678, 0x967C, 0x9686, 0x96A3, 0x96B7, 0x96B8, 0x96C3, 0x96E2, ++ 0x96E3, 0x96F6, 0x96F7, 0x9723, 0x9732, 0x9748, 0x9756, 0x97DB, ++ 0x97E0, 0x97FF, 0x980B, 0x9818, 0x9829, 0x983B, 0x985E, 0x98E2, ++ 0x98EF, 0x98FC, 0x9928, 0x9929, 0x99A7, 0x99C2, 0x99F1, 0x99FE, ++ 0x9A6A, 0x9B12, 0x9B6F, 0x9C40, 0x9C57, 0x9CFD, 0x9D67, 0x9DB4, ++ 0x9DFA, 0x9E1E, 0x9E7F, 0x9E97, 0x9E9F, 0x9EBB, 0x9ECE, 0x9EF9, ++ 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x9F3B, 0x9F43, 0x9F8D, 0x9F8E, ++ 0x9F9C, + }; +-static const uint16_t +-_hb_ucd_dm1_p2_map[110] = ++static const uint16_t _hb_ucd_dm1_p2_map[110]= + { +- 0x0122u, 0x051Cu, 0x0525u, 0x054Bu, 0x063Au, 0x0804u, 0x08DEu, 0x0A2Cu, +- 0x0B63u, 0x14E4u, 0x16A8u, 0x16EAu, 0x19C8u, 0x1B18u, 0x1D0Bu, 0x1DE4u, +- 0x1DE6u, 0x2183u, 0x219Fu, 0x2331u, 0x26D4u, 0x2844u, 0x284Au, 0x2B0Cu, +- 0x2BF1u, 0x300Au, 0x32B8u, 0x335Fu, 0x3393u, 0x339Cu, 0x33C3u, 0x33D5u, +- 0x346Du, 0x36A3u, 0x38A7u, 0x3A8Du, 0x3AFAu, 0x3CBCu, 0x3D1Eu, 0x3ED1u, +- 0x3F5Eu, 0x3F8Eu, 0x4263u, 0x42EEu, 0x43ABu, 0x4608u, 0x4735u, 0x4814u, +- 0x4C36u, 0x4C92u, 0x4FA1u, 0x4FB8u, 0x5044u, 0x50F2u, 0x50F3u, 0x5119u, +- 0x5133u, 0x5249u, 0x541Du, 0x5626u, 0x569Au, 0x56C5u, 0x597Cu, 0x5AA7u, +- 0x5BABu, 0x5C80u, 0x5CD0u, 0x5F86u, 0x61DAu, 0x6228u, 0x6247u, 0x62D9u, +- 0x633Eu, 0x64DAu, 0x6523u, 0x65A8u, 0x67A7u, 0x67B5u, 0x6B3Cu, 0x6C36u, +- 0x6CD5u, 0x6D6Bu, 0x6F2Cu, 0x6FB1u, 0x70D2u, 0x73CAu, 0x7667u, 0x78AEu, +- 0x7966u, 0x7CA8u, 0x7ED3u, 0x7F2Fu, 0x85D2u, 0x85EDu, 0x872Eu, 0x8BFAu, +- 0x8D77u, 0x9145u, 0x91DFu, 0x921Au, 0x940Au, 0x9496u, 0x95B6u, 0x9B30u, +- 0xA0CEu, 0xA105u, 0xA20Eu, 0xA291u, 0xA392u, 0xA600u, ++ 0x0122, 0x051C, 0x0525, 0x054B, 0x063A, 0x0804, 0x08DE, 0x0A2C, ++ 0x0B63, 0x14E4, 0x16A8, 0x16EA, 0x19C8, 0x1B18, 0x1D0B, 0x1DE4, ++ 0x1DE6, 0x2183, 0x219F, 0x2331, 0x26D4, 0x2844, 0x284A, 0x2B0C, ++ 0x2BF1, 0x300A, 0x32B8, 0x335F, 0x3393, 0x339C, 0x33C3, 0x33D5, ++ 0x346D, 0x36A3, 0x38A7, 0x3A8D, 0x3AFA, 0x3CBC, 0x3D1E, 0x3ED1, ++ 0x3F5E, 0x3F8E, 0x4263, 0x42EE, 0x43AB, 0x4608, 0x4735, 0x4814, ++ 0x4C36, 0x4C92, 0x4FA1, 0x4FB8, 0x5044, 0x50F2, 0x50F3, 0x5119, ++ 0x5133, 0x5249, 0x541D, 0x5626, 0x569A, 0x56C5, 0x597C, 0x5AA7, ++ 0x5BAB, 0x5C80, 0x5CD0, 0x5F86, 0x61DA, 0x6228, 0x6247, 0x62D9, ++ 0x633E, 0x64DA, 0x6523, 0x65A8, 0x67A7, 0x67B5, 0x6B3C, 0x6C36, ++ 0x6CD5, 0x6D6B, 0x6F2C, 0x6FB1, 0x70D2, 0x73CA, 0x7667, 0x78AE, ++ 0x7966, 0x7CA8, 0x7ED3, 0x7F2F, 0x85D2, 0x85ED, 0x872E, 0x8BFA, ++ 0x8D77, 0x9145, 0x91DF, 0x921A, 0x940A, 0x9496, 0x95B6, 0x9B30, ++ 0xA0CE, 0xA105, 0xA20E, 0xA291, 0xA392, 0xA600, + }; +-static const uint32_t +-_hb_ucd_dm2_u32_map[638] = ++static const uint32_t _hb_ucd_dm2_u32_map[638]= + { +- HB_CODEPOINT_ENCODE3_11_7_14 (0x003Cu, 0x0338u, 0x226Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x003Du, 0x0338u, 0x2260u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x003Eu, 0x0338u, 0x226Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0300u, 0x00C0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0301u, 0x00C1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0302u, 0x00C2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0303u, 0x00C3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0304u, 0x0100u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0306u, 0x0102u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0307u, 0x0226u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0308u, 0x00C4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0309u, 0x1EA2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Au, 0x00C5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Cu, 0x01CDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Fu, 0x0200u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0311u, 0x0202u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0323u, 0x1EA0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0325u, 0x1E00u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0328u, 0x0104u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0307u, 0x1E02u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0323u, 0x1E04u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0331u, 0x1E06u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0301u, 0x0106u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0302u, 0x0108u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0307u, 0x010Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x030Cu, 0x010Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0327u, 0x00C7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0307u, 0x1E0Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x030Cu, 0x010Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0323u, 0x1E0Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0327u, 0x1E10u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x032Du, 0x1E12u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0331u, 0x1E0Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0300u, 0x00C8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0301u, 0x00C9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0302u, 0x00CAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0303u, 0x1EBCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0304u, 0x0112u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0306u, 0x0114u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0307u, 0x0116u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0308u, 0x00CBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0309u, 0x1EBAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Cu, 0x011Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Fu, 0x0204u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0311u, 0x0206u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0323u, 0x1EB8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0327u, 0x0228u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0328u, 0x0118u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x032Du, 0x1E18u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0330u, 0x1E1Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0046u, 0x0307u, 0x1E1Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0301u, 0x01F4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0302u, 0x011Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0304u, 0x1E20u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0306u, 0x011Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0307u, 0x0120u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x030Cu, 0x01E6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0327u, 0x0122u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0302u, 0x0124u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0307u, 0x1E22u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0308u, 0x1E26u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x030Cu, 0x021Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0323u, 0x1E24u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0327u, 0x1E28u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x032Eu, 0x1E2Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0300u, 0x00CCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0301u, 0x00CDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0302u, 0x00CEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0303u, 0x0128u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0304u, 0x012Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0306u, 0x012Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0307u, 0x0130u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0308u, 0x00CFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0309u, 0x1EC8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Cu, 0x01CFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Fu, 0x0208u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0311u, 0x020Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0323u, 0x1ECAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0328u, 0x012Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0330u, 0x1E2Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Au, 0x0302u, 0x0134u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0301u, 0x1E30u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x030Cu, 0x01E8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0323u, 0x1E32u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0327u, 0x0136u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0331u, 0x1E34u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0301u, 0x0139u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x030Cu, 0x013Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0323u, 0x1E36u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0327u, 0x013Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x032Du, 0x1E3Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0331u, 0x1E3Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0301u, 0x1E3Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0307u, 0x1E40u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0323u, 0x1E42u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0300u, 0x01F8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0301u, 0x0143u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0303u, 0x00D1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0307u, 0x1E44u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x030Cu, 0x0147u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0323u, 0x1E46u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0327u, 0x0145u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x032Du, 0x1E4Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0331u, 0x1E48u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0300u, 0x00D2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0301u, 0x00D3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0302u, 0x00D4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0303u, 0x00D5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0304u, 0x014Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0306u, 0x014Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0307u, 0x022Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0308u, 0x00D6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0309u, 0x1ECEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Bu, 0x0150u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Cu, 0x01D1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Fu, 0x020Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0311u, 0x020Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x031Bu, 0x01A0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0323u, 0x1ECCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0328u, 0x01EAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0301u, 0x1E54u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0307u, 0x1E56u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0301u, 0x0154u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0307u, 0x1E58u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Cu, 0x0158u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Fu, 0x0210u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0311u, 0x0212u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0323u, 0x1E5Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0327u, 0x0156u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0331u, 0x1E5Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0301u, 0x015Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0302u, 0x015Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0307u, 0x1E60u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x030Cu, 0x0160u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0323u, 0x1E62u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0326u, 0x0218u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0327u, 0x015Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0307u, 0x1E6Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x030Cu, 0x0164u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0323u, 0x1E6Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0326u, 0x021Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0327u, 0x0162u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x032Du, 0x1E70u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0331u, 0x1E6Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0300u, 0x00D9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0301u, 0x00DAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0302u, 0x00DBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0303u, 0x0168u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0304u, 0x016Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0306u, 0x016Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0308u, 0x00DCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0309u, 0x1EE6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Au, 0x016Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Bu, 0x0170u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Cu, 0x01D3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Fu, 0x0214u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0311u, 0x0216u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x031Bu, 0x01AFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0323u, 0x1EE4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0324u, 0x1E72u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0328u, 0x0172u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x032Du, 0x1E76u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0330u, 0x1E74u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0303u, 0x1E7Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0323u, 0x1E7Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0300u, 0x1E80u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0301u, 0x1E82u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0302u, 0x0174u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0307u, 0x1E86u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0308u, 0x1E84u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0323u, 0x1E88u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0307u, 0x1E8Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0308u, 0x1E8Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0300u, 0x1EF2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0301u, 0x00DDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0302u, 0x0176u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0303u, 0x1EF8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0304u, 0x0232u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0307u, 0x1E8Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0308u, 0x0178u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0309u, 0x1EF6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0323u, 0x1EF4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0301u, 0x0179u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0302u, 0x1E90u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0307u, 0x017Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x030Cu, 0x017Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0323u, 0x1E92u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0331u, 0x1E94u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0300u, 0x00E0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0301u, 0x00E1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0302u, 0x00E2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0303u, 0x00E3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0304u, 0x0101u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0306u, 0x0103u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0307u, 0x0227u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0308u, 0x00E4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0309u, 0x1EA3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Au, 0x00E5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Cu, 0x01CEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Fu, 0x0201u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0311u, 0x0203u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0323u, 0x1EA1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0325u, 0x1E01u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0328u, 0x0105u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0307u, 0x1E03u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0323u, 0x1E05u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0331u, 0x1E07u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0301u, 0x0107u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0302u, 0x0109u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0307u, 0x010Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x030Cu, 0x010Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0327u, 0x00E7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0307u, 0x1E0Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x030Cu, 0x010Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0323u, 0x1E0Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0327u, 0x1E11u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x032Du, 0x1E13u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0331u, 0x1E0Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0300u, 0x00E8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0301u, 0x00E9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0302u, 0x00EAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0303u, 0x1EBDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0304u, 0x0113u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0306u, 0x0115u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0307u, 0x0117u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0308u, 0x00EBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0309u, 0x1EBBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Cu, 0x011Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Fu, 0x0205u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0311u, 0x0207u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0323u, 0x1EB9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0327u, 0x0229u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0328u, 0x0119u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x032Du, 0x1E19u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0330u, 0x1E1Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0066u, 0x0307u, 0x1E1Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0301u, 0x01F5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0302u, 0x011Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0304u, 0x1E21u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0306u, 0x011Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0307u, 0x0121u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x030Cu, 0x01E7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0327u, 0x0123u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0302u, 0x0125u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0307u, 0x1E23u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0308u, 0x1E27u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x030Cu, 0x021Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0323u, 0x1E25u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0327u, 0x1E29u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x032Eu, 0x1E2Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0331u, 0x1E96u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0300u, 0x00ECu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0301u, 0x00EDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0302u, 0x00EEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0303u, 0x0129u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0304u, 0x012Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0306u, 0x012Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0308u, 0x00EFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0309u, 0x1EC9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Cu, 0x01D0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Fu, 0x0209u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0311u, 0x020Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0323u, 0x1ECBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0328u, 0x012Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0330u, 0x1E2Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x0302u, 0x0135u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x030Cu, 0x01F0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0301u, 0x1E31u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x030Cu, 0x01E9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0323u, 0x1E33u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0327u, 0x0137u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0331u, 0x1E35u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0301u, 0x013Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x030Cu, 0x013Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0323u, 0x1E37u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0327u, 0x013Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x032Du, 0x1E3Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0331u, 0x1E3Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0301u, 0x1E3Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0307u, 0x1E41u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0323u, 0x1E43u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0300u, 0x01F9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0301u, 0x0144u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0303u, 0x00F1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0307u, 0x1E45u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x030Cu, 0x0148u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0323u, 0x1E47u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0327u, 0x0146u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x032Du, 0x1E4Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0331u, 0x1E49u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0300u, 0x00F2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0301u, 0x00F3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0302u, 0x00F4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0303u, 0x00F5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0304u, 0x014Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0306u, 0x014Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0307u, 0x022Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0308u, 0x00F6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0309u, 0x1ECFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Bu, 0x0151u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Cu, 0x01D2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Fu, 0x020Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0311u, 0x020Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x031Bu, 0x01A1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0323u, 0x1ECDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0328u, 0x01EBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0301u, 0x1E55u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0307u, 0x1E57u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0301u, 0x0155u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0307u, 0x1E59u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Cu, 0x0159u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Fu, 0x0211u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0311u, 0x0213u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0323u, 0x1E5Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0327u, 0x0157u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0331u, 0x1E5Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0301u, 0x015Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0302u, 0x015Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0307u, 0x1E61u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x030Cu, 0x0161u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0323u, 0x1E63u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0326u, 0x0219u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0327u, 0x015Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0307u, 0x1E6Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0308u, 0x1E97u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x030Cu, 0x0165u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0323u, 0x1E6Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0326u, 0x021Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0327u, 0x0163u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x032Du, 0x1E71u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0331u, 0x1E6Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0300u, 0x00F9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0301u, 0x00FAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0302u, 0x00FBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0303u, 0x0169u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0304u, 0x016Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0306u, 0x016Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0308u, 0x00FCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0309u, 0x1EE7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Au, 0x016Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Bu, 0x0171u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Cu, 0x01D4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Fu, 0x0215u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0311u, 0x0217u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x031Bu, 0x01B0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0323u, 0x1EE5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0324u, 0x1E73u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0328u, 0x0173u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x032Du, 0x1E77u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0330u, 0x1E75u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0303u, 0x1E7Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0323u, 0x1E7Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0300u, 0x1E81u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0301u, 0x1E83u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0302u, 0x0175u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0307u, 0x1E87u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0308u, 0x1E85u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x030Au, 0x1E98u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0323u, 0x1E89u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0307u, 0x1E8Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0308u, 0x1E8Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0300u, 0x1EF3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0301u, 0x00FDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0302u, 0x0177u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0303u, 0x1EF9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0304u, 0x0233u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0307u, 0x1E8Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0308u, 0x00FFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0309u, 0x1EF7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x030Au, 0x1E99u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0323u, 0x1EF5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0301u, 0x017Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0302u, 0x1E91u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0307u, 0x017Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x030Cu, 0x017Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0323u, 0x1E93u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0331u, 0x1E95u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0300u, 0x1FEDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0301u, 0x0385u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0342u, 0x1FC1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0300u, 0x1EA6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0301u, 0x1EA4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0303u, 0x1EAAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0309u, 0x1EA8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4u, 0x0304u, 0x01DEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5u, 0x0301u, 0x01FAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0301u, 0x01FCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0304u, 0x01E2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7u, 0x0301u, 0x1E08u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0300u, 0x1EC0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0301u, 0x1EBEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0303u, 0x1EC4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0309u, 0x1EC2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CFu, 0x0301u, 0x1E2Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0300u, 0x1ED2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0301u, 0x1ED0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0303u, 0x1ED6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0309u, 0x1ED4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0301u, 0x1E4Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0304u, 0x022Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0308u, 0x1E4Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6u, 0x0304u, 0x022Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8u, 0x0301u, 0x01FEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0300u, 0x01DBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0301u, 0x01D7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0304u, 0x01D5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x030Cu, 0x01D9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0300u, 0x1EA7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0301u, 0x1EA5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0303u, 0x1EABu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0309u, 0x1EA9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4u, 0x0304u, 0x01DFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5u, 0x0301u, 0x01FBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0301u, 0x01FDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0304u, 0x01E3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7u, 0x0301u, 0x1E09u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0300u, 0x1EC1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0301u, 0x1EBFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0303u, 0x1EC5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0309u, 0x1EC3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EFu, 0x0301u, 0x1E2Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0300u, 0x1ED3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0301u, 0x1ED1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0303u, 0x1ED7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0309u, 0x1ED5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0301u, 0x1E4Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0304u, 0x022Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0308u, 0x1E4Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6u, 0x0304u, 0x022Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8u, 0x0301u, 0x01FFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0300u, 0x01DCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0301u, 0x01D8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0304u, 0x01D6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x030Cu, 0x01DAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0300u, 0x1EB0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0301u, 0x1EAEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0303u, 0x1EB4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0309u, 0x1EB2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0300u, 0x1EB1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0301u, 0x1EAFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0303u, 0x1EB5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0309u, 0x1EB3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0300u, 0x1E14u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0301u, 0x1E16u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0300u, 0x1E15u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0301u, 0x1E17u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0300u, 0x1E50u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0301u, 0x1E52u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0300u, 0x1E51u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0301u, 0x1E53u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x015Au, 0x0307u, 0x1E64u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x015Bu, 0x0307u, 0x1E65u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0160u, 0x0307u, 0x1E66u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0161u, 0x0307u, 0x1E67u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0168u, 0x0301u, 0x1E78u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0169u, 0x0301u, 0x1E79u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x016Au, 0x0308u, 0x1E7Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x016Bu, 0x0308u, 0x1E7Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x017Fu, 0x0307u, 0x1E9Bu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0300u, 0x1EDCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0301u, 0x1EDAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0303u, 0x1EE0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0309u, 0x1EDEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0323u, 0x1EE2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0300u, 0x1EDDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0301u, 0x1EDBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0303u, 0x1EE1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0309u, 0x1EDFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0323u, 0x1EE3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0300u, 0x1EEAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0301u, 0x1EE8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0303u, 0x1EEEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0309u, 0x1EECu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0323u, 0x1EF0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0300u, 0x1EEBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0301u, 0x1EE9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0303u, 0x1EEFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0309u, 0x1EEDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0323u, 0x1EF1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7u, 0x030Cu, 0x01EEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01EAu, 0x0304u, 0x01ECu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x01EBu, 0x0304u, 0x01EDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0226u, 0x0304u, 0x01E0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0227u, 0x0304u, 0x01E1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0228u, 0x0306u, 0x1E1Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0229u, 0x0306u, 0x1E1Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x022Eu, 0x0304u, 0x0230u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x022Fu, 0x0304u, 0x0231u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0292u, 0x030Cu, 0x01EFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0308u, 0x0301u, 0x0000u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0300u, 0x1FBAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0301u, 0x0386u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0304u, 0x1FB9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0306u, 0x1FB8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0313u, 0x1F08u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0314u, 0x1F09u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0345u, 0x1FBCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0300u, 0x1FC8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0301u, 0x0388u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0313u, 0x1F18u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0314u, 0x1F19u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0300u, 0x1FCAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0301u, 0x0389u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0313u, 0x1F28u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0314u, 0x1F29u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0345u, 0x1FCCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0300u, 0x1FDAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0301u, 0x038Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0304u, 0x1FD9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0306u, 0x1FD8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0308u, 0x03AAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0313u, 0x1F38u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0314u, 0x1F39u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0300u, 0x1FF8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0301u, 0x038Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0313u, 0x1F48u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0314u, 0x1F49u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1u, 0x0314u, 0x1FECu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0300u, 0x1FEAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0301u, 0x038Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0304u, 0x1FE9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0306u, 0x1FE8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0308u, 0x03ABu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0314u, 0x1F59u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0300u, 0x1FFAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0301u, 0x038Fu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0313u, 0x1F68u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0314u, 0x1F69u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0345u, 0x1FFCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03ACu, 0x0345u, 0x1FB4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03AEu, 0x0345u, 0x1FC4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0300u, 0x1F70u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0301u, 0x03ACu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0304u, 0x1FB1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0306u, 0x1FB0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0313u, 0x1F00u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0314u, 0x1F01u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0342u, 0x1FB6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0345u, 0x1FB3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0300u, 0x1F72u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0301u, 0x03ADu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0313u, 0x1F10u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0314u, 0x1F11u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0300u, 0x1F74u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0301u, 0x03AEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0313u, 0x1F20u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0314u, 0x1F21u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0342u, 0x1FC6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0345u, 0x1FC3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0300u, 0x1F76u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0301u, 0x03AFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0304u, 0x1FD1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0306u, 0x1FD0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0308u, 0x03CAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0313u, 0x1F30u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0314u, 0x1F31u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0342u, 0x1FD6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0300u, 0x1F78u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0301u, 0x03CCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0313u, 0x1F40u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0314u, 0x1F41u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0313u, 0x1FE4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0314u, 0x1FE5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0300u, 0x1F7Au), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0301u, 0x03CDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0304u, 0x1FE1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0306u, 0x1FE0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0308u, 0x03CBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0313u, 0x1F50u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0314u, 0x1F51u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0342u, 0x1FE6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0300u, 0x1F7Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0301u, 0x03CEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0313u, 0x1F60u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0314u, 0x1F61u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0342u, 0x1FF6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0345u, 0x1FF3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0300u, 0x1FD2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0301u, 0x0390u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0342u, 0x1FD7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0300u, 0x1FE2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0301u, 0x03B0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0342u, 0x1FE7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CEu, 0x0345u, 0x1FF4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0301u, 0x03D3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0308u, 0x03D4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0406u, 0x0308u, 0x0407u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0306u, 0x04D0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0308u, 0x04D2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0413u, 0x0301u, 0x0403u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0300u, 0x0400u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0306u, 0x04D6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0308u, 0x0401u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0306u, 0x04C1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0308u, 0x04DCu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0417u, 0x0308u, 0x04DEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0300u, 0x040Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0304u, 0x04E2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0306u, 0x0419u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0308u, 0x04E4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x041Au, 0x0301u, 0x040Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x041Eu, 0x0308u, 0x04E6u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0304u, 0x04EEu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0306u, 0x040Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0308u, 0x04F0u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x030Bu, 0x04F2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0427u, 0x0308u, 0x04F4u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x042Bu, 0x0308u, 0x04F8u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x042Du, 0x0308u, 0x04ECu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0306u, 0x04D1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0308u, 0x04D3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0433u, 0x0301u, 0x0453u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0300u, 0x0450u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0306u, 0x04D7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0308u, 0x0451u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0306u, 0x04C2u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0308u, 0x04DDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0437u, 0x0308u, 0x04DFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0300u, 0x045Du), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0304u, 0x04E3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0306u, 0x0439u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0308u, 0x04E5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x043Au, 0x0301u, 0x045Cu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x043Eu, 0x0308u, 0x04E7u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0304u, 0x04EFu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0306u, 0x045Eu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0308u, 0x04F1u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x030Bu, 0x04F3u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0447u, 0x0308u, 0x04F5u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x044Bu, 0x0308u, 0x04F9u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x044Du, 0x0308u, 0x04EDu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0456u, 0x0308u, 0x0457u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0474u, 0x030Fu, 0x0476u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x0475u, 0x030Fu, 0x0477u), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8u, 0x0308u, 0x04DAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9u, 0x0308u, 0x04DBu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8u, 0x0308u, 0x04EAu), +- HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x003C, 0x0338, 0x226E),HB_CODEPOINT_ENCODE3_11_7_14 (0x003D, 0x0338, 0x2260), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x003E, 0x0338, 0x226F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0300, 0x00C0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0301, 0x00C1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0302, 0x00C2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0303, 0x00C3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0304, 0x0100), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0306, 0x0102),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0307, 0x0226), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0308, 0x00C4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0309, 0x1EA2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030A, 0x00C5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030C, 0x01CD), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030F, 0x0200),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0311, 0x0202), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0323, 0x1EA0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0325, 0x1E00), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0328, 0x0104),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0307, 0x1E02), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0323, 0x1E04),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0331, 0x1E06), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0301, 0x0106),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0302, 0x0108), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0307, 0x010A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x030C, 0x010C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0327, 0x00C7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0307, 0x1E0A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x030C, 0x010E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0323, 0x1E0C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0327, 0x1E10),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x032D, 0x1E12), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0331, 0x1E0E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0300, 0x00C8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0301, 0x00C9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0302, 0x00CA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0303, 0x1EBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0304, 0x0112), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0306, 0x0114),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0307, 0x0116), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0308, 0x00CB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0309, 0x1EBA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030C, 0x011A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030F, 0x0204), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0311, 0x0206),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0323, 0x1EB8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0327, 0x0228),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0328, 0x0118), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x032D, 0x1E18),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0330, 0x1E1A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0046, 0x0307, 0x1E1E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0301, 0x01F4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0302, 0x011C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0304, 0x1E20), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0306, 0x011E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0307, 0x0120), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x030C, 0x01E6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0327, 0x0122), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0302, 0x0124),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0307, 0x1E22), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0308, 0x1E26),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x030C, 0x021E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0323, 0x1E24),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0327, 0x1E28), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x032E, 0x1E2A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0300, 0x00CC), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0301, 0x00CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0302, 0x00CE), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0303, 0x0128),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0304, 0x012A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0306, 0x012C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0307, 0x0130), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0308, 0x00CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0309, 0x1EC8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030C, 0x01CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030F, 0x0208), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0311, 0x020A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0323, 0x1ECA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0328, 0x012E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0330, 0x1E2C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004A, 0x0302, 0x0134),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0301, 0x1E30), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x030C, 0x01E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0323, 0x1E32), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0327, 0x0136),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0331, 0x1E34), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0301, 0x0139),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x030C, 0x013D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0323, 0x1E36),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0327, 0x013B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x032D, 0x1E3C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0331, 0x1E3A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0301, 0x1E3E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0307, 0x1E40), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0323, 0x1E42),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0300, 0x01F8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0301, 0x0143),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0303, 0x00D1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0307, 0x1E44),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x030C, 0x0147), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0323, 0x1E46),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0327, 0x0145), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x032D, 0x1E4A),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0331, 0x1E48), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0300, 0x00D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0301, 0x00D3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0302, 0x00D4),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0303, 0x00D5), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0304, 0x014C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0306, 0x014E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0307, 0x022E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0308, 0x00D6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0309, 0x1ECE),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030B, 0x0150), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030C, 0x01D1),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030F, 0x020C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0311, 0x020E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x031B, 0x01A0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0323, 0x1ECC),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0328, 0x01EA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0301, 0x1E54),HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0307, 0x1E56), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0301, 0x0154),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0307, 0x1E58), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030C, 0x0158),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030F, 0x0210), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0311, 0x0212),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0323, 0x1E5A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0327, 0x0156),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0331, 0x1E5E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0301, 0x015A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0302, 0x015C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0307, 0x1E60),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x030C, 0x0160), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0323, 0x1E62),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0326, 0x0218), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0327, 0x015E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0307, 0x1E6A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x030C, 0x0164),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0323, 0x1E6C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0326, 0x021A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0327, 0x0162), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x032D, 0x1E70),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0331, 0x1E6E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0300, 0x00D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0301, 0x00DA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0302, 0x00DB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0303, 0x0168), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0304, 0x016A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0306, 0x016C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0308, 0x00DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0309, 0x1EE6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030A, 0x016E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030B, 0x0170), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030C, 0x01D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030F, 0x0214), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0311, 0x0216),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x031B, 0x01AF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0323, 0x1EE4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0324, 0x1E72), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0328, 0x0172),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x032D, 0x1E76), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0330, 0x1E74),HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0303, 0x1E7C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0323, 0x1E7E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0300, 0x1E80), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0301, 0x1E82),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0302, 0x0174), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0307, 0x1E86),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0308, 0x1E84), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0323, 0x1E88),HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0307, 0x1E8A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0308, 0x1E8C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0300, 0x1EF2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0301, 0x00DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0302, 0x0176), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0303, 0x1EF8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0304, 0x0232), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0307, 0x1E8E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0308, 0x0178), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0309, 0x1EF6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0323, 0x1EF4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0301, 0x0179),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0302, 0x1E90), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0307, 0x017B),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x030C, 0x017D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0323, 0x1E92),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0331, 0x1E94), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0300, 0x00E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0301, 0x00E1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0302, 0x00E2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0303, 0x00E3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0304, 0x0101),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0306, 0x0103), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0307, 0x0227),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0308, 0x00E4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0309, 0x1EA3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030A, 0x00E5), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030C, 0x01CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030F, 0x0201), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0311, 0x0203),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0323, 0x1EA1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0325, 0x1E01),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0328, 0x0105), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0307, 0x1E03),HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0323, 0x1E05), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0331, 0x1E07),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0301, 0x0107), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0302, 0x0109),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0307, 0x010B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x030C, 0x010D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0327, 0x00E7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0307, 0x1E0B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x030C, 0x010F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0323, 0x1E0D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0327, 0x1E11), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x032D, 0x1E13),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0331, 0x1E0F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0300, 0x00E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0301, 0x00E9), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0302, 0x00EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0303, 0x1EBD), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0304, 0x0113),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0306, 0x0115), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0307, 0x0117),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0308, 0x00EB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0309, 0x1EBB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030C, 0x011B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030F, 0x0205),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0311, 0x0207), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0323, 0x1EB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0327, 0x0229), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0328, 0x0119),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x032D, 0x1E19), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0330, 0x1E1B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0066, 0x0307, 0x1E1F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0301, 0x01F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0302, 0x011D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0304, 0x1E21),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0306, 0x011F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0307, 0x0121),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x030C, 0x01E7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0327, 0x0123),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0302, 0x0125), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0307, 0x1E23),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0308, 0x1E27), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x030C, 0x021F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0323, 0x1E25), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0327, 0x1E29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x032E, 0x1E2B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0331, 0x1E96),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0300, 0x00EC), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0301, 0x00ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0302, 0x00EE), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0303, 0x0129),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0304, 0x012B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0306, 0x012D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0308, 0x00EF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0309, 0x1EC9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030C, 0x01D0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030F, 0x0209),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0311, 0x020B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0323, 0x1ECB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0328, 0x012F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0330, 0x1E2D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x0302, 0x0135), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x030C, 0x01F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0301, 0x1E31), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x030C, 0x01E9),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0323, 0x1E33), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0327, 0x0137),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0331, 0x1E35), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0301, 0x013A),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x030C, 0x013E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0323, 0x1E37),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0327, 0x013C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x032D, 0x1E3D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0331, 0x1E3B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0301, 0x1E3F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0307, 0x1E41), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0323, 0x1E43),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0300, 0x01F9), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0301, 0x0144),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0303, 0x00F1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0307, 0x1E45),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x030C, 0x0148), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0323, 0x1E47),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0327, 0x0146), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x032D, 0x1E4B),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0331, 0x1E49), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0300, 0x00F2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0301, 0x00F3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0302, 0x00F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0303, 0x00F5), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0304, 0x014D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0306, 0x014F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0307, 0x022F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0308, 0x00F6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0309, 0x1ECF),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030B, 0x0151), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030C, 0x01D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030F, 0x020D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0311, 0x020F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x031B, 0x01A1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0323, 0x1ECD),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0328, 0x01EB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0301, 0x1E55),HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0307, 0x1E57), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0301, 0x0155),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0307, 0x1E59), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030C, 0x0159),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030F, 0x0211), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0311, 0x0213),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0323, 0x1E5B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0327, 0x0157),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0331, 0x1E5F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0301, 0x015B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0302, 0x015D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0307, 0x1E61),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x030C, 0x0161), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0323, 0x1E63),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0326, 0x0219), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0327, 0x015F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0307, 0x1E6B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0308, 0x1E97),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x030C, 0x0165), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0323, 0x1E6D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0326, 0x021B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0327, 0x0163),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x032D, 0x1E71), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0331, 0x1E6F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0300, 0x00F9), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0301, 0x00FA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0302, 0x00FB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0303, 0x0169),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0304, 0x016B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0306, 0x016D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0308, 0x00FC), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0309, 0x1EE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030A, 0x016F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030B, 0x0171),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030C, 0x01D4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030F, 0x0215),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0311, 0x0217), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x031B, 0x01B0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0323, 0x1EE5), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0324, 0x1E73),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0328, 0x0173), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x032D, 0x1E77),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0330, 0x1E75), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0303, 0x1E7D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0323, 0x1E7F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0300, 0x1E81),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0301, 0x1E83), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0302, 0x0175),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0307, 0x1E87), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0308, 0x1E85),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x030A, 0x1E98), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0323, 0x1E89),HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0307, 0x1E8B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0308, 0x1E8D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0300, 0x1EF3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0301, 0x00FD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0302, 0x0177), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0303, 0x1EF9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0304, 0x0233), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0307, 0x1E8F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0308, 0x00FF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0309, 0x1EF7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x030A, 0x1E99), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0323, 0x1EF5),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0301, 0x017A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0302, 0x1E91),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0307, 0x017C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x030C, 0x017E),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0323, 0x1E93), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0331, 0x1E95),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0300, 0x1FED), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0301, 0x0385),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0342, 0x1FC1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0300, 0x1EA6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0301, 0x1EA4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0303, 0x1EAA),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0309, 0x1EA8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4, 0x0304, 0x01DE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5, 0x0301, 0x01FA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0301, 0x01FC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0304, 0x01E2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7, 0x0301, 0x1E08),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0300, 0x1EC0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0301, 0x1EBE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0303, 0x1EC4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0309, 0x1EC2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CF, 0x0301, 0x1E2E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0300, 0x1ED2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0301, 0x1ED0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0303, 0x1ED6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0309, 0x1ED4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0301, 0x1E4C),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0304, 0x022C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0308, 0x1E4E),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6, 0x0304, 0x022A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8, 0x0301, 0x01FE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0300, 0x01DB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0301, 0x01D7),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0304, 0x01D5), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x030C, 0x01D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0300, 0x1EA7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0301, 0x1EA5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0303, 0x1EAB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0309, 0x1EA9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4, 0x0304, 0x01DF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5, 0x0301, 0x01FB),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0301, 0x01FD), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0304, 0x01E3),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7, 0x0301, 0x1E09), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0300, 0x1EC1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0301, 0x1EBF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0303, 0x1EC5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0309, 0x1EC3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00EF, 0x0301, 0x1E2F),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0300, 0x1ED3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0301, 0x1ED1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0303, 0x1ED7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0309, 0x1ED5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0301, 0x1E4D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0304, 0x022D),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0308, 0x1E4F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6, 0x0304, 0x022B),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8, 0x0301, 0x01FF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0300, 0x01DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0301, 0x01D8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0304, 0x01D6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x030C, 0x01DA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0300, 0x1EB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0301, 0x1EAE), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0303, 0x1EB4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0309, 0x1EB2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0300, 0x1EB1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0301, 0x1EAF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0303, 0x1EB5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0309, 0x1EB3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0300, 0x1E14),HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0301, 0x1E16), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0300, 0x1E15),HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0301, 0x1E17), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0300, 0x1E50),HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0301, 0x1E52), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0300, 0x1E51),HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0301, 0x1E53), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x015A, 0x0307, 0x1E64),HB_CODEPOINT_ENCODE3_11_7_14 (0x015B, 0x0307, 0x1E65), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0160, 0x0307, 0x1E66),HB_CODEPOINT_ENCODE3_11_7_14 (0x0161, 0x0307, 0x1E67), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0168, 0x0301, 0x1E78),HB_CODEPOINT_ENCODE3_11_7_14 (0x0169, 0x0301, 0x1E79), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x016A, 0x0308, 0x1E7A),HB_CODEPOINT_ENCODE3_11_7_14 (0x016B, 0x0308, 0x1E7B), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x017F, 0x0307, 0x1E9B),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0300, 0x1EDC), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0301, 0x1EDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0303, 0x1EE0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0309, 0x1EDE),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0323, 0x1EE2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0300, 0x1EDD),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0301, 0x1EDB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0303, 0x1EE1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0309, 0x1EDF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0323, 0x1EE3),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0300, 0x1EEA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0301, 0x1EE8),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0303, 0x1EEE), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0309, 0x1EEC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0323, 0x1EF0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0300, 0x1EEB),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0301, 0x1EE9), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0303, 0x1EEF),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0309, 0x1EED), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0323, 0x1EF1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7, 0x030C, 0x01EE), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x01EA, 0x0304, 0x01EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01EB, 0x0304, 0x01ED), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0226, 0x0304, 0x01E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0227, 0x0304, 0x01E1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0228, 0x0306, 0x1E1C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0229, 0x0306, 0x1E1D), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x022E, 0x0304, 0x0230),HB_CODEPOINT_ENCODE3_11_7_14 (0x022F, 0x0304, 0x0231), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0292, 0x030C, 0x01EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0308, 0x0301, 0x0000), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0300, 0x1FBA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0301, 0x0386), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0304, 0x1FB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0306, 0x1FB8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0313, 0x1F08),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0314, 0x1F09), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0345, 0x1FBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0300, 0x1FC8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0301, 0x0388),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0313, 0x1F18), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0314, 0x1F19),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0300, 0x1FCA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0301, 0x0389),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0313, 0x1F28), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0314, 0x1F29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0345, 0x1FCC), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0300, 0x1FDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0301, 0x038A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0304, 0x1FD9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0306, 0x1FD8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0308, 0x03AA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0313, 0x1F38), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0314, 0x1F39),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0300, 0x1FF8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0301, 0x038C),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0313, 0x1F48), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0314, 0x1F49),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1, 0x0314, 0x1FEC), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0300, 0x1FEA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0301, 0x038E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0304, 0x1FE9),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0306, 0x1FE8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0308, 0x03AB),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0314, 0x1F59), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0300, 0x1FFA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0301, 0x038F), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0313, 0x1F68),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0314, 0x1F69), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0345, 0x1FFC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03AC, 0x0345, 0x1FB4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03AE, 0x0345, 0x1FC4),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0300, 0x1F70), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0301, 0x03AC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0304, 0x1FB1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0306, 0x1FB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0313, 0x1F00), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0314, 0x1F01),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0342, 0x1FB6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0345, 0x1FB3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0300, 0x1F72), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0301, 0x03AD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0313, 0x1F10), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0314, 0x1F11),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0300, 0x1F74), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0301, 0x03AE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0313, 0x1F20), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0314, 0x1F21),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0342, 0x1FC6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0345, 0x1FC3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0300, 0x1F76), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0301, 0x03AF),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0304, 0x1FD1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0306, 0x1FD0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0308, 0x03CA), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0313, 0x1F30),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0314, 0x1F31), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0342, 0x1FD6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0300, 0x1F78), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0301, 0x03CC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0313, 0x1F40), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0314, 0x1F41),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0313, 0x1FE4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0314, 0x1FE5),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0300, 0x1F7A), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0301, 0x03CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0304, 0x1FE1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0306, 0x1FE0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0308, 0x03CB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0313, 0x1F50),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0314, 0x1F51), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0342, 0x1FE6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0300, 0x1F7C), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0301, 0x03CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0313, 0x1F60), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0314, 0x1F61),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0342, 0x1FF6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0345, 0x1FF3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0300, 0x1FD2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0301, 0x0390),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0342, 0x1FD7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0300, 0x1FE2),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0301, 0x03B0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0342, 0x1FE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CE, 0x0345, 0x1FF4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0301, 0x03D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0308, 0x03D4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0406, 0x0308, 0x0407),HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0306, 0x04D0), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0308, 0x04D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0413, 0x0301, 0x0403), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0300, 0x0400),HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0306, 0x04D6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0308, 0x0401),HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0306, 0x04C1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0308, 0x04DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0417, 0x0308, 0x04DE), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0300, 0x040D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0304, 0x04E2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0306, 0x0419),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0308, 0x04E4), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x041A, 0x0301, 0x040C),HB_CODEPOINT_ENCODE3_11_7_14 (0x041E, 0x0308, 0x04E6), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0304, 0x04EE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0306, 0x040E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0308, 0x04F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x030B, 0x04F2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0427, 0x0308, 0x04F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x042B, 0x0308, 0x04F8), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x042D, 0x0308, 0x04EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0306, 0x04D1), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0308, 0x04D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0433, 0x0301, 0x0453), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0300, 0x0450),HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0306, 0x04D7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0308, 0x0451),HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0306, 0x04C2), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0308, 0x04DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0437, 0x0308, 0x04DF), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0300, 0x045D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0304, 0x04E3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0306, 0x0439),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0308, 0x04E5), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x043A, 0x0301, 0x045C),HB_CODEPOINT_ENCODE3_11_7_14 (0x043E, 0x0308, 0x04E7), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0304, 0x04EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0306, 0x045E), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0308, 0x04F1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x030B, 0x04F3), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0447, 0x0308, 0x04F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x044B, 0x0308, 0x04F9), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x044D, 0x0308, 0x04ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0456, 0x0308, 0x0457), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x0474, 0x030F, 0x0476),HB_CODEPOINT_ENCODE3_11_7_14 (0x0475, 0x030F, 0x0477), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8, 0x0308, 0x04DA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9, 0x0308, 0x04DB), ++ HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8, 0x0308, 0x04EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9, 0x0308, 0x04EB), + }; +-static const uint64_t +-_hb_ucd_dm2_u64_map[408] = ++static const uint64_t _hb_ucd_dm2_u64_map[408]= + { +- HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D2u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05D3u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D4u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05B9u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05D6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D8u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05B4u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05DAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DCu, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05DEu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E0u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05E1u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E3u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BFu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05E6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E7u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05E8u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C2u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x05EAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05F2u, 0x05B7u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0627u, 0x0653u, 0x0622u), HB_CODEPOINT_ENCODE3 (0x0627u, 0x0654u, 0x0623u), +- HB_CODEPOINT_ENCODE3 (0x0627u, 0x0655u, 0x0625u), HB_CODEPOINT_ENCODE3 (0x0648u, 0x0654u, 0x0624u), +- HB_CODEPOINT_ENCODE3 (0x064Au, 0x0654u, 0x0626u), HB_CODEPOINT_ENCODE3 (0x06C1u, 0x0654u, 0x06C2u), +- HB_CODEPOINT_ENCODE3 (0x06D2u, 0x0654u, 0x06D3u), HB_CODEPOINT_ENCODE3 (0x06D5u, 0x0654u, 0x06C0u), +- HB_CODEPOINT_ENCODE3 (0x0915u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0916u, 0x093Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0917u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x091Cu, 0x093Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0921u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0922u, 0x093Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0928u, 0x093Cu, 0x0929u), HB_CODEPOINT_ENCODE3 (0x092Bu, 0x093Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x092Fu, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0930u, 0x093Cu, 0x0931u), +- HB_CODEPOINT_ENCODE3 (0x0933u, 0x093Cu, 0x0934u), HB_CODEPOINT_ENCODE3 (0x09A1u, 0x09BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x09A2u, 0x09BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x09AFu, 0x09BCu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09BEu, 0x09CBu), HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09D7u, 0x09CCu), +- HB_CODEPOINT_ENCODE3 (0x0A16u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A17u, 0x0A3Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0A1Cu, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A2Bu, 0x0A3Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0A32u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A38u, 0x0A3Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0B21u, 0x0B3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0B22u, 0x0B3Cu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B3Eu, 0x0B4Bu), HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B56u, 0x0B48u), +- HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B57u, 0x0B4Cu), HB_CODEPOINT_ENCODE3 (0x0B92u, 0x0BD7u, 0x0B94u), +- HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BBEu, 0x0BCAu), HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BD7u, 0x0BCCu), +- HB_CODEPOINT_ENCODE3 (0x0BC7u, 0x0BBEu, 0x0BCBu), HB_CODEPOINT_ENCODE3 (0x0C46u, 0x0C56u, 0x0C48u), +- HB_CODEPOINT_ENCODE3 (0x0CBFu, 0x0CD5u, 0x0CC0u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CC2u, 0x0CCAu), +- HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD5u, 0x0CC7u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD6u, 0x0CC8u), +- HB_CODEPOINT_ENCODE3 (0x0CCAu, 0x0CD5u, 0x0CCBu), HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D3Eu, 0x0D4Au), +- HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D57u, 0x0D4Cu), HB_CODEPOINT_ENCODE3 (0x0D47u, 0x0D3Eu, 0x0D4Bu), +- HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCAu, 0x0DDAu), HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCFu, 0x0DDCu), +- HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DDFu, 0x0DDEu), HB_CODEPOINT_ENCODE3 (0x0DDCu, 0x0DCAu, 0x0DDDu), +- HB_CODEPOINT_ENCODE3 (0x0F40u, 0x0FB5u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F42u, 0x0FB7u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0F4Cu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F51u, 0x0FB7u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0F56u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F5Bu, 0x0FB7u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F72u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F74u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F90u, 0x0FB5u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0F92u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F9Cu, 0x0FB7u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0FA1u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FA6u, 0x0FB7u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0FABu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FB2u, 0x0F80u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x0FB3u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1025u, 0x102Eu, 0x1026u), +- HB_CODEPOINT_ENCODE3 (0x1B05u, 0x1B35u, 0x1B06u), HB_CODEPOINT_ENCODE3 (0x1B07u, 0x1B35u, 0x1B08u), +- HB_CODEPOINT_ENCODE3 (0x1B09u, 0x1B35u, 0x1B0Au), HB_CODEPOINT_ENCODE3 (0x1B0Bu, 0x1B35u, 0x1B0Cu), +- HB_CODEPOINT_ENCODE3 (0x1B0Du, 0x1B35u, 0x1B0Eu), HB_CODEPOINT_ENCODE3 (0x1B11u, 0x1B35u, 0x1B12u), +- HB_CODEPOINT_ENCODE3 (0x1B3Au, 0x1B35u, 0x1B3Bu), HB_CODEPOINT_ENCODE3 (0x1B3Cu, 0x1B35u, 0x1B3Du), +- HB_CODEPOINT_ENCODE3 (0x1B3Eu, 0x1B35u, 0x1B40u), HB_CODEPOINT_ENCODE3 (0x1B3Fu, 0x1B35u, 0x1B41u), +- HB_CODEPOINT_ENCODE3 (0x1B42u, 0x1B35u, 0x1B43u), HB_CODEPOINT_ENCODE3 (0x1E36u, 0x0304u, 0x1E38u), +- HB_CODEPOINT_ENCODE3 (0x1E37u, 0x0304u, 0x1E39u), HB_CODEPOINT_ENCODE3 (0x1E5Au, 0x0304u, 0x1E5Cu), +- HB_CODEPOINT_ENCODE3 (0x1E5Bu, 0x0304u, 0x1E5Du), HB_CODEPOINT_ENCODE3 (0x1E62u, 0x0307u, 0x1E68u), +- HB_CODEPOINT_ENCODE3 (0x1E63u, 0x0307u, 0x1E69u), HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0302u, 0x1EACu), +- HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0306u, 0x1EB6u), HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0302u, 0x1EADu), +- HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0306u, 0x1EB7u), HB_CODEPOINT_ENCODE3 (0x1EB8u, 0x0302u, 0x1EC6u), +- HB_CODEPOINT_ENCODE3 (0x1EB9u, 0x0302u, 0x1EC7u), HB_CODEPOINT_ENCODE3 (0x1ECCu, 0x0302u, 0x1ED8u), +- HB_CODEPOINT_ENCODE3 (0x1ECDu, 0x0302u, 0x1ED9u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0300u, 0x1F02u), +- HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0301u, 0x1F04u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0342u, 0x1F06u), +- HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0345u, 0x1F80u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0300u, 0x1F03u), +- HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0301u, 0x1F05u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0342u, 0x1F07u), +- HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0345u, 0x1F81u), HB_CODEPOINT_ENCODE3 (0x1F02u, 0x0345u, 0x1F82u), +- HB_CODEPOINT_ENCODE3 (0x1F03u, 0x0345u, 0x1F83u), HB_CODEPOINT_ENCODE3 (0x1F04u, 0x0345u, 0x1F84u), +- HB_CODEPOINT_ENCODE3 (0x1F05u, 0x0345u, 0x1F85u), HB_CODEPOINT_ENCODE3 (0x1F06u, 0x0345u, 0x1F86u), +- HB_CODEPOINT_ENCODE3 (0x1F07u, 0x0345u, 0x1F87u), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0300u, 0x1F0Au), +- HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0301u, 0x1F0Cu), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0342u, 0x1F0Eu), +- HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0345u, 0x1F88u), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0300u, 0x1F0Bu), +- HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0301u, 0x1F0Du), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0342u, 0x1F0Fu), +- HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0345u, 0x1F89u), HB_CODEPOINT_ENCODE3 (0x1F0Au, 0x0345u, 0x1F8Au), +- HB_CODEPOINT_ENCODE3 (0x1F0Bu, 0x0345u, 0x1F8Bu), HB_CODEPOINT_ENCODE3 (0x1F0Cu, 0x0345u, 0x1F8Cu), +- HB_CODEPOINT_ENCODE3 (0x1F0Du, 0x0345u, 0x1F8Du), HB_CODEPOINT_ENCODE3 (0x1F0Eu, 0x0345u, 0x1F8Eu), +- HB_CODEPOINT_ENCODE3 (0x1F0Fu, 0x0345u, 0x1F8Fu), HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0300u, 0x1F12u), +- HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0301u, 0x1F14u), HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0300u, 0x1F13u), +- HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0301u, 0x1F15u), HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0300u, 0x1F1Au), +- HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0301u, 0x1F1Cu), HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0300u, 0x1F1Bu), +- HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0301u, 0x1F1Du), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0300u, 0x1F22u), +- HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0301u, 0x1F24u), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0342u, 0x1F26u), +- HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0345u, 0x1F90u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0300u, 0x1F23u), +- HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0301u, 0x1F25u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0342u, 0x1F27u), +- HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0345u, 0x1F91u), HB_CODEPOINT_ENCODE3 (0x1F22u, 0x0345u, 0x1F92u), +- HB_CODEPOINT_ENCODE3 (0x1F23u, 0x0345u, 0x1F93u), HB_CODEPOINT_ENCODE3 (0x1F24u, 0x0345u, 0x1F94u), +- HB_CODEPOINT_ENCODE3 (0x1F25u, 0x0345u, 0x1F95u), HB_CODEPOINT_ENCODE3 (0x1F26u, 0x0345u, 0x1F96u), +- HB_CODEPOINT_ENCODE3 (0x1F27u, 0x0345u, 0x1F97u), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0300u, 0x1F2Au), +- HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0301u, 0x1F2Cu), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0342u, 0x1F2Eu), +- HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0345u, 0x1F98u), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0300u, 0x1F2Bu), +- HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0301u, 0x1F2Du), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0342u, 0x1F2Fu), +- HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0345u, 0x1F99u), HB_CODEPOINT_ENCODE3 (0x1F2Au, 0x0345u, 0x1F9Au), +- HB_CODEPOINT_ENCODE3 (0x1F2Bu, 0x0345u, 0x1F9Bu), HB_CODEPOINT_ENCODE3 (0x1F2Cu, 0x0345u, 0x1F9Cu), +- HB_CODEPOINT_ENCODE3 (0x1F2Du, 0x0345u, 0x1F9Du), HB_CODEPOINT_ENCODE3 (0x1F2Eu, 0x0345u, 0x1F9Eu), +- HB_CODEPOINT_ENCODE3 (0x1F2Fu, 0x0345u, 0x1F9Fu), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0300u, 0x1F32u), +- HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0301u, 0x1F34u), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0342u, 0x1F36u), +- HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0300u, 0x1F33u), HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0301u, 0x1F35u), +- HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0342u, 0x1F37u), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0300u, 0x1F3Au), +- HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0301u, 0x1F3Cu), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0342u, 0x1F3Eu), +- HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0300u, 0x1F3Bu), HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0301u, 0x1F3Du), +- HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0342u, 0x1F3Fu), HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0300u, 0x1F42u), +- HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0301u, 0x1F44u), HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0300u, 0x1F43u), +- HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0301u, 0x1F45u), HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0300u, 0x1F4Au), +- HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0301u, 0x1F4Cu), HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0300u, 0x1F4Bu), +- HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0301u, 0x1F4Du), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0300u, 0x1F52u), +- HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0301u, 0x1F54u), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0342u, 0x1F56u), +- HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0300u, 0x1F53u), HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0301u, 0x1F55u), +- HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0342u, 0x1F57u), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0300u, 0x1F5Bu), +- HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0301u, 0x1F5Du), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0342u, 0x1F5Fu), +- HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0300u, 0x1F62u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0301u, 0x1F64u), +- HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0342u, 0x1F66u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0345u, 0x1FA0u), +- HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0300u, 0x1F63u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0301u, 0x1F65u), +- HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0342u, 0x1F67u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0345u, 0x1FA1u), +- HB_CODEPOINT_ENCODE3 (0x1F62u, 0x0345u, 0x1FA2u), HB_CODEPOINT_ENCODE3 (0x1F63u, 0x0345u, 0x1FA3u), +- HB_CODEPOINT_ENCODE3 (0x1F64u, 0x0345u, 0x1FA4u), HB_CODEPOINT_ENCODE3 (0x1F65u, 0x0345u, 0x1FA5u), +- HB_CODEPOINT_ENCODE3 (0x1F66u, 0x0345u, 0x1FA6u), HB_CODEPOINT_ENCODE3 (0x1F67u, 0x0345u, 0x1FA7u), +- HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0300u, 0x1F6Au), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0301u, 0x1F6Cu), +- HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0342u, 0x1F6Eu), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0345u, 0x1FA8u), +- HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0300u, 0x1F6Bu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0301u, 0x1F6Du), +- HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0342u, 0x1F6Fu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0345u, 0x1FA9u), +- HB_CODEPOINT_ENCODE3 (0x1F6Au, 0x0345u, 0x1FAAu), HB_CODEPOINT_ENCODE3 (0x1F6Bu, 0x0345u, 0x1FABu), +- HB_CODEPOINT_ENCODE3 (0x1F6Cu, 0x0345u, 0x1FACu), HB_CODEPOINT_ENCODE3 (0x1F6Du, 0x0345u, 0x1FADu), +- HB_CODEPOINT_ENCODE3 (0x1F6Eu, 0x0345u, 0x1FAEu), HB_CODEPOINT_ENCODE3 (0x1F6Fu, 0x0345u, 0x1FAFu), +- HB_CODEPOINT_ENCODE3 (0x1F70u, 0x0345u, 0x1FB2u), HB_CODEPOINT_ENCODE3 (0x1F74u, 0x0345u, 0x1FC2u), +- HB_CODEPOINT_ENCODE3 (0x1F7Cu, 0x0345u, 0x1FF2u), HB_CODEPOINT_ENCODE3 (0x1FB6u, 0x0345u, 0x1FB7u), +- HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0300u, 0x1FCDu), HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0301u, 0x1FCEu), +- HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0342u, 0x1FCFu), HB_CODEPOINT_ENCODE3 (0x1FC6u, 0x0345u, 0x1FC7u), +- HB_CODEPOINT_ENCODE3 (0x1FF6u, 0x0345u, 0x1FF7u), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0300u, 0x1FDDu), +- HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0301u, 0x1FDEu), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0342u, 0x1FDFu), +- HB_CODEPOINT_ENCODE3 (0x2190u, 0x0338u, 0x219Au), HB_CODEPOINT_ENCODE3 (0x2192u, 0x0338u, 0x219Bu), +- HB_CODEPOINT_ENCODE3 (0x2194u, 0x0338u, 0x21AEu), HB_CODEPOINT_ENCODE3 (0x21D0u, 0x0338u, 0x21CDu), +- HB_CODEPOINT_ENCODE3 (0x21D2u, 0x0338u, 0x21CFu), HB_CODEPOINT_ENCODE3 (0x21D4u, 0x0338u, 0x21CEu), +- HB_CODEPOINT_ENCODE3 (0x2203u, 0x0338u, 0x2204u), HB_CODEPOINT_ENCODE3 (0x2208u, 0x0338u, 0x2209u), +- HB_CODEPOINT_ENCODE3 (0x220Bu, 0x0338u, 0x220Cu), HB_CODEPOINT_ENCODE3 (0x2223u, 0x0338u, 0x2224u), +- HB_CODEPOINT_ENCODE3 (0x2225u, 0x0338u, 0x2226u), HB_CODEPOINT_ENCODE3 (0x223Cu, 0x0338u, 0x2241u), +- HB_CODEPOINT_ENCODE3 (0x2243u, 0x0338u, 0x2244u), HB_CODEPOINT_ENCODE3 (0x2245u, 0x0338u, 0x2247u), +- HB_CODEPOINT_ENCODE3 (0x2248u, 0x0338u, 0x2249u), HB_CODEPOINT_ENCODE3 (0x224Du, 0x0338u, 0x226Du), +- HB_CODEPOINT_ENCODE3 (0x2261u, 0x0338u, 0x2262u), HB_CODEPOINT_ENCODE3 (0x2264u, 0x0338u, 0x2270u), +- HB_CODEPOINT_ENCODE3 (0x2265u, 0x0338u, 0x2271u), HB_CODEPOINT_ENCODE3 (0x2272u, 0x0338u, 0x2274u), +- HB_CODEPOINT_ENCODE3 (0x2273u, 0x0338u, 0x2275u), HB_CODEPOINT_ENCODE3 (0x2276u, 0x0338u, 0x2278u), +- HB_CODEPOINT_ENCODE3 (0x2277u, 0x0338u, 0x2279u), HB_CODEPOINT_ENCODE3 (0x227Au, 0x0338u, 0x2280u), +- HB_CODEPOINT_ENCODE3 (0x227Bu, 0x0338u, 0x2281u), HB_CODEPOINT_ENCODE3 (0x227Cu, 0x0338u, 0x22E0u), +- HB_CODEPOINT_ENCODE3 (0x227Du, 0x0338u, 0x22E1u), HB_CODEPOINT_ENCODE3 (0x2282u, 0x0338u, 0x2284u), +- HB_CODEPOINT_ENCODE3 (0x2283u, 0x0338u, 0x2285u), HB_CODEPOINT_ENCODE3 (0x2286u, 0x0338u, 0x2288u), +- HB_CODEPOINT_ENCODE3 (0x2287u, 0x0338u, 0x2289u), HB_CODEPOINT_ENCODE3 (0x2291u, 0x0338u, 0x22E2u), +- HB_CODEPOINT_ENCODE3 (0x2292u, 0x0338u, 0x22E3u), HB_CODEPOINT_ENCODE3 (0x22A2u, 0x0338u, 0x22ACu), +- HB_CODEPOINT_ENCODE3 (0x22A8u, 0x0338u, 0x22ADu), HB_CODEPOINT_ENCODE3 (0x22A9u, 0x0338u, 0x22AEu), +- HB_CODEPOINT_ENCODE3 (0x22ABu, 0x0338u, 0x22AFu), HB_CODEPOINT_ENCODE3 (0x22B2u, 0x0338u, 0x22EAu), +- HB_CODEPOINT_ENCODE3 (0x22B3u, 0x0338u, 0x22EBu), HB_CODEPOINT_ENCODE3 (0x22B4u, 0x0338u, 0x22ECu), +- HB_CODEPOINT_ENCODE3 (0x22B5u, 0x0338u, 0x22EDu), HB_CODEPOINT_ENCODE3 (0x2ADDu, 0x0338u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x3046u, 0x3099u, 0x3094u), HB_CODEPOINT_ENCODE3 (0x304Bu, 0x3099u, 0x304Cu), +- HB_CODEPOINT_ENCODE3 (0x304Du, 0x3099u, 0x304Eu), HB_CODEPOINT_ENCODE3 (0x304Fu, 0x3099u, 0x3050u), +- HB_CODEPOINT_ENCODE3 (0x3051u, 0x3099u, 0x3052u), HB_CODEPOINT_ENCODE3 (0x3053u, 0x3099u, 0x3054u), +- HB_CODEPOINT_ENCODE3 (0x3055u, 0x3099u, 0x3056u), HB_CODEPOINT_ENCODE3 (0x3057u, 0x3099u, 0x3058u), +- HB_CODEPOINT_ENCODE3 (0x3059u, 0x3099u, 0x305Au), HB_CODEPOINT_ENCODE3 (0x305Bu, 0x3099u, 0x305Cu), +- HB_CODEPOINT_ENCODE3 (0x305Du, 0x3099u, 0x305Eu), HB_CODEPOINT_ENCODE3 (0x305Fu, 0x3099u, 0x3060u), +- HB_CODEPOINT_ENCODE3 (0x3061u, 0x3099u, 0x3062u), HB_CODEPOINT_ENCODE3 (0x3064u, 0x3099u, 0x3065u), +- HB_CODEPOINT_ENCODE3 (0x3066u, 0x3099u, 0x3067u), HB_CODEPOINT_ENCODE3 (0x3068u, 0x3099u, 0x3069u), +- HB_CODEPOINT_ENCODE3 (0x306Fu, 0x3099u, 0x3070u), HB_CODEPOINT_ENCODE3 (0x306Fu, 0x309Au, 0x3071u), +- HB_CODEPOINT_ENCODE3 (0x3072u, 0x3099u, 0x3073u), HB_CODEPOINT_ENCODE3 (0x3072u, 0x309Au, 0x3074u), +- HB_CODEPOINT_ENCODE3 (0x3075u, 0x3099u, 0x3076u), HB_CODEPOINT_ENCODE3 (0x3075u, 0x309Au, 0x3077u), +- HB_CODEPOINT_ENCODE3 (0x3078u, 0x3099u, 0x3079u), HB_CODEPOINT_ENCODE3 (0x3078u, 0x309Au, 0x307Au), +- HB_CODEPOINT_ENCODE3 (0x307Bu, 0x3099u, 0x307Cu), HB_CODEPOINT_ENCODE3 (0x307Bu, 0x309Au, 0x307Du), +- HB_CODEPOINT_ENCODE3 (0x309Du, 0x3099u, 0x309Eu), HB_CODEPOINT_ENCODE3 (0x30A6u, 0x3099u, 0x30F4u), +- HB_CODEPOINT_ENCODE3 (0x30ABu, 0x3099u, 0x30ACu), HB_CODEPOINT_ENCODE3 (0x30ADu, 0x3099u, 0x30AEu), +- HB_CODEPOINT_ENCODE3 (0x30AFu, 0x3099u, 0x30B0u), HB_CODEPOINT_ENCODE3 (0x30B1u, 0x3099u, 0x30B2u), +- HB_CODEPOINT_ENCODE3 (0x30B3u, 0x3099u, 0x30B4u), HB_CODEPOINT_ENCODE3 (0x30B5u, 0x3099u, 0x30B6u), +- HB_CODEPOINT_ENCODE3 (0x30B7u, 0x3099u, 0x30B8u), HB_CODEPOINT_ENCODE3 (0x30B9u, 0x3099u, 0x30BAu), +- HB_CODEPOINT_ENCODE3 (0x30BBu, 0x3099u, 0x30BCu), HB_CODEPOINT_ENCODE3 (0x30BDu, 0x3099u, 0x30BEu), +- HB_CODEPOINT_ENCODE3 (0x30BFu, 0x3099u, 0x30C0u), HB_CODEPOINT_ENCODE3 (0x30C1u, 0x3099u, 0x30C2u), +- HB_CODEPOINT_ENCODE3 (0x30C4u, 0x3099u, 0x30C5u), HB_CODEPOINT_ENCODE3 (0x30C6u, 0x3099u, 0x30C7u), +- HB_CODEPOINT_ENCODE3 (0x30C8u, 0x3099u, 0x30C9u), HB_CODEPOINT_ENCODE3 (0x30CFu, 0x3099u, 0x30D0u), +- HB_CODEPOINT_ENCODE3 (0x30CFu, 0x309Au, 0x30D1u), HB_CODEPOINT_ENCODE3 (0x30D2u, 0x3099u, 0x30D3u), +- HB_CODEPOINT_ENCODE3 (0x30D2u, 0x309Au, 0x30D4u), HB_CODEPOINT_ENCODE3 (0x30D5u, 0x3099u, 0x30D6u), +- HB_CODEPOINT_ENCODE3 (0x30D5u, 0x309Au, 0x30D7u), HB_CODEPOINT_ENCODE3 (0x30D8u, 0x3099u, 0x30D9u), +- HB_CODEPOINT_ENCODE3 (0x30D8u, 0x309Au, 0x30DAu), HB_CODEPOINT_ENCODE3 (0x30DBu, 0x3099u, 0x30DCu), +- HB_CODEPOINT_ENCODE3 (0x30DBu, 0x309Au, 0x30DDu), HB_CODEPOINT_ENCODE3 (0x30EFu, 0x3099u, 0x30F7u), +- HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u), HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u), +- HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu), HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu), +- HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x105D2u, 0x0307u, 0x105C9u), HB_CODEPOINT_ENCODE3 (0x105DAu, 0x0307u, 0x105E4u), +- HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu), +- HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu), +- HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu), +- HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x11382u, 0x113C9u, 0x11383u), +- HB_CODEPOINT_ENCODE3 (0x11384u, 0x113BBu, 0x11385u),HB_CODEPOINT_ENCODE3 (0x1138Bu, 0x113C2u, 0x1138Eu), +- HB_CODEPOINT_ENCODE3 (0x11390u, 0x113C9u, 0x11391u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113B8u, 0x113C7u), +- HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C2u, 0x113C5u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C9u, 0x113C8u), +- HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu), +- HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu), +- HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), +- HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Eu, 0x16121u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Fu, 0x16123u), +- HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16120u, 0x16125u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16129u, 0x16122u), +- HB_CODEPOINT_ENCODE3 (0x16121u, 0x1611Fu, 0x16126u),HB_CODEPOINT_ENCODE3 (0x16121u, 0x16120u, 0x16128u), +- HB_CODEPOINT_ENCODE3 (0x16122u, 0x1611Fu, 0x16127u),HB_CODEPOINT_ENCODE3 (0x16129u, 0x1611Fu, 0x16124u), +- HB_CODEPOINT_ENCODE3 (0x16D63u, 0x16D67u, 0x16D69u),HB_CODEPOINT_ENCODE3 (0x16D67u, 0x16D67u, 0x16D68u), +- HB_CODEPOINT_ENCODE3 (0x16D69u, 0x16D67u, 0x16D6Au), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), +- HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u), ++ HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B7, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B8, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05D0, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D2, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05D3, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D4, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05D5, 0x05B9, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D5, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05D6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D8, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05D9, 0x05B4, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D9, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05DA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DC, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05DE, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E0, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05E1, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E3, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BF, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05E6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E7, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05E8, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C2, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x05EA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05F2, 0x05B7, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0627, 0x0653, 0x0622), HB_CODEPOINT_ENCODE3 (0x0627, 0x0654, 0x0623), ++ HB_CODEPOINT_ENCODE3 (0x0627, 0x0655, 0x0625), HB_CODEPOINT_ENCODE3 (0x0648, 0x0654, 0x0624), ++ HB_CODEPOINT_ENCODE3 (0x064A, 0x0654, 0x0626), HB_CODEPOINT_ENCODE3 (0x06C1, 0x0654, 0x06C2), ++ HB_CODEPOINT_ENCODE3 (0x06D2, 0x0654, 0x06D3), HB_CODEPOINT_ENCODE3 (0x06D5, 0x0654, 0x06C0), ++ HB_CODEPOINT_ENCODE3 (0x0915, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0916, 0x093C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0917, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x091C, 0x093C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0921, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0922, 0x093C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0928, 0x093C, 0x0929), HB_CODEPOINT_ENCODE3 (0x092B, 0x093C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x092F, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0930, 0x093C, 0x0931), ++ HB_CODEPOINT_ENCODE3 (0x0933, 0x093C, 0x0934), HB_CODEPOINT_ENCODE3 (0x09A1, 0x09BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x09A2, 0x09BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x09AF, 0x09BC, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x09C7, 0x09BE, 0x09CB), HB_CODEPOINT_ENCODE3 (0x09C7, 0x09D7, 0x09CC), ++ HB_CODEPOINT_ENCODE3 (0x0A16, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A17, 0x0A3C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0A1C, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A2B, 0x0A3C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0A32, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A38, 0x0A3C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0B21, 0x0B3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0B22, 0x0B3C, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B3E, 0x0B4B), HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B56, 0x0B48), ++ HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B57, 0x0B4C), HB_CODEPOINT_ENCODE3 (0x0B92, 0x0BD7, 0x0B94), ++ HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BBE, 0x0BCA), HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BD7, 0x0BCC), ++ HB_CODEPOINT_ENCODE3 (0x0BC7, 0x0BBE, 0x0BCB), HB_CODEPOINT_ENCODE3 (0x0C46, 0x0C56, 0x0C48), ++ HB_CODEPOINT_ENCODE3 (0x0CBF, 0x0CD5, 0x0CC0), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CC2, 0x0CCA), ++ HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD5, 0x0CC7), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD6, 0x0CC8), ++ HB_CODEPOINT_ENCODE3 (0x0CCA, 0x0CD5, 0x0CCB), HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D3E, 0x0D4A), ++ HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D57, 0x0D4C), HB_CODEPOINT_ENCODE3 (0x0D47, 0x0D3E, 0x0D4B), ++ HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCA, 0x0DDA), HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCF, 0x0DDC), ++ HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DDF, 0x0DDE), HB_CODEPOINT_ENCODE3 (0x0DDC, 0x0DCA, 0x0DDD), ++ HB_CODEPOINT_ENCODE3 (0x0F40, 0x0FB5, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F42, 0x0FB7, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0F4C, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F51, 0x0FB7, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0F56, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F5B, 0x0FB7, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F72, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F74, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F90, 0x0FB5, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0F92, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F9C, 0x0FB7, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0FA1, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FA6, 0x0FB7, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0FAB, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FB2, 0x0F80, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x0FB3, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x1025, 0x102E, 0x1026), ++ HB_CODEPOINT_ENCODE3 (0x1B05, 0x1B35, 0x1B06), HB_CODEPOINT_ENCODE3 (0x1B07, 0x1B35, 0x1B08), ++ HB_CODEPOINT_ENCODE3 (0x1B09, 0x1B35, 0x1B0A), HB_CODEPOINT_ENCODE3 (0x1B0B, 0x1B35, 0x1B0C), ++ HB_CODEPOINT_ENCODE3 (0x1B0D, 0x1B35, 0x1B0E), HB_CODEPOINT_ENCODE3 (0x1B11, 0x1B35, 0x1B12), ++ HB_CODEPOINT_ENCODE3 (0x1B3A, 0x1B35, 0x1B3B), HB_CODEPOINT_ENCODE3 (0x1B3C, 0x1B35, 0x1B3D), ++ HB_CODEPOINT_ENCODE3 (0x1B3E, 0x1B35, 0x1B40), HB_CODEPOINT_ENCODE3 (0x1B3F, 0x1B35, 0x1B41), ++ HB_CODEPOINT_ENCODE3 (0x1B42, 0x1B35, 0x1B43), HB_CODEPOINT_ENCODE3 (0x1E36, 0x0304, 0x1E38), ++ HB_CODEPOINT_ENCODE3 (0x1E37, 0x0304, 0x1E39), HB_CODEPOINT_ENCODE3 (0x1E5A, 0x0304, 0x1E5C), ++ HB_CODEPOINT_ENCODE3 (0x1E5B, 0x0304, 0x1E5D), HB_CODEPOINT_ENCODE3 (0x1E62, 0x0307, 0x1E68), ++ HB_CODEPOINT_ENCODE3 (0x1E63, 0x0307, 0x1E69), HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0302, 0x1EAC), ++ HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0306, 0x1EB6), HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0302, 0x1EAD), ++ HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0306, 0x1EB7), HB_CODEPOINT_ENCODE3 (0x1EB8, 0x0302, 0x1EC6), ++ HB_CODEPOINT_ENCODE3 (0x1EB9, 0x0302, 0x1EC7), HB_CODEPOINT_ENCODE3 (0x1ECC, 0x0302, 0x1ED8), ++ HB_CODEPOINT_ENCODE3 (0x1ECD, 0x0302, 0x1ED9), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0300, 0x1F02), ++ HB_CODEPOINT_ENCODE3 (0x1F00, 0x0301, 0x1F04), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0342, 0x1F06), ++ HB_CODEPOINT_ENCODE3 (0x1F00, 0x0345, 0x1F80), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0300, 0x1F03), ++ HB_CODEPOINT_ENCODE3 (0x1F01, 0x0301, 0x1F05), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0342, 0x1F07), ++ HB_CODEPOINT_ENCODE3 (0x1F01, 0x0345, 0x1F81), HB_CODEPOINT_ENCODE3 (0x1F02, 0x0345, 0x1F82), ++ HB_CODEPOINT_ENCODE3 (0x1F03, 0x0345, 0x1F83), HB_CODEPOINT_ENCODE3 (0x1F04, 0x0345, 0x1F84), ++ HB_CODEPOINT_ENCODE3 (0x1F05, 0x0345, 0x1F85), HB_CODEPOINT_ENCODE3 (0x1F06, 0x0345, 0x1F86), ++ HB_CODEPOINT_ENCODE3 (0x1F07, 0x0345, 0x1F87), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0300, 0x1F0A), ++ HB_CODEPOINT_ENCODE3 (0x1F08, 0x0301, 0x1F0C), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0342, 0x1F0E), ++ HB_CODEPOINT_ENCODE3 (0x1F08, 0x0345, 0x1F88), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0300, 0x1F0B), ++ HB_CODEPOINT_ENCODE3 (0x1F09, 0x0301, 0x1F0D), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0342, 0x1F0F), ++ HB_CODEPOINT_ENCODE3 (0x1F09, 0x0345, 0x1F89), HB_CODEPOINT_ENCODE3 (0x1F0A, 0x0345, 0x1F8A), ++ HB_CODEPOINT_ENCODE3 (0x1F0B, 0x0345, 0x1F8B), HB_CODEPOINT_ENCODE3 (0x1F0C, 0x0345, 0x1F8C), ++ HB_CODEPOINT_ENCODE3 (0x1F0D, 0x0345, 0x1F8D), HB_CODEPOINT_ENCODE3 (0x1F0E, 0x0345, 0x1F8E), ++ HB_CODEPOINT_ENCODE3 (0x1F0F, 0x0345, 0x1F8F), HB_CODEPOINT_ENCODE3 (0x1F10, 0x0300, 0x1F12), ++ HB_CODEPOINT_ENCODE3 (0x1F10, 0x0301, 0x1F14), HB_CODEPOINT_ENCODE3 (0x1F11, 0x0300, 0x1F13), ++ HB_CODEPOINT_ENCODE3 (0x1F11, 0x0301, 0x1F15), HB_CODEPOINT_ENCODE3 (0x1F18, 0x0300, 0x1F1A), ++ HB_CODEPOINT_ENCODE3 (0x1F18, 0x0301, 0x1F1C), HB_CODEPOINT_ENCODE3 (0x1F19, 0x0300, 0x1F1B), ++ HB_CODEPOINT_ENCODE3 (0x1F19, 0x0301, 0x1F1D), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0300, 0x1F22), ++ HB_CODEPOINT_ENCODE3 (0x1F20, 0x0301, 0x1F24), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0342, 0x1F26), ++ HB_CODEPOINT_ENCODE3 (0x1F20, 0x0345, 0x1F90), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0300, 0x1F23), ++ HB_CODEPOINT_ENCODE3 (0x1F21, 0x0301, 0x1F25), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0342, 0x1F27), ++ HB_CODEPOINT_ENCODE3 (0x1F21, 0x0345, 0x1F91), HB_CODEPOINT_ENCODE3 (0x1F22, 0x0345, 0x1F92), ++ HB_CODEPOINT_ENCODE3 (0x1F23, 0x0345, 0x1F93), HB_CODEPOINT_ENCODE3 (0x1F24, 0x0345, 0x1F94), ++ HB_CODEPOINT_ENCODE3 (0x1F25, 0x0345, 0x1F95), HB_CODEPOINT_ENCODE3 (0x1F26, 0x0345, 0x1F96), ++ HB_CODEPOINT_ENCODE3 (0x1F27, 0x0345, 0x1F97), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0300, 0x1F2A), ++ HB_CODEPOINT_ENCODE3 (0x1F28, 0x0301, 0x1F2C), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0342, 0x1F2E), ++ HB_CODEPOINT_ENCODE3 (0x1F28, 0x0345, 0x1F98), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0300, 0x1F2B), ++ HB_CODEPOINT_ENCODE3 (0x1F29, 0x0301, 0x1F2D), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0342, 0x1F2F), ++ HB_CODEPOINT_ENCODE3 (0x1F29, 0x0345, 0x1F99), HB_CODEPOINT_ENCODE3 (0x1F2A, 0x0345, 0x1F9A), ++ HB_CODEPOINT_ENCODE3 (0x1F2B, 0x0345, 0x1F9B), HB_CODEPOINT_ENCODE3 (0x1F2C, 0x0345, 0x1F9C), ++ HB_CODEPOINT_ENCODE3 (0x1F2D, 0x0345, 0x1F9D), HB_CODEPOINT_ENCODE3 (0x1F2E, 0x0345, 0x1F9E), ++ HB_CODEPOINT_ENCODE3 (0x1F2F, 0x0345, 0x1F9F), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0300, 0x1F32), ++ HB_CODEPOINT_ENCODE3 (0x1F30, 0x0301, 0x1F34), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0342, 0x1F36), ++ HB_CODEPOINT_ENCODE3 (0x1F31, 0x0300, 0x1F33), HB_CODEPOINT_ENCODE3 (0x1F31, 0x0301, 0x1F35), ++ HB_CODEPOINT_ENCODE3 (0x1F31, 0x0342, 0x1F37), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0300, 0x1F3A), ++ HB_CODEPOINT_ENCODE3 (0x1F38, 0x0301, 0x1F3C), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0342, 0x1F3E), ++ HB_CODEPOINT_ENCODE3 (0x1F39, 0x0300, 0x1F3B), HB_CODEPOINT_ENCODE3 (0x1F39, 0x0301, 0x1F3D), ++ HB_CODEPOINT_ENCODE3 (0x1F39, 0x0342, 0x1F3F), HB_CODEPOINT_ENCODE3 (0x1F40, 0x0300, 0x1F42), ++ HB_CODEPOINT_ENCODE3 (0x1F40, 0x0301, 0x1F44), HB_CODEPOINT_ENCODE3 (0x1F41, 0x0300, 0x1F43), ++ HB_CODEPOINT_ENCODE3 (0x1F41, 0x0301, 0x1F45), HB_CODEPOINT_ENCODE3 (0x1F48, 0x0300, 0x1F4A), ++ HB_CODEPOINT_ENCODE3 (0x1F48, 0x0301, 0x1F4C), HB_CODEPOINT_ENCODE3 (0x1F49, 0x0300, 0x1F4B), ++ HB_CODEPOINT_ENCODE3 (0x1F49, 0x0301, 0x1F4D), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0300, 0x1F52), ++ HB_CODEPOINT_ENCODE3 (0x1F50, 0x0301, 0x1F54), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0342, 0x1F56), ++ HB_CODEPOINT_ENCODE3 (0x1F51, 0x0300, 0x1F53), HB_CODEPOINT_ENCODE3 (0x1F51, 0x0301, 0x1F55), ++ HB_CODEPOINT_ENCODE3 (0x1F51, 0x0342, 0x1F57), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0300, 0x1F5B), ++ HB_CODEPOINT_ENCODE3 (0x1F59, 0x0301, 0x1F5D), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0342, 0x1F5F), ++ HB_CODEPOINT_ENCODE3 (0x1F60, 0x0300, 0x1F62), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0301, 0x1F64), ++ HB_CODEPOINT_ENCODE3 (0x1F60, 0x0342, 0x1F66), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0345, 0x1FA0), ++ HB_CODEPOINT_ENCODE3 (0x1F61, 0x0300, 0x1F63), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0301, 0x1F65), ++ HB_CODEPOINT_ENCODE3 (0x1F61, 0x0342, 0x1F67), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0345, 0x1FA1), ++ HB_CODEPOINT_ENCODE3 (0x1F62, 0x0345, 0x1FA2), HB_CODEPOINT_ENCODE3 (0x1F63, 0x0345, 0x1FA3), ++ HB_CODEPOINT_ENCODE3 (0x1F64, 0x0345, 0x1FA4), HB_CODEPOINT_ENCODE3 (0x1F65, 0x0345, 0x1FA5), ++ HB_CODEPOINT_ENCODE3 (0x1F66, 0x0345, 0x1FA6), HB_CODEPOINT_ENCODE3 (0x1F67, 0x0345, 0x1FA7), ++ HB_CODEPOINT_ENCODE3 (0x1F68, 0x0300, 0x1F6A), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0301, 0x1F6C), ++ HB_CODEPOINT_ENCODE3 (0x1F68, 0x0342, 0x1F6E), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0345, 0x1FA8), ++ HB_CODEPOINT_ENCODE3 (0x1F69, 0x0300, 0x1F6B), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0301, 0x1F6D), ++ HB_CODEPOINT_ENCODE3 (0x1F69, 0x0342, 0x1F6F), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0345, 0x1FA9), ++ HB_CODEPOINT_ENCODE3 (0x1F6A, 0x0345, 0x1FAA), HB_CODEPOINT_ENCODE3 (0x1F6B, 0x0345, 0x1FAB), ++ HB_CODEPOINT_ENCODE3 (0x1F6C, 0x0345, 0x1FAC), HB_CODEPOINT_ENCODE3 (0x1F6D, 0x0345, 0x1FAD), ++ HB_CODEPOINT_ENCODE3 (0x1F6E, 0x0345, 0x1FAE), HB_CODEPOINT_ENCODE3 (0x1F6F, 0x0345, 0x1FAF), ++ HB_CODEPOINT_ENCODE3 (0x1F70, 0x0345, 0x1FB2), HB_CODEPOINT_ENCODE3 (0x1F74, 0x0345, 0x1FC2), ++ HB_CODEPOINT_ENCODE3 (0x1F7C, 0x0345, 0x1FF2), HB_CODEPOINT_ENCODE3 (0x1FB6, 0x0345, 0x1FB7), ++ HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0300, 0x1FCD), HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0301, 0x1FCE), ++ HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0342, 0x1FCF), HB_CODEPOINT_ENCODE3 (0x1FC6, 0x0345, 0x1FC7), ++ HB_CODEPOINT_ENCODE3 (0x1FF6, 0x0345, 0x1FF7), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0300, 0x1FDD), ++ HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0301, 0x1FDE), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0342, 0x1FDF), ++ HB_CODEPOINT_ENCODE3 (0x2190, 0x0338, 0x219A), HB_CODEPOINT_ENCODE3 (0x2192, 0x0338, 0x219B), ++ HB_CODEPOINT_ENCODE3 (0x2194, 0x0338, 0x21AE), HB_CODEPOINT_ENCODE3 (0x21D0, 0x0338, 0x21CD), ++ HB_CODEPOINT_ENCODE3 (0x21D2, 0x0338, 0x21CF), HB_CODEPOINT_ENCODE3 (0x21D4, 0x0338, 0x21CE), ++ HB_CODEPOINT_ENCODE3 (0x2203, 0x0338, 0x2204), HB_CODEPOINT_ENCODE3 (0x2208, 0x0338, 0x2209), ++ HB_CODEPOINT_ENCODE3 (0x220B, 0x0338, 0x220C), HB_CODEPOINT_ENCODE3 (0x2223, 0x0338, 0x2224), ++ HB_CODEPOINT_ENCODE3 (0x2225, 0x0338, 0x2226), HB_CODEPOINT_ENCODE3 (0x223C, 0x0338, 0x2241), ++ HB_CODEPOINT_ENCODE3 (0x2243, 0x0338, 0x2244), HB_CODEPOINT_ENCODE3 (0x2245, 0x0338, 0x2247), ++ HB_CODEPOINT_ENCODE3 (0x2248, 0x0338, 0x2249), HB_CODEPOINT_ENCODE3 (0x224D, 0x0338, 0x226D), ++ HB_CODEPOINT_ENCODE3 (0x2261, 0x0338, 0x2262), HB_CODEPOINT_ENCODE3 (0x2264, 0x0338, 0x2270), ++ HB_CODEPOINT_ENCODE3 (0x2265, 0x0338, 0x2271), HB_CODEPOINT_ENCODE3 (0x2272, 0x0338, 0x2274), ++ HB_CODEPOINT_ENCODE3 (0x2273, 0x0338, 0x2275), HB_CODEPOINT_ENCODE3 (0x2276, 0x0338, 0x2278), ++ HB_CODEPOINT_ENCODE3 (0x2277, 0x0338, 0x2279), HB_CODEPOINT_ENCODE3 (0x227A, 0x0338, 0x2280), ++ HB_CODEPOINT_ENCODE3 (0x227B, 0x0338, 0x2281), HB_CODEPOINT_ENCODE3 (0x227C, 0x0338, 0x22E0), ++ HB_CODEPOINT_ENCODE3 (0x227D, 0x0338, 0x22E1), HB_CODEPOINT_ENCODE3 (0x2282, 0x0338, 0x2284), ++ HB_CODEPOINT_ENCODE3 (0x2283, 0x0338, 0x2285), HB_CODEPOINT_ENCODE3 (0x2286, 0x0338, 0x2288), ++ HB_CODEPOINT_ENCODE3 (0x2287, 0x0338, 0x2289), HB_CODEPOINT_ENCODE3 (0x2291, 0x0338, 0x22E2), ++ HB_CODEPOINT_ENCODE3 (0x2292, 0x0338, 0x22E3), HB_CODEPOINT_ENCODE3 (0x22A2, 0x0338, 0x22AC), ++ HB_CODEPOINT_ENCODE3 (0x22A8, 0x0338, 0x22AD), HB_CODEPOINT_ENCODE3 (0x22A9, 0x0338, 0x22AE), ++ HB_CODEPOINT_ENCODE3 (0x22AB, 0x0338, 0x22AF), HB_CODEPOINT_ENCODE3 (0x22B2, 0x0338, 0x22EA), ++ HB_CODEPOINT_ENCODE3 (0x22B3, 0x0338, 0x22EB), HB_CODEPOINT_ENCODE3 (0x22B4, 0x0338, 0x22EC), ++ HB_CODEPOINT_ENCODE3 (0x22B5, 0x0338, 0x22ED), HB_CODEPOINT_ENCODE3 (0x2ADD, 0x0338, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x3046, 0x3099, 0x3094), HB_CODEPOINT_ENCODE3 (0x304B, 0x3099, 0x304C), ++ HB_CODEPOINT_ENCODE3 (0x304D, 0x3099, 0x304E), HB_CODEPOINT_ENCODE3 (0x304F, 0x3099, 0x3050), ++ HB_CODEPOINT_ENCODE3 (0x3051, 0x3099, 0x3052), HB_CODEPOINT_ENCODE3 (0x3053, 0x3099, 0x3054), ++ HB_CODEPOINT_ENCODE3 (0x3055, 0x3099, 0x3056), HB_CODEPOINT_ENCODE3 (0x3057, 0x3099, 0x3058), ++ HB_CODEPOINT_ENCODE3 (0x3059, 0x3099, 0x305A), HB_CODEPOINT_ENCODE3 (0x305B, 0x3099, 0x305C), ++ HB_CODEPOINT_ENCODE3 (0x305D, 0x3099, 0x305E), HB_CODEPOINT_ENCODE3 (0x305F, 0x3099, 0x3060), ++ HB_CODEPOINT_ENCODE3 (0x3061, 0x3099, 0x3062), HB_CODEPOINT_ENCODE3 (0x3064, 0x3099, 0x3065), ++ HB_CODEPOINT_ENCODE3 (0x3066, 0x3099, 0x3067), HB_CODEPOINT_ENCODE3 (0x3068, 0x3099, 0x3069), ++ HB_CODEPOINT_ENCODE3 (0x306F, 0x3099, 0x3070), HB_CODEPOINT_ENCODE3 (0x306F, 0x309A, 0x3071), ++ HB_CODEPOINT_ENCODE3 (0x3072, 0x3099, 0x3073), HB_CODEPOINT_ENCODE3 (0x3072, 0x309A, 0x3074), ++ HB_CODEPOINT_ENCODE3 (0x3075, 0x3099, 0x3076), HB_CODEPOINT_ENCODE3 (0x3075, 0x309A, 0x3077), ++ HB_CODEPOINT_ENCODE3 (0x3078, 0x3099, 0x3079), HB_CODEPOINT_ENCODE3 (0x3078, 0x309A, 0x307A), ++ HB_CODEPOINT_ENCODE3 (0x307B, 0x3099, 0x307C), HB_CODEPOINT_ENCODE3 (0x307B, 0x309A, 0x307D), ++ HB_CODEPOINT_ENCODE3 (0x309D, 0x3099, 0x309E), HB_CODEPOINT_ENCODE3 (0x30A6, 0x3099, 0x30F4), ++ HB_CODEPOINT_ENCODE3 (0x30AB, 0x3099, 0x30AC), HB_CODEPOINT_ENCODE3 (0x30AD, 0x3099, 0x30AE), ++ HB_CODEPOINT_ENCODE3 (0x30AF, 0x3099, 0x30B0), HB_CODEPOINT_ENCODE3 (0x30B1, 0x3099, 0x30B2), ++ HB_CODEPOINT_ENCODE3 (0x30B3, 0x3099, 0x30B4), HB_CODEPOINT_ENCODE3 (0x30B5, 0x3099, 0x30B6), ++ HB_CODEPOINT_ENCODE3 (0x30B7, 0x3099, 0x30B8), HB_CODEPOINT_ENCODE3 (0x30B9, 0x3099, 0x30BA), ++ HB_CODEPOINT_ENCODE3 (0x30BB, 0x3099, 0x30BC), HB_CODEPOINT_ENCODE3 (0x30BD, 0x3099, 0x30BE), ++ HB_CODEPOINT_ENCODE3 (0x30BF, 0x3099, 0x30C0), HB_CODEPOINT_ENCODE3 (0x30C1, 0x3099, 0x30C2), ++ HB_CODEPOINT_ENCODE3 (0x30C4, 0x3099, 0x30C5), HB_CODEPOINT_ENCODE3 (0x30C6, 0x3099, 0x30C7), ++ HB_CODEPOINT_ENCODE3 (0x30C8, 0x3099, 0x30C9), HB_CODEPOINT_ENCODE3 (0x30CF, 0x3099, 0x30D0), ++ HB_CODEPOINT_ENCODE3 (0x30CF, 0x309A, 0x30D1), HB_CODEPOINT_ENCODE3 (0x30D2, 0x3099, 0x30D3), ++ HB_CODEPOINT_ENCODE3 (0x30D2, 0x309A, 0x30D4), HB_CODEPOINT_ENCODE3 (0x30D5, 0x3099, 0x30D6), ++ HB_CODEPOINT_ENCODE3 (0x30D5, 0x309A, 0x30D7), HB_CODEPOINT_ENCODE3 (0x30D8, 0x3099, 0x30D9), ++ HB_CODEPOINT_ENCODE3 (0x30D8, 0x309A, 0x30DA), HB_CODEPOINT_ENCODE3 (0x30DB, 0x3099, 0x30DC), ++ HB_CODEPOINT_ENCODE3 (0x30DB, 0x309A, 0x30DD), HB_CODEPOINT_ENCODE3 (0x30EF, 0x3099, 0x30F7), ++ HB_CODEPOINT_ENCODE3 (0x30F0, 0x3099, 0x30F8), HB_CODEPOINT_ENCODE3 (0x30F1, 0x3099, 0x30F9), ++ HB_CODEPOINT_ENCODE3 (0x30F2, 0x3099, 0x30FA), HB_CODEPOINT_ENCODE3 (0x30FD, 0x3099, 0x30FE), ++ HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C2, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x105D2, 0x0307, 0x105C9), HB_CODEPOINT_ENCODE3 (0x105DA, 0x0307, 0x105E4), ++ HB_CODEPOINT_ENCODE3 (0x11099, 0x110BA, 0x1109A),HB_CODEPOINT_ENCODE3 (0x1109B, 0x110BA, 0x1109C), ++ HB_CODEPOINT_ENCODE3 (0x110A5, 0x110BA, 0x110AB),HB_CODEPOINT_ENCODE3 (0x11131, 0x11127, 0x1112E), ++ HB_CODEPOINT_ENCODE3 (0x11132, 0x11127, 0x1112F),HB_CODEPOINT_ENCODE3 (0x11347, 0x1133E, 0x1134B), ++ HB_CODEPOINT_ENCODE3 (0x11347, 0x11357, 0x1134C),HB_CODEPOINT_ENCODE3 (0x11382, 0x113C9, 0x11383), ++ HB_CODEPOINT_ENCODE3 (0x11384, 0x113BB, 0x11385),HB_CODEPOINT_ENCODE3 (0x1138B, 0x113C2, 0x1138E), ++ HB_CODEPOINT_ENCODE3 (0x11390, 0x113C9, 0x11391),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113B8, 0x113C7), ++ HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C2, 0x113C5),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C9, 0x113C8), ++ HB_CODEPOINT_ENCODE3 (0x114B9, 0x114B0, 0x114BC),HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BA, 0x114BB), ++ HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BD, 0x114BE),HB_CODEPOINT_ENCODE3 (0x115B8, 0x115AF, 0x115BA), ++ HB_CODEPOINT_ENCODE3 (0x115B9, 0x115AF, 0x115BB),HB_CODEPOINT_ENCODE3 (0x11935, 0x11930, 0x11938), ++ HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611E, 0x16121),HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611F, 0x16123), ++ HB_CODEPOINT_ENCODE3 (0x1611E, 0x16120, 0x16125),HB_CODEPOINT_ENCODE3 (0x1611E, 0x16129, 0x16122), ++ HB_CODEPOINT_ENCODE3 (0x16121, 0x1611F, 0x16126),HB_CODEPOINT_ENCODE3 (0x16121, 0x16120, 0x16128), ++ HB_CODEPOINT_ENCODE3 (0x16122, 0x1611F, 0x16127),HB_CODEPOINT_ENCODE3 (0x16129, 0x1611F, 0x16124), ++ HB_CODEPOINT_ENCODE3 (0x16D63, 0x16D67, 0x16D69),HB_CODEPOINT_ENCODE3 (0x16D67, 0x16D67, 0x16D68), ++ HB_CODEPOINT_ENCODE3 (0x16D69, 0x16D67, 0x16D6A), HB_CODEPOINT_ENCODE3 (0x1D157, 0x1D165, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x1D158, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16E, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16F, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D170, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D171, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D172, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x1D1B9, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BA, 0x1D165, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16F, 0x0000), ++ HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16F, 0x0000), + }; + + #ifndef HB_OPTIMIZE_SIZE + +-static const uint8_t +-_hb_ucd_u8[17612] = ++#include ++ ++static const uint8_t _hb_ucd_u8[19868]= + { +- 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, 26, 26, 26, 67, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 68, 69, 70, 58, 58, 58, 58, 71, 58, ++ 58, 58, 58, 58, 58, 58, 72, 73, 74, 75, 76, 77, 78, 79, 58, 80, ++ 81, 82, 83, 84, 85, 58, 86, 87, 88, 89, 78, 90, 91, 92, 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, 93, 26, 26, 26, 26, 26, 26, 26, 26, 94, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 95, 26, 26, 26, 26, 26, 26, 26, 26, ++ 26, 26, 26, 26, 26, 96, 26, 97, 58, 58, 58, 58, 26, 98, 58, 58, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 99, 26, 26, 26, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,100, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 101, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, ++ 58, 58, 58, 58, 58, 58, 58, 58, 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,102, ++ 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,103, + 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, +@@ -1148,496 +914,529 @@ _hb_ucd_u8[17612] = + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, +- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, +- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, +- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, +- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, +- 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, +- 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, +- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, +- 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, +- 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, +- 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, +- 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, +- 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, +- 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, +- 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, +- 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, +- 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, +- 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, +- 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, +- 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, +- 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, +- 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, +- 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, +- 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, +- 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, +- 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, +- 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, +- 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, +- 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, +- 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, +- 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, +- 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, +- 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, +- 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, +- 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, +- 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, +- 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, +- 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, +- 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, +- 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, +- 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, +- 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, +- 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, +- 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, +- 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, +- 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, +- 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, +- 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, +- 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, +- 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, +- 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, +- 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, +- 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, +- 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, +- 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, +- 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, +- 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, +- 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, +- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, +- 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, +- 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, +- 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, +- 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, +- 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, +- 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, +- 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, +- 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, +- 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, +- 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, +- 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, +- 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, +- 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, +- 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, +- 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, +- 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, +- 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, +- 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, +- 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, +- 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, +- 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, +- 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, +- 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, +- 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, +- 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, +- 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, +- 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, +- 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, +- 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, +- 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, +- 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, +- 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, +- 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, +- 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, +- 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, +- 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, +- 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, +- 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, +- 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, +- 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, +- 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, +- 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, +- 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, +- 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, +- 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, +- 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, +- 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, +- 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, +- 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, +- 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, +- 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, +- 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, +- 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, +- 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, +- 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, +- 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, +- 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, +- 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, +- 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, +- 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, +- 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, +- 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, +- 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, +- 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, +- 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, +- 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, +- 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, +- 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, +- 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, +- 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, +- 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, +- 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, +- 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, +- 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, +- 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, +- 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, +- 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, +- 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, +- 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, +- 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, +- 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, +- 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, +- 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, +- 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, +- 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, +- 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, +- 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, +- 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, +- 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, +- 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, +- 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, +- 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, +- 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, +- 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, +- 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, +- 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, +- 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, ++ 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, ++ 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, ++ 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, ++ 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 43, 44, 16, 10, ++ 43, 43, 40, 45, 11, 46, 46, 11, 34, 11, 11, 11, 11, 11, 11, 11, ++ 11, 47, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, ++ 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 48, 34, 32, 34, 11, ++ 32, 49, 42, 42, 50, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, ++ 47, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 46, 51, 2, 2, 2, ++ 16, 16, 16, 16, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, ++ 42, 42, 42, 42, 42, 42, 42, 57, 58, 59, 42, 58, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 61, ++ 36, 62, 63, 43, 43, 43, 43, 43, 64, 64, 64, 8, 9, 65, 2, 66, ++ 42, 42, 42, 42, 42, 59, 67, 2, 68, 36, 36, 36, 36, 69, 42, 42, ++ 7, 7, 7, 7, 7, 2, 2, 36, 70, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 71, 42, 42, 42, 72, 49, 42, 42, 73, 74, 75, 42, 42, 36, ++ 7, 7, 7, 7, 7, 36, 76, 77, 2, 2, 2, 2, 2, 2, 2, 78, ++ 69, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 79, 61, 36, ++ 36, 36, 36, 42, 42, 42, 42, 42, 70, 43, 43, 43, 43, 43, 43, 43, ++ 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, ++ 42, 42, 39, 21, 2, 80, 56, 20, 36, 36, 36, 42, 42, 74, 42, 42, ++ 42, 42, 74, 42, 74, 42, 42, 43, 2, 2, 2, 2, 2, 2, 2, 63, ++ 36, 36, 36, 36, 69, 42, 43, 63, 36, 36, 36, 36, 36, 60, 43, 43, ++ 36, 36, 36, 36, 81, 36, 36, 36, 64, 43, 43, 56, 42, 42, 42, 42, ++ 36, 36, 36, 36, 82, 42, 42, 42, 42, 83, 42, 42, 42, 42, 42, 42, ++ 42, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 70, 85, ++ 86, 42, 42, 42, 84, 85, 86, 85, 69, 42, 42, 42, 36, 36, 36, 36, ++ 36, 42, 2, 7, 7, 7, 7, 7, 87, 36, 36, 36, 36, 36, 36, 36, ++ 69, 85, 61, 36, 36, 36, 60, 61, 60, 61, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 60, 36, 36, 36, 60, 60, 43, 36, 36, 43, 70, 85, ++ 86, 42, 79, 88, 89, 88, 86, 60, 43, 43, 43, 88, 43, 43, 36, 61, ++ 36, 42, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 55, 62, 79, ++ 56, 84, 61, 36, 36, 60, 43, 61, 60, 36, 61, 60, 36, 43, 79, 85, ++ 86, 79, 43, 56, 79, 56, 42, 43, 56, 43, 43, 43, 61, 36, 60, 60, ++ 43, 43, 43, 7, 7, 7, 7, 7, 42, 36, 69, 63, 43, 43, 43, 43, ++ 56, 84, 61, 36, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, ++ 60, 36, 61, 36, 36, 43, 70, 85, 86, 42, 42, 56, 84, 88, 86, 43, ++ 60, 43, 43, 43, 43, 43, 43, 43, 65, 43, 43, 43, 61, 42, 42, 42, ++ 56, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 43, 70, 86, ++ 86, 42, 79, 88, 89, 88, 86, 43, 43, 43, 56, 84, 43, 43, 36, 61, ++ 77, 27, 27, 27, 43, 43, 43, 43, 43, 70, 61, 36, 36, 60, 43, 36, ++ 60, 36, 36, 43, 61, 60, 60, 36, 43, 61, 60, 43, 36, 60, 43, 36, ++ 36, 36, 36, 36, 36, 43, 43, 85, 84, 89, 43, 85, 89, 85, 86, 43, ++ 60, 43, 43, 88, 43, 43, 43, 43, 27, 90, 66, 66, 55, 91, 43, 43, ++ 84, 85, 70, 36, 36, 36, 60, 36, 60, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 43, 70, 42, 84, 85, 89, 42, 79, 42, 42, 43, ++ 43, 43, 56, 79, 36, 60, 36, 43, 43, 43, 43, 92, 27, 27, 27, 90, ++ 69, 85, 71, 36, 36, 36, 60, 36, 36, 36, 61, 36, 36, 43, 70, 86, ++ 85, 85, 89, 84, 89, 85, 42, 43, 43, 43, 88, 89, 43, 43, 36, 60, ++ 61, 93, 43, 43, 43, 43, 43, 43, 42, 85, 36, 36, 36, 36, 60, 36, ++ 36, 36, 36, 36, 36, 69, 70, 85, 86, 42, 79, 85, 89, 85, 86, 76, ++ 43, 43, 36, 93, 27, 27, 27, 94, 27, 27, 27, 27, 90, 36, 36, 36, ++ 56, 85, 61, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 36, 36, 36, ++ 36, 61, 36, 36, 36, 36, 61, 43, 36, 36, 36, 60, 43, 79, 43, 88, ++ 85, 42, 79, 79, 85, 85, 85, 85, 43, 85, 63, 43, 43, 43, 43, 43, ++ 61, 36, 36, 36, 36, 36, 36, 36, 69, 36, 42, 42, 42, 79, 43, 95, ++ 36, 36, 36, 74, 42, 42, 42, 59, 7, 7, 7, 7, 7, 2, 43, 43, ++ 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 60, 36, 36, 60, 36, 36, ++ 36, 36, 61, 61, 36, 36, 36, 36, 69, 36, 42, 42, 42, 42, 70, 43, ++ 36, 36, 60, 80, 42, 42, 42, 79, 7, 7, 7, 7, 7, 43, 36, 36, ++ 76, 66, 2, 2, 2, 2, 2, 2, 2, 96, 96, 66, 42, 66, 66, 66, ++ 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 49, 49, 49, 4, 4, 85, ++ 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, ++ 56, 42, 42, 42, 42, 42, 42, 84, 42, 42, 59, 42, 36, 36, 69, 42, ++ 42, 42, 42, 42, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79, 66, ++ 66, 66, 66, 75, 66, 66, 91, 66, 2, 2, 96, 66, 21, 63, 43, 43, ++ 36, 36, 36, 36, 36, 93, 86, 42, 84, 42, 42, 42, 86, 84, 86, 70, ++ 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 85, 42, 36, 36, 42, ++ 70, 85, 97, 93, 85, 85, 85, 36, 69, 42, 70, 36, 36, 36, 36, 36, ++ 36, 84, 86, 84, 85, 85, 86, 93, 7, 7, 7, 7, 7, 85, 86, 66, ++ 11, 11, 11, 47, 43, 43, 47, 43, 16, 16, 16, 16, 16, 52, 44, 16, ++ 36, 36, 36, 36, 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, ++ 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, 36, 36, 36, 36, ++ 36, 36, 36, 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 56, 42, ++ 2, 2, 2, 2, 98, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, ++ 66, 66, 66, 66, 66, 43, 43, 43, 11, 11, 11, 43, 16, 16, 16, 43, ++ 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 71, ++ 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,102,103, 43, ++ 36, 36, 36, 36, 36, 62, 2,104,105, 36, 36, 36, 60, 43, 43, 43, ++ 36, 42, 84, 43, 43, 43, 43, 61, 36, 42,106, 63, 43, 43, 43, 43, ++ 36, 42, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 60, 36, ++ 60, 42, 43, 43, 43, 43, 43, 43, 36, 36, 42, 86, 42, 42, 42, 85, ++ 85, 85, 85, 84, 86, 42, 42, 42, 42, 42, 2, 87, 2, 65, 69, 43, ++ 7, 7, 7, 7, 7, 43, 43, 43, 27, 27, 27, 27, 27, 43, 43, 43, ++ 2, 2, 2,107, 2, 58, 42, 83, 36, 82, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 60, 43, 43, 43, 36, 36, 69, 70, 36, 36, 36, 36, ++ 36, 36, 36, 36, 69, 60, 43, 43, 36, 36, 36, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 60, 42, 84, 85, 86, 84, 85, 43, 43, ++ 85, 84, 85, 85, 86, 42, 43, 43, 91, 43, 2, 7, 7, 7, 7, 7, ++ 36, 36, 36, 36, 36, 36, 36, 43, 36, 36, 60, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 43, 43, 36, 36, 36, 36, 36, 43, 43, 43, ++ 7, 7, 7, 7, 7, 99, 43, 66, 66, 66, 66, 66, 66, 66, 66, 66, ++ 36, 36, 36, 69, 84, 86, 43, 2, 36, 36, 93, 84, 42, 42, 42, 79, ++ 84, 84, 86, 42, 42, 42, 84, 85, 85, 86, 42, 42, 42, 42, 79, 56, ++ 2, 2, 2, 87, 2, 2, 2, 43, 42, 42, 42, 42, 42, 42, 42,108, ++ 42, 42, 42, 42, 42, 42, 42, 43, 42, 42, 42, 42, 42, 42, 43, 43, ++ 42, 42, 97, 36, 36, 36, 36, 36, 36, 36, 84, 42, 42, 84, 84, 85, ++ 85, 84, 97, 36, 36, 36, 60, 2, 96, 66, 66, 66, 66, 49, 42, 42, ++ 42, 42, 66, 66, 66, 66, 21, 2, 42, 97, 36, 36, 36, 36, 36, 36, ++ 93, 42, 42, 85, 42, 86, 42, 36, 36, 36, 36, 84, 42, 85, 86, 86, ++ 42, 85, 43, 43, 43, 43, 2, 2, 36, 36, 85, 85, 85, 85, 42, 42, ++ 42, 42, 85, 42, 43, 92, 2, 2, 7, 7, 7, 7, 7, 43, 61, 36, ++ 36, 36, 36, 36, 39, 39, 39, 2, 16, 16, 16, 16, 34,109, 43, 43, ++ 11, 11, 11, 11, 11, 46, 47, 11, 2, 2, 2, 2, 43, 43, 43, 43, ++ 42, 59, 42, 42, 42, 42, 42, 42, 84, 42, 42, 42, 70, 36, 69, 36, ++ 36, 36, 70, 93, 42, 60, 43, 43, 16, 16, 16, 16, 16, 16, 39, 39, ++ 39, 39, 39, 39, 39, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, ++ 16, 16, 16, 16, 16,110, 39, 39, 32, 32, 32, 16, 16, 16, 16, 32, ++ 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 43, 11, 11, 11, 43, ++ 16, 16, 16, 16, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 16, 43, ++ 16, 16, 16, 16,111,111,111,111, 16, 16,109, 16, 11, 11,112,113, ++ 40, 16,109, 16, 11, 11,112, 40, 16, 16, 43, 16, 11, 11,114, 40, ++ 16, 16, 16, 16, 11, 11,115, 40, 43, 16,109, 16, 11, 11,112,116, ++ 117,117,117,117,117,118, 64, 64,119,119,119, 2,120,121,120,121, ++ 2, 2, 2, 2,122, 64, 64,123, 2, 2, 2, 2,124,125, 2,126, ++ 127, 2,128,129, 2, 2, 2, 2, 2, 9,127, 2, 2, 2, 2,130, ++ 64, 64,131, 64, 64, 64, 64, 64,132, 43, 27, 27, 27, 8,128,133, ++ 27, 27, 27, 27, 27, 8,128,103, 39, 39, 39, 39, 39, 39, 80, 43, ++ 20, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43, 43, ++ 42, 42, 42, 42, 42, 42,134, 50,108, 50,108, 42, 42, 42, 42, 42, ++ 79, 43, 43, 43, 43, 43, 43, 43, 66,135, 66,136, 66, 34, 11, 16, ++ 11, 32,136, 66, 48, 11, 11, 66, 66, 66,135,135,135, 11, 11,137, ++ 11, 11, 35, 36,138, 66, 16, 11, 8, 8, 48, 16, 16, 26, 66,139, ++ 27, 27, 27, 27, 27, 27, 27, 27,104,104,104,104,104,104,104,104, ++ 104,140,141,104,142, 66, 43, 43, 8, 8,143, 66, 66, 8, 66, 66, ++ 143, 26, 66,143, 66, 66, 66,143, 66, 66, 66, 66, 66, 66, 66, 8, ++ 66,143,143, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, 66, 66, 66, 66, 4, 4, 66, 66, ++ 8, 66, 66, 66,144,145, 66, 66, 66, 66, 66, 66, 66, 66,143, 66, ++ 66, 66, 66, 66, 66, 26, 8, 8, 8, 8, 66, 66, 66, 66, 66, 66, ++ 66, 66, 66, 66, 66, 66, 8, 8, 8, 66, 66, 66, 66, 66, 66, 66, ++ 66, 66, 66, 66, 66, 91, 43, 43, 27, 27, 27, 27, 27, 27, 66, 66, ++ 66, 66, 66, 66, 66, 27, 27, 27, 66, 66, 66, 26, 66, 66, 66, 66, ++ 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, ++ 66, 66, 66, 66, 66, 66, 66, 26, 66, 66, 66, 66, 4, 4, 4, 4, ++ 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, ++ 8, 8,128,146, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, ++ 8,128,147,147,147,147,147,147,147,147,147,147,146, 8, 8, 8, ++ 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, ++ 8, 8,143, 26, 8, 8,143, 66, 66, 66, 43, 66, 66, 66, 66, 66, ++ 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 39, 11, ++ 32, 32,139, 66, 66,136, 34,148, 42, 32, 43, 43, 92, 2, 98, 2, ++ 16, 16, 16,149, 43, 43,149, 43, 36, 36, 36, 36, 43, 43, 43, 51, ++ 63, 43, 43, 43, 43, 43, 43, 56, 36, 36, 36, 60, 43, 43, 43, 43, ++ 36, 36, 36, 60, 36, 36, 36, 60, 2,120,120, 2,124,125,120, 2, ++ 2, 2, 2, 6, 2,107,120, 2,120, 4, 4, 4, 4, 2, 2, 87, ++ 2, 2, 2, 2, 2,119, 2, 2,107,150, 2, 2, 2, 2, 2, 2, ++ 66, 2,151,147,147,147,152, 43, 66, 66, 66, 66, 66, 54, 66, 66, ++ 66, 66, 43, 43, 43, 43, 43, 43, 66, 66, 66, 43, 43, 43, 43, 43, ++ 1, 2,153,154, 4, 4, 4, 4, 4, 66, 4, 4, 4, 4,155,156, ++ 157,104,104,104,104, 42, 42, 85,158, 39, 39, 66,104,159, 62, 66, ++ 36, 36, 36, 60, 56,160,161, 68, 36, 36, 36, 36, 36, 62, 39, 68, ++ 43, 43, 61, 36, 36, 36, 36, 36, 66, 27, 27, 66, 66, 66, 66, 66, ++ 66, 66, 66, 43, 43, 43, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, ++ 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, ++ 162, 27, 27, 27, 27, 27, 27, 27, 36, 36, 82, 36, 36, 36, 36, 36, ++ 66, 66, 66, 91, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 2, ++ 7, 7, 7, 7, 7, 36, 43, 43, 32, 32, 32, 32, 32, 32, 32, 69, ++ 50,164, 42, 42, 42, 42, 42, 87, 32, 32, 32, 32, 32, 32, 39, 42, ++ 36, 36, 36,104,104,104,104,104, 42, 2, 2, 2, 43, 43, 43, 43, ++ 40, 40, 40,161, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, ++ 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, ++ 32, 32, 32, 32, 41,165, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, +- 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, +- 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, +- 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, +- 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, +- 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, +- 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, +- 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, +- 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, +- 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, +- 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, +- 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, +- 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, +- 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, +- 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, +- 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, +- 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, +- 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, +- 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, +- 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, +- 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, +- 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, +- 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, +- 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, +- 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, +- 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, +- 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, +- 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, +- 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, +- 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, +- 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, +- 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, +- 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, +- 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, +- 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, +- 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, +- 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, +- 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, +- 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, +- 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, +- 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, +- 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, +- 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, +- 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, +- 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, +- 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, +- 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, +- 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, +- 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, +- 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, +- 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, +- 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, +- 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, +- 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, +- 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, +- 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, +- 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, +- 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, +- 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, +- 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, +- 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, +- 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, +- 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, +- 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, +- 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, +- 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, +- 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, +- 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, +- 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, +- 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, +- 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, +- 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, +- 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, +- 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, +- 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, +- 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, +- 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, +- 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, +- 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, +- 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, +- 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, +- 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, +- 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, +- 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, +- 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, +- 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, +- 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, +- 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, +- 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, +- 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, +- 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, +- 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, +- 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, +- 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, +- 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, +- 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, +- 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, +- 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, +- 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, +- 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, +- 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, +- 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, +- 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, +- 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, +- 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, +- 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, +- 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, +- 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, +- 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, +- 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, +- 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, +- 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, +- 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, +- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, +- 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, +- 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, +- 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, +- 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, +- 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, +- 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, +- 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, +- 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, +- 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, +- 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, +- 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, +- 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, +- 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, +- 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, +- 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, +- 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, +- 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, +- 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, +- 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, +- 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, +- 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, +- 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, +- 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, +- 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, +- 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, +- 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, +- 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, +- 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, +- 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, +- 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, +- 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, +- 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, +- 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, +- 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, +- 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, +- 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, +- 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, +- 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, +- 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, +- 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, +- 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, +- 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, +- 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, +- 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, +- 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, +- 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, +- 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, +- 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, +- 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, +- 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, +- 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, +- 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, +- 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, +- 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, +- 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, +- 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, +- 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, +- 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, +- 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, +- 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, +- 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, +- 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, +- 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, +- 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, +- 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, +- 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, +- 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, +- 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, +- 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, +- 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, +- 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +- 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, ++ 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 46, 43, ++ 51, 39,166, 35, 39, 35, 36, 36, 36, 70, 36, 70, 36, 69, 36, 36, ++ 36, 93, 86, 84, 66, 66, 79, 43, 27, 27, 27, 66,167, 43, 43, 43, ++ 36, 36, 2, 2, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 85, 85, 85, 85, 85, 85, 85, 85, 42, 43, 43, 43, 43, 2, ++ 42, 36, 36, 36, 2, 71, 71, 69, 36, 36, 36, 42, 42, 42, 42, 2, ++ 36, 36, 36, 69, 42, 42, 42, 42, 42, 85, 43, 43, 43, 43, 43, 92, ++ 36, 69, 85, 42, 42, 85, 42, 85,106, 2, 2, 2, 2, 2, 2, 51, ++ 7, 7, 7, 7, 7, 43, 43, 2, 36, 36, 69, 68, 36, 36, 36, 36, ++ 7, 7, 7, 7, 7, 36, 36, 60, 36, 36, 36, 36, 69, 42, 42, 84, ++ 86, 84, 86, 79, 43, 43, 43, 43, 36, 69, 36, 36, 36, 36, 84, 43, ++ 7, 7, 7, 7, 7, 43, 2, 2, 68, 36, 36, 76, 66, 93, 84, 36, ++ 70, 42, 70, 69, 70, 36, 36, 42, 69, 60, 43, 43, 43, 43, 43, 43, ++ 43, 43, 43, 43, 43, 61, 82, 2, 36, 36, 36, 36, 36, 93, 42, 85, ++ 2, 82,168, 79, 43, 43, 43, 43, 61, 36, 36, 60, 61, 36, 36, 60, ++ 61, 36, 36, 60, 43, 43, 43, 43, 16, 16, 16, 16, 16,113, 39, 39, ++ 16, 16, 16, 16,110, 40, 43, 43, 36, 93, 86, 85, 84,106, 86, 43, ++ 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 43, 61, 36, 36, ++ 169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170, ++ 16, 16, 16,109, 43, 43, 43, 43, 43,149, 16, 16, 43, 43, 61, 70, ++ 36, 36, 36, 36,171, 36, 36, 36, 36, 36, 36, 60, 36, 36, 60, 60, ++ 36, 61, 60, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, ++ 40, 22, 66, 66, 66, 66, 66, 66, 66, 77, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 36,147, 66, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 66, 66, 66, 66, 36, 36, 36, 36, 36, 36,167, 66, ++ 2, 2, 2,151,129, 43, 43, 43, 6,172,173,147,147,147,147,147, ++ 147,147,129,151,129, 2,126,174, 2, 63, 2, 2,155,147,147,129, ++ 2,175, 8,176, 65, 2, 43, 43, 36, 36, 60, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 60, 78, 92, 2, 3, 2, 4, 5, 6, 2, ++ 16, 16, 16, 16, 16, 17, 18,128,129, 4, 2, 36, 36, 36, 36, 36, ++ 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, ++ 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 60, 43, ++ 20,177, 55,178, 26, 8,143, 91, 43, 43, 43, 43, 78, 64, 66, 43, ++ 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 60, 36, 61, ++ 2, 63, 43,179, 27, 27, 27, 27, 27, 27, 43, 54, 66, 66, 66, 66, ++ 104,104,142, 27, 90, 66, 66, 66, 66, 66, 66, 66, 66, 27, 66, 91, ++ 66, 66, 66, 66, 66, 66, 91, 43, 91, 43, 43, 43, 43, 43, 43, 43, ++ 66, 66, 66, 66, 66, 66, 49, 43,180, 27, 27, 27, 27, 27, 27, 27, ++ 27, 27, 27, 27, 27, 27, 43, 43, 27, 27, 43, 43, 43, 43, 61, 36, ++ 154, 36, 36, 36, 36,181, 43, 43, 36, 36, 36, 42, 42, 79, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 92, 36, 36, 43, 43, 36, 36, 36, 36, ++ 182,104,104, 43, 43, 43, 43, 43, 11, 11, 11, 11, 16, 16, 16, 16, ++ 11, 11, 43, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 43, 43, ++ 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, 43, 92, ++ 11, 11, 11, 11, 11, 46, 11, 11, 11, 46, 11,149, 16, 16, 16, 16, ++ 16,149, 16, 16, 16, 16, 16, 16, 16,149, 16, 16, 16,149,109, 43, ++ 39, 39, 39, 51, 39, 39, 39, 39, 80, 39, 39, 39, 39, 80, 43, 43, ++ 36, 36, 36, 43, 60, 36, 36, 36, 36, 36, 36, 61, 60, 43, 60, 61, ++ 36, 36, 36, 92, 27, 27, 27, 27, 36, 36, 36, 76,162, 27, 27, 27, ++ 43, 43, 43,179, 27, 27, 27, 27, 36, 60, 36, 43, 43,179, 27, 27, ++ 36, 36, 36, 27, 27, 27, 43, 92, 36, 36, 36, 36, 36, 43, 43, 92, ++ 36, 36, 36, 36, 43, 43, 27, 36, 43, 27, 27, 27, 27, 27, 27, 27, ++ 69, 42, 56, 79, 43, 43, 42, 42, 36, 36, 61, 36, 61, 36, 36, 36, ++ 36, 36, 36, 43, 42, 79, 43, 56, 27, 27, 27, 27, 99, 43, 43, 43, ++ 2, 2, 2, 2, 63, 43, 43, 43, 36, 36, 36, 36, 36, 36,183, 30, ++ 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 77, 36, 36, 36, ++ 36, 36, 69, 79, 43,179, 27, 27, 2, 2, 2, 63, 43, 43, 43, 43, ++ 36, 36, 36, 43, 92, 2, 2, 2, 36, 36, 36, 43, 27, 27, 27, 27, ++ 36, 60, 43, 43, 27, 27, 27, 27, 36, 43, 43, 43, 92, 2, 63, 43, ++ 43, 43, 43, 43,179, 27, 27, 27, 11, 46, 43, 43, 43, 43, 43, 43, ++ 16,109, 43, 43, 43, 27, 27, 27, 36, 36, 42, 42, 43, 43, 43, 43, ++ 7, 7, 7, 7, 7, 36, 36, 68, 11, 11, 11, 43, 56, 42, 42,158, ++ 16, 16, 16, 43, 43, 43, 43, 8, 27, 27, 27, 27, 27, 27, 27, 99, ++ 36, 36, 36, 36, 36, 56,184, 43, 36, 43, 43, 43, 43, 43, 43, 43, ++ 43, 36, 82, 36, 43, 43, 43, 43, 96, 66, 66, 66, 91, 43, 43, 43, ++ 43, 43, 43, 43, 43, 42, 42, 42, 27, 27, 27, 94, 43, 43, 43, 43, ++ 180, 27, 30, 2, 2, 43, 43, 43, 36, 42, 42, 2, 2, 43, 43, 43, ++ 36, 36,183, 27, 27, 27, 43, 43, 86, 97, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 42, 59, 2, 2, 2, 43, ++ 27, 27, 27, 7, 7, 7, 7, 7, 70, 69, 70, 43, 43, 43, 43, 56, ++ 85, 86, 42, 84, 86, 59,185, 2, 2, 79, 43, 43, 43, 43, 78, 43, ++ 42, 70, 36, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, 86, 42, ++ 42, 42, 79, 7, 7, 7, 7, 7, 2, 2, 93, 97, 43, 43, 43, 43, ++ 36, 69, 2, 60, 43, 43, 43, 43, 36, 93, 85, 42, 42, 42, 42, 84, ++ 97, 36, 62, 2, 58, 42, 59, 86, 7, 7, 7, 7, 7, 62, 62, 2, ++ 179, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 85, 86, 42, 85, 84, 42, 2, 2, 2, 70, ++ 69, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 60, 36, 36, 61, ++ 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 62, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 69, 85, 86, 42, 42, 42, 79, 43, 43, ++ 42, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 56, 70, 85, ++ 84, 85, 89, 88, 89, 88, 85, 43, 60, 43, 43, 88, 43, 43, 61, 36, ++ 36, 85, 43, 42, 42, 42, 79, 43, 42, 42, 79, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 61, 43, 60, 36, 36, 36, 61, 85, 86, 42, 42, ++ 79, 89, 88, 88, 85, 89, 85, 84, 70, 70, 2, 92, 63, 43, 43, 43, ++ 56, 79, 43, 43, 43, 43, 43, 43, 36, 36, 93, 85, 42, 42, 42, 42, ++ 85, 42, 84, 70, 36, 62, 2, 2, 7, 7, 7, 7, 7, 2, 92, 70, ++ 85, 86, 42, 42, 84, 84, 85, 86, 84, 42, 36, 71, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 93, 85, 42, 42, 43, 85, 85, 42, 86, ++ 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 43, ++ 85, 86, 42, 42, 42, 84, 86, 86, 59, 2, 60, 43, 43, 43, 43, 43, ++ 2, 2, 2, 2, 2, 2, 63, 43, 36, 36, 36, 36, 36, 69, 86, 85, ++ 42, 42, 42, 86, 62, 43, 43, 43, 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 56, 86, ++ 85, 42, 42, 86, 42, 42, 43, 43, 7, 7, 7, 7, 7, 27, 2, 96, ++ 42, 42, 42, 42, 86, 59, 43, 43, 27, 99, 43, 43, 43, 43, 43, 61, ++ 36, 36, 36, 60, 61, 43, 36, 36, 36, 36, 61, 60, 36, 36, 36, 36, ++ 85, 85, 85, 88, 89, 56, 84, 70, 97, 86, 2, 63, 43, 43, 43, 43, ++ 36, 36, 36, 36, 43, 36, 36, 36, 93, 85, 42, 42, 43, 42, 85, 85, ++ 70, 71, 89, 43, 43, 43, 43, 43, 69, 42, 42, 42, 42, 70, 36, 36, ++ 36, 69, 42, 42, 84, 69, 42, 59, 2, 2, 2, 58, 43, 43, 43, 43, ++ 69, 42, 42, 84, 86, 42, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, ++ 42, 42, 42, 84, 42, 2, 71, 2, 2, 63, 43, 43, 43, 43, 43, 43, ++ 2, 2, 2, 2, 2, 43, 43, 43, 84, 42, 84, 84, 43, 43, 43, 43, ++ 62, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 42, 42, 42, 86, ++ 62, 2, 2, 43, 43, 43, 43, 43, 2, 36, 36, 36, 36, 36, 36, 36, ++ 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 88, 42, 42, 42, ++ 84, 42, 86, 79, 43, 43, 43, 43, 36, 36, 36, 60, 36, 61, 36, 36, ++ 69, 42, 42, 79, 43, 79, 42, 56, 42, 42, 42, 69, 43, 43, 43, 43, ++ 36, 36, 36, 61, 60, 36, 36, 36, 36, 36, 36, 36, 36, 85, 85, 89, ++ 42, 88, 86, 86, 60, 43, 43, 43, 36, 36, 36, 36, 82, 36, 43, 43, ++ 36, 69, 84,106, 63, 43, 43, 43, 42, 93, 36, 36, 36, 36, 36, 36, ++ 36, 36, 85, 42, 42, 79, 43, 85, 84, 59, 2, 2, 2, 2, 2, 2, ++ 7, 7, 7, 7, 7, 79, 43, 43, 27, 27, 90, 66, 66, 66, 55, 20, ++ 167, 66, 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 43, 43, 92, ++ 104,104,104,104,104,104,104,181, 2, 2, 63, 43, 43, 43, 43, 43, ++ 62, 63, 43, 43, 43, 43, 43, 43, 64, 64, 64, 64, 64, 64, 64, 64, ++ 70, 36, 36, 69, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 85, 86, 42, ++ 42, 42, 59, 43, 43, 43, 43, 43, 42, 42, 42, 59, 2, 2, 66, 66, ++ 39, 39, 96, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7,179, 27, 27, ++ 27, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 61, 36, ++ 39, 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82,163, 2, ++ 27, 27, 27, 30, 2, 63, 43, 43, 11, 11, 11, 11, 46,149, 16, 16, ++ 16, 16, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 43, 56, ++ 93, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 43, 43, 43, 56, 42, 73, 39, 39, 39, 39, 39, 39, ++ 39, 87, 79, 43, 43, 43, 43, 43, 85, 39,104,181, 43, 43, 43, 43, ++ 43, 43, 43, 43, 43, 43, 43, 61, 36, 60, 43, 43, 43, 43, 43, 43, ++ 39, 39, 51, 39, 39, 39, 51, 80, 43, 60, 43, 43, 43, 43, 43, 43, ++ 36, 60, 61, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 43, 49, 59, 64, 64, 43, 43, 43, 43, 43, 43, ++ 7, 7, 7, 7, 7, 66, 91, 43, 66, 66, 43, 43, 43, 66, 66, 66, ++ 176, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 43, 43, 43, 43, ++ 66, 66, 66, 91, 54, 66, 66, 66, 66, 66,186, 86, 42, 66,186, 85, ++ 85,187, 64, 64, 64, 83, 42, 42, 42, 75, 49, 42, 42, 42, 66, 66, ++ 66, 66, 66, 66, 66, 42, 42, 66, 66, 42, 75, 43, 43, 43, 43, 43, ++ 27, 27, 43, 43, 43, 43, 43, 43, 11, 11, 11, 11, 11, 16, 16, 16, ++ 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, ++ 16, 16,109, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, ++ 16, 16, 16, 16, 16, 16, 46, 11, 43, 46, 47, 46, 47, 11, 46, 11, ++ 11, 11, 11, 16, 16,149,149, 16, 16, 16,149, 16, 16, 16, 16, 16, ++ 16, 16, 11, 47, 11, 46, 47, 11, 11, 11, 46, 11, 11, 11, 46, 16, ++ 16, 16, 16, 16, 11, 47, 11, 46, 11, 11, 46, 46, 43, 11, 11, 11, ++ 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, ++ 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 43, 11, 11, 11, 11, ++ 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, ++ 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, ++ 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, ++ 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, ++ 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 43, 7, ++ 42, 42, 42, 75, 66, 49, 42, 42, 42, 42, 42, 42, 42, 42, 75, 66, ++ 66, 66, 49, 66, 66, 66, 66, 66, 66, 66, 75, 21, 2, 2, 43, 43, ++ 43, 43, 43, 43, 43, 56, 42, 42, 16, 16, 16, 16, 16,138, 16, 16, ++ 16, 16, 16, 16, 16, 16, 16,109, 43, 43,149, 16, 16,109, 43, 43, ++ 42, 42, 42, 79, 42, 42, 42, 42, 42, 42, 42, 42, 79, 56, 42, 42, ++ 42, 56, 79, 42, 42, 79, 43, 43, 39, 39, 39, 39, 39, 39, 39, 43, ++ 43, 43, 43, 43, 43, 43, 43, 56, 42, 42, 42, 73, 39, 39, 39, 43, ++ 7, 7, 7, 7, 7, 43, 43, 76, 36, 36, 36, 36, 36, 36, 36, 79, ++ 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 43, 43, 95, ++ 36, 36, 36, 36, 36, 82, 42, 42,188, 7, 7, 7, 7,189, 43, 92, ++ 36, 69, 36, 70, 36, 36, 36, 42, 36, 36, 69, 43, 43, 43, 43, 82, ++ 36, 36, 36, 60, 36, 36, 61, 60, 36, 36, 60,179, 27, 27, 27, 27, ++ 16, 16, 42, 42, 42, 73, 43, 43, 27, 27, 27, 27, 27, 27,162, 27, ++ 190, 27, 99, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 27,162, ++ 27, 27, 27, 27, 27, 27, 27, 43, 36, 36, 61, 36, 36, 36, 36, 36, ++ 61, 60, 60, 61, 61, 36, 36, 36, 36, 60, 36, 36, 61, 61, 43, 43, ++ 43, 60, 43, 61, 61, 61, 61, 36, 61, 60, 60, 61, 61, 61, 61, 61, ++ 61, 60, 60, 61, 36, 60, 36, 36, 36, 60, 36, 36, 61, 36, 60, 60, ++ 36, 36, 36, 36, 36, 61, 36, 36, 61, 36, 61, 36, 36, 61, 36, 36, ++ 8, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 66, 43, 43, ++ 54, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, 27, 27, 90, 66, ++ 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 66, 66, 66, 66, 66, ++ 66, 91, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 91, 43, 43, 43, ++ 66, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 25, 40, 40, ++ 66, 66, 66, 66, 91, 43, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, ++ 8, 8, 8, 8,176, 43, 43, 43, 66, 66, 66, 66, 66, 91, 43, 66, ++ 66, 66, 66, 91, 91, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, 54, ++ 66, 66, 66, 66, 66, 91, 43, 54, 66, 91, 66, 66, 66, 66, 66, 66, ++ 7, 7, 7, 7, 7, 91, 43, 43, 78, 43, 43, 43, 43, 43, 43, 43, ++ 170,170,170,170,170,170,170, 43,170,170,170,170,170,170,170, 0, ++ 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, ++ 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, ++ 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, ++ 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, ++ 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, ++ 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, ++ 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, ++ 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, ++ 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, ++ 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, ++ 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, ++ 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, ++ 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, ++ 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, ++ 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, ++ 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, ++ 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 12, 11, 9, 26, ++ 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, ++ 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, ++ 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, ++ 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, ++ 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, ++ 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, ++ 12, 17, 21, 1, 26, 10, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, ++ 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, ++ 0, 0, 0, 0, 15, 0, 16, 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, 17, 18, 19, 0, 0, 0, 0, ++ 0, 17, 18, 19, 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, 20, 0, 21, 22, 23, ++ 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, ++ 0, 0, 0, 36, 0, 37, 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, 35, 0, 0, 0, 0, 36, 0, 37, 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, 44, 45, 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, 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, 52, 0, 53, 54, 55, ++ 0, 56, 0, 57, 0, 58, 0, 0, 0, 0, 59, 60, 0, 0, 0, 0, ++ 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 66, ++ 0, 0, 0, 67, 0, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 70, 71, 0, 0, 72, 0, 0, 0, 0, ++ 0, 0, 0, 0, 73, 74, 0, 0, 0, 0, 54, 75, 0, 76, 77, 0, ++ 0, 78, 79, 0, 0, 0, 0, 0, 0, 80, 81, 82, 0, 0, 0, 0, ++ 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, ++ 0, 0, 0, 0, 0, 84, 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, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 87, ++ 0, 0, 0, 0, 88, 89, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 92, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 94, 0, 0, 95, 0, ++ 96, 0, 0, 0, 0, 0, 73, 97, 0, 98, 0, 0, 99,100, 0, 78, ++ 0, 0,101, 0, 0,102, 0, 0, 0, 0, 0,103, 0,104, 26,105, ++ 0, 0,106, 0, 0, 0,107, 0, 0, 0,108, 0, 0, 0, 0, 0, ++ 0, 66,109, 0, 0, 66, 0, 0, 0,110, 0, 0, 0,111, 0, 0, ++ 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0,112,113, 0, ++ 0, 0, 0, 79, 0, 44,114, 0,115, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, ++ 117, 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, 0,119, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 0,121, 0, 0, + 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, 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, +- 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, +- 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, ++ 0, 0, 0,122, 0, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124, ++ 125,126, 0, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,128,129, 0, 0,130, 0, 0, 0, 0,121, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0,132, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, 0, ++ 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0,135, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 0, 0, 0,137, 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, 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, 1, ++ 1, 1, 1, 41, 1, 21, 87, 0, 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, ++ 90, 9, 12, 4, 91, 8, 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, ++ 94, 1, 1, 1, 1, 1, 1, 1, 1, 95, 96, 97, 0, 0, 0, 0, ++ 98, 1, 99, 58, 81,100,101, 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,102,103, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,104, 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,105, 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,106,107, 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,108, 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, 90, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,110, 61, 0,111, 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,112, 51, 0,112, 14, 52, ++ 84, 0, 0, 0,113, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 62, 0, 0, 61, 0, 0, 0, 0, 0, 0,114, 0, 90, 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,114, 0, 0, 0, 0,115, 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,116, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,116, 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, 92, 0, 0, 0, 0, 0, 0, ++ 1, 90, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,118, 0,119,120,121,122, 0,105, 4,123, 49, 23, 0, ++ 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, 38, 58, 0, 0, ++ 0, 0, 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 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,124, ++ 0, 0, 0, 0, 0, 0, 0,113, 0, 0, 0, 0, 19, 59, 0, 38, ++ 0, 81, 0, 0, 0, 0, 0, 0, 4,123, 0, 0, 0, 1,125, 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,234, 0, 0, 9, 9, 0, 0, 7, 0,230,230,230, 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, +@@ -1683,63 +1482,81 @@ _hb_ucd_u8[17612] = + 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, ++ 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, ++ 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 13, 13, ++ 24, 25, 26, 26, 26, 27, 13, 13, 13, 28, 29, 30, 13, 31, 32, 33, ++ 34, 35, 36, 37, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, 38, 7, 7, 39, 7, 40, 7, 7, ++ 7, 41, 13, 42, 7, 7, 43, 7, 7, 7, 44, 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, 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, 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, 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, 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, +- 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, 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, 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, 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, +- 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, 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, 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, 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, +- 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, ++ 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, 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, 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, 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, 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, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, ++ 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, ++ 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ++ 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, ++ 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 59, 63, 64, ++ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 59, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 78, 69, 69, 69, 69, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, ++ 81, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95, 95, 95, 69, 69, 96, 97, 98, 99, 99, 99, ++ 100,101,102,103,104,105,106,107,108,109, 95,110,111,112,113,114, ++ 115,116,117,117,118,119,120,121,122,123,124,125,126,127,128,129, ++ 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, ++ 95,146,147,148,149, 95,150,151,152,153,154,155,156,157,158,159, ++ 160,161, 95,162,163,164,165,165,165,165,165,165,165,166,167,165, ++ 168, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95,169,170,170,170,170,170,170,170,170,171,170, ++ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, ++ 170,170,170,170,170,170,170,170,170,170,170,170,170,172,173,173, ++ 173,173,174, 95, 95, 95, 95, 95,175, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95,176,176,176,176,177,178,179,180, 95, 95, ++ 181, 95,182,183,184,185,186,186,186,186,186,186,186,186,186,186, ++ 186,186,186,186,186,186,186,186,186,186,186,186,187,187,187,188, ++ 189,190, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95,191,192,193,194,195,195,196, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,197,198, ++ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 59,199, ++ 59, 59, 59,200,201,202, 59,203,204,205,206,207,208, 95,209,210, ++ 211, 59, 59,212, 59,213,214,214,214,214,214,215, 95, 95, 95, 95, ++ 95, 95, 95, 95,216, 95,217,218,219, 95, 95,220, 95, 95, 95,221, ++ 95,222, 95,223, 95,224,225,226,227, 95, 95, 95, 95, 95,228,229, ++ 230, 95,231,232, 95, 95,233,234, 59,235,236, 95, 59, 59, 59, 59, ++ 59, 59, 59,237, 59,238,239,240, 59, 59,241,242, 59,243, 95, 95, ++ 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69,244, 69, 69,245, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69,246, 69, 69, 69, 69, 69, 69, 69, 69, 69,247, 69, 69, ++ 69, 69,248, 95, 95, 95, 69, 69, 69, 69,249, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69,250, 69, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,251, 95, ++ 95, 95, 95, 95, 95, 95,252, 95,253,254, 0, 1, 2, 2, 0, 1, ++ 2, 2, 2, 3, 4, 5, 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, +@@ -1764,46 +1581,46 @@ _hb_ucd_u8[17612] = + 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, ++ 37, 2, 2, 2, 2, 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, 23, 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, 2, 2, 2, 2, 16, 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, +@@ -1850,137 +1667,135 @@ _hb_ucd_u8[17612] = + 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, ++ 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 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, 0, 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, 0, 2, 2, 2, 2, 2, 27, 27, ++ 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 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, 2, 19, ++ 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, 3, 3, 3, 0, 0, 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,173,173, ++ 173,173,173,173,173,173,173,173, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 2,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, ++ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, ++ 2, 2, 2, 2, 2, 2,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, +@@ -2039,46 +1854,51 @@ _hb_ucd_u8[17612] = + 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, ++ 2, 2, 2, 2, 2, 2,175,175,175,175,175,175,175,175,175,175, ++ 175,175, 2, 2, 2, 2,175,175, 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,172,172, ++ 172,172,172,172,172,172,172, 2, 2,172,172,172,172,172,172,172, ++ 172,172, 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, ++ 13, 13,155, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 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,136, ++ 136,136,136,136,136, 2,136,136,136, 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, ++ 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 2, 2, ++ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 1, 1, ++ 1, 1, 1, 1, 1, 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, ++ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, +@@ -2090,7 +1910,9 @@ _hb_ucd_u8[17612] = + 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, ++ 168, 2, 2, 2, 2,168,174,174,174,174,174,174,174,174,174,174, ++ 174,174,174,174,174, 2,174,174,174,174,174,174, 2, 2, 2, 2, ++ 2, 2, 2, 2,174,174, 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, +@@ -2101,8 +1923,8 @@ _hb_ucd_u8[17612] = + 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, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, ++ 0, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 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, +@@ -2186,8 +2008,7 @@ _hb_ucd_u8[17612] = + 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[10832]= + { + 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, +@@ -2210,27 +2031,29 @@ _hb_ucd_u16[10400] = + 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, + 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, +- 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, +- 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, +- 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, +- 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, +- 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, +- 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, +- 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, +- 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, +- 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, +- 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, +- 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, +- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, +- 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, +- 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, ++ 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 32, 216, 217, 140, ++ 218, 48, 48, 219, 220, 160, 221, 222, 223, 48, 224, 64, 48, 48, 225, 226, ++ 48, 48, 227, 228, 229, 64, 48, 230, 231, 9, 9, 232, 233, 234, 235, 236, ++ 11, 11, 237, 27, 27, 27, 238, 239, 11, 240, 27, 27, 32, 32, 32, 32, ++ 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, ++ 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, ++ 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, ++ 267, 268, 269, 270, 271, 272, 273, 273, 274, 275, 276, 209, 277, 278, 209, 279, ++ 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, ++ 281, 209, 282, 209, 209, 209, 209, 283, 209, 284, 280, 285, 209, 286, 287, 209, ++ 209, 209, 176, 140, 288, 140, 272, 272, 272, 289, 209, 209, 209, 209, 290, 272, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, ++ 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, ++ 209, 209, 209, 209, 209, 209, 295, 296, 272, 297, 209, 209, 298, 280, 299, 280, + 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, +- 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, ++ 280, 280, 280, 280, 280, 280, 280, 280, 300, 301, 280, 280, 280, 302, 280, 303, ++ 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, ++ 209, 209, 209, 280, 304, 209, 209, 305, 209, 209, 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, + 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, +@@ -2238,226 +2061,201 @@ _hb_ucd_u16[10400] = + 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, 151, 209, 209, 209, 338, 48, 48, 229, ++ 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, 230, ++ 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, + 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, + 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, +- 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, ++ 422, 272, 272, 423, 273, 273, 273, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, + 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, ++ 48, 454, 48, 455, 48, 207, 140, 140, 48, 48, 48, 456, 272, 457, 272, 272, + 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, + 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, + 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, +- 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, +- 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, +- 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, +- 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, +- 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, +- 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, +- 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, +- 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, +- 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, +- 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +- 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, +- 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, +- 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, +- 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, +- 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, +- 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, ++ 140, 140, 140, 140, 140, 140, 272, 479, 48, 48, 480, 481, 482, 483, 140, 484, ++ 48, 464, 485, 48, 62, 486, 140, 48, 487, 140, 140, 48, 488, 140, 48, 313, ++ 489, 48, 48, 490, 491, 457, 492, 493, 223, 48, 48, 494, 495, 48, 196, 192, ++ 496, 48, 497, 498, 499, 48, 48, 500, 223, 48, 48, 501, 502, 503, 504, 505, ++ 48, 97, 506, 507, 508, 140, 140, 140, 509, 510, 511, 48, 48, 512, 513, 192, ++ 514, 83, 84, 515, 516, 517, 518, 519, 520, 48, 48, 521, 522, 523, 524, 140, ++ 48, 48, 48, 525, 526, 527, 481, 140, 48, 48, 48, 528, 529, 192, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 530, 531, 532, 533, 140, 140, ++ 48, 48, 48, 534, 535, 192, 536, 140, 48, 48, 537, 538, 192, 539, 540, 140, ++ 48, 541, 542, 543, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 48, 48, 506, 544, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 545, ++ 546, 547, 48, 548, 549, 192, 140, 140, 140, 140, 550, 48, 48, 551, 552, 140, ++ 553, 48, 48, 554, 555, 556, 48, 48, 557, 558, 559, 48, 48, 48, 48, 196, ++ 560, 140, 140, 140, 140, 140, 561, 140, 140, 140, 140, 140, 48, 48, 562, 192, ++ 84, 48, 530, 563, 564, 148, 175, 565, 48, 566, 567, 568, 140, 140, 140, 140, ++ 569, 48, 48, 570, 571, 192, 572, 48, 573, 574, 192, 48, 48, 575, 192, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 576, ++ 577, 115, 48, 578, 579, 580, 140, 140, 140, 140, 140, 100, 272, 581, 582, 583, ++ 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, ++ 273, 273, 273, 273, 273, 273, 584, 585, 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, 48, 48, 48, 48, 48, 48, 583, +- 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 586, ++ 48, 48, 48, 587, 588, 589, 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, +- 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, 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, 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, 606, +- 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 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, 140, 140, 140, 140, 140, ++ 48, 590, 591, 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, 592, ++ 48, 48, 48, 593, 594, 595, 596, 597, 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, 598, 48, 599, 192, 140, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 9, 9, 11, 11, 272, 600, 9, 601, 11, 602, 140, 140, ++ 48, 48, 48, 48, 603, 604, 605, 605, 606, 607, 140, 140, 140, 140, 608, 609, ++ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 610, ++ 48, 200, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 611, ++ 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, 612, ++ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, ++ 48, 48, 611, 613, 140, 614, 615, 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, +- 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 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, 322, 140, 140, 140, 140, +- 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 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, 71, 151, 196, 616, 617, 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, 618, ++ 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, 619, 209, 427, 209, 620, ++ 32, 32, 216, 32, 621, 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, +- 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, +- 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, +- 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, +- 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, +- 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, +- 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 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, 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, 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, +- 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, +- 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, +- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, +- 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, 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, ++ 209, 209, 622, 209, 209, 209, 623, 624, 625, 209, 626, 209, 209, 209, 288, 140, ++ 209, 209, 209, 209, 627, 140, 140, 140, 140, 140, 140, 140, 272, 628, 272, 628, ++ 209, 209, 209, 209, 209, 338, 272, 461, 140, 140, 140, 140, 140, 140, 140, 140, ++ 9, 629, 11, 630, 631, 632, 242, 9, 633, 634, 635, 636, 637, 9, 629, 11, ++ 638, 639, 11, 640, 641, 642, 643, 9, 644, 11, 9, 629, 11, 630, 631, 11, ++ 242, 9, 633, 643, 9, 644, 11, 9, 629, 11, 645, 9, 646, 647, 648, 649, ++ 11, 650, 9, 651, 652, 653, 654, 11, 655, 9, 656, 11, 657, 539, 539, 539, ++ 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, 658, 32, 32, 659, 660, 661, 662, 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, ++ 663, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 666, 667, 668, 27, 27, 27, 669, 140, 670, 140, 140, 140, 140, 140, 140, 140, ++ 48, 48, 151, 671, 672, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 673, 140, 48, 48, 674, 675, ++ 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, 676, 192, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 590, 677, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 200, 678, 679, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 680, 200, ++ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 681, 621, 140, 140, ++ 9, 9, 633, 11, 682, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 504, 272, 272, 683, 684, 140, 140, 140, 140, ++ 504, 272, 685, 686, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 687, 48, 688, 689, 690, 691, 692, 693, 694, 206, 695, 206, 140, 140, 140, 696, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 209, 209, 697, 209, 209, 209, 209, 209, 209, 322, 333, 698, 698, 698, 209, 323, ++ 699, 209, 209, 209, 209, 209, 209, 209, 209, 209, 700, 140, 140, 140, 701, 209, ++ 702, 209, 209, 697, 703, 704, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 705, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 706, 426, 426, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 176, 697, 427, ++ 697, 209, 209, 209, 707, 176, 209, 209, 707, 209, 700, 697, 704, 708, 140, 140, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, ++ 209, 209, 209, 209, 209, 707, 700, 426, 709, 209, 209, 209, 710, 711, 712, 703, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 713, 209, 209, 209, 209, 209, 714, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, +- 48, 48, 48, 207, 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, 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, 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, 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, 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, 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, 705, +- 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, +- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, +- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, +- 57, 57, 58, 59, 60, 60, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, +- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 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, 7, 4, 4, 4, 4, 99, 100, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 114, 0, +- 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 124, 125, 126, 126, 126, 127, +- 128, 129, 130, 131, 132, 60, 133, 134, 135, 136, 0, 137, 138, 139, 0, 0, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +- 126, 126, 126, 126, 126, 126, 126, 0, 126, 126, 126, 126, 126, 126, 126, 126, ++ 48, 48, 48, 48, 48, 48, 48, 207, 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, 141, 142, 143, 143, 143, 143, 144, 11, 145, 146, 147, 4, 148, 149, +- 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, +- 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, 60, 60, 60, 60, 60, 166, 167, +- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +- 168, 168, 168, 168, 126, 126, 126, 126, 126, 169, 126, 170, 171, 172, 19, 173, +- 19, 19, 19, 19, 174, 19, 175, 176, 177, 178, 19, 179, 180, 181, 182, 183, +- 184, 185, 186, 187, 188, 189, 190, 191, 168, 168, 192, 193, 194, 195, 196, 197, +- 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 206, 206, 207, 208, 209, 168, +- 210, 211, 212, 213, 214, 168, 215, 216, 217, 218, 219, 220, 221, 222, 223, 168, +- 224, 225, 226, 227, 228, 229, 230, 168, 168, 231, 232, 233, 234, 235, 236, 237, +- 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, +- 254, 255, 256, 257, 168, 168, 258, 259, 260, 261, 262, 263, 264, 265, 168, 168, +- 266, 168, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 168, 168, 278, +- 279, 280, 281, 168, 282, 283, 284, 168, 168, 168, 168, 285, 286, 287, 288, 289, +- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 168, +- 290, 292, 290, 290, 290, 293, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 294, 295, +- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, +- 296, 297, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, +- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 298, +- 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 168, 168, 168, 168, 168, 168, +- 168, 168, 168, 168, 301, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +- 302, 302, 302, 302, 302, 302, 302, 302, 303, 304, 305, 306, 307, 308, 309, 168, +- 168, 168, 168, 168, 168, 310, 168, 168, 168, 311, 312, 168, 313, 314, 315, 316, +- 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, +- 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, +- 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 319, 319, 319, 319, +- 319, 319, 319, 320, 321, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 322, +- 323, 324, 324, 324, 325, 326, 327, 327, 327, 327, 327, 328, 168, 168, 168, 168, +- 329, 330, 331, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +- 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 333, 168, 334, 335, 0, 336, +- 0, 0, 0, 337, 338, 339, 340, 341, 189, 342, 168, 343, 0, 344, 168, 168, +- 0, 345, 346, 347, 348, 349, 0, 0, 0, 0, 350, 0, 0, 0, 0, 351, +- 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 168, 168, 168, 168, 168, +- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 354, 168, 168, 168, +- 355, 356, 357, 168, 358, 359, 168, 168, 168, 168, 360, 361, 168, 168, 168, 168, +- 168, 168, 168, 362, 168, 168, 168, 363, 168, 168, 168, 168, 168, 168, 168, 364, +- 365, 365, 365, 366, 367, 368, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, +- 168, 369, 370, 168, 371, 168, 168, 168, 372, 373, 374, 375, 168, 168, 168, 168, +- 376, 0, 377, 378, 0, 0, 379, 380, 381, 382, 168, 168, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 384, 0, 385, +- 386, 387, 388, 389, 0, 0, 0, 0, 0, 390, 391, 392, 0, 0, 393, 332, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 394, 126, 126, 126, 126, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 395, 126, 126, 126, +- 396, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 397, 126, 126, 126, 126, 126, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 398, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, +- 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, 168, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 400, 126, 126, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 401, 168, +- 402, 0, 168, 168, 7, 7, 7, 403, 0, 1, 2, 3, 4, 4, 4, 4, ++ 715, 140, 587, 587, 587, 587, 587, 587, 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, 716, ++ 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, 717, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, + 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, +- 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, +- 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, +- 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, +- 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, +- 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, +- 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, +- 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, +- 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, +- 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, +- 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, +- 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, +- 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, +- 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, +- 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, +- 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, +- 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, +- 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, +- 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, +- 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, +- 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, +- 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, +- 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, +- 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, +- 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, +- 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, ++ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, ++ 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, ++ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, ++ 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, ++ 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, ++ 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, ++ 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, ++ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, ++ 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, ++ 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, ++ 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, ++ 31, 31, 50, 31, 31, 31, 31, 31, 31, 31, 31, 31, 51, 31, 31, 31, ++ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 54, 52, 52, 52, ++ 55, 56, 57, 58, 58, 59, 60, 61, 56, 62, 63, 64, 65, 58, 58, 66, ++ 67, 68, 69, 70, 70, 71, 72, 73, 68, 74, 75, 76, 77, 70, 78, 26, ++ 79, 80, 81, 82, 82, 83, 84, 85, 80, 86, 87, 26, 88, 82, 89, 90, ++ 91, 92, 93, 94, 94, 95, 96, 97, 92, 98, 99, 100, 101, 94, 94, 26, ++ 102, 103, 104, 105, 106, 103, 107, 108, 103, 104, 109, 26, 110, 107, 107, 111, ++ 112, 113, 114, 112, 112, 114, 112, 115, 113, 116, 117, 118, 119, 112, 120, 112, ++ 121, 122, 123, 121, 121, 123, 124, 125, 122, 126, 127, 128, 129, 121, 130, 26, ++ 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, ++ 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, ++ 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, ++ 150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157, 26, 26, 26, 26, ++ 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158, ++ 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, 26, 26, 26, 26, ++ 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, +- 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, +- 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, +- 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, +- 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, ++ 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, ++ 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170, ++ 170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170, ++ 170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174, ++ 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, ++ 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, + 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, +@@ -2466,165 +2264,215 @@ _hb_ucd_u16[10400] = + 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, + 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, + 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, +- 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, +- 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 222, +- 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, +- 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, +- 18, 232, 165, 165, 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, +- 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, +- 2, 2, 2, 2, 2, 2, 2, 245, 14, 14, 246, 246, 14, 14, 14, 14, +- 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 14, 14, 14, 14, 248, 14, +- 248, 14, 249, 250, 14, 14, 251, 252, 0, 253, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, 0, 0, 0, 0, +- 259, 26, 9, 9, 9, 9, 260, 26, 0, 0, 0, 0, 261, 262, 4, 0, +- 0, 263, 0, 0, 2, 2, 2, 2, 2, 264, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, +- 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 268, 0, +- 0, 0, 269, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, +- 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, +- 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, +- 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, +- 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 276, 26, 26, 26, 26, +- 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, +- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, +- 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, +- 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, +- 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, +- 0, 0, 0, 0, 276, 296, 290, 290, 169, 169, 169, 295, 0, 0, 0, 0, +- 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 290, 290, 290, 290, 290, 298, +- 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, +- 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, +- 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, +- 303, 303, 303, 303, 303, 304, 26, 26, 18, 18, 18, 18, 305, 305, 305, 305, +- 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, +- 2, 307, 2, 2, 2, 2, 2, 2, 2, 308, 309, 258, 26, 26, 310, 2, +- 311, 311, 311, 311, 311, 312, 0, 265, 313, 313, 313, 313, 313, 313, 313, 26, +- 314, 314, 314, 314, 314, 314, 314, 314, 315, 316, 314, 317, 53, 53, 53, 53, +- 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, +- 324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, +- 328, 328, 328, 328, 328, 328, 329, 26, 328, 330, 328, 331, 164, 164, 164, 164, +- 332, 332, 332, 332, 332, 332, 332, 332, 333, 26, 26, 334, 335, 335, 336, 26, +- 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, 339, 340, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, +- 169, 169, 169, 169, 343, 26, 169, 169, 295, 344, 169, 169, 169, 169, 169, 343, +- 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 280, 277, 277, +- 277, 277, 277, 345, 26, 26, 26, 26, 346, 26, 347, 348, 25, 25, 349, 350, +- 351, 25, 31, 31, 31, 31, 31, 31, 352, 26, 353, 31, 31, 31, 31, 31, +- 31, 31, 31, 31, 31, 31, 31, 354, 31, 31, 355, 31, 31, 31, 31, 31, +- 31, 356, 26, 26, 26, 26, 31, 31, 9, 9, 0, 265, 9, 357, 0, 0, +- 0, 0, 358, 0, 257, 359, 360, 31, 31, 31, 31, 31, 31, 31, 31, 361, +- 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, +- 290, 290, 290, 364, 169, 169, 169, 295, 365, 365, 365, 366, 257, 257, 26, 367, +- 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, +- 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, +- 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, +- 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, +- 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, +- 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, +- 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, +- 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, +- 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, +- 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, +- 407, 408, 409, 407, 410, 407, 410, 411, 412, 412, 412, 412, 412, 412, 413, 26, +- 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 415, 26, +- 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, +- 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, +- 428, 428, 428, 429, 430, 428, 26, 26, 26, 26, 26, 26, 431, 431, 432, 433, +- 434, 434, 434, 435, 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, +- 439, 439, 441, 439, 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, +- 446, 449, 446, 449, 450, 450, 450, 450, 451, 451, 451, 451, 26, 26, 26, 26, +- 452, 452, 452, 452, 453, 454, 453, 26, 455, 455, 455, 455, 455, 455, 456, 457, +- 458, 458, 459, 458, 460, 460, 461, 460, 462, 462, 463, 464, 26, 465, 26, 26, +- 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 26, 26, 26, 26, 26, 26, +- 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 468, 468, 468, 468, 469, 470, +- 471, 471, 471, 471, 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, +- 474, 476, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, +- 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, 26, 26, 26, 481, +- 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, 26, 26, 485, 485, +- 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, 489, 489, 490, 26, +- 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, +- 495, 495, 495, 495, 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, +- 501, 501, 501, 501, 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, +- 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 137, 507, 26, +- 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, 26, 26, 26, 26, +- 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, +- 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, +- 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, +- 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, +- 541, 541, 541, 541, 541, 541, 541, 541, 541, 26, 541, 542, 26, 26, 26, 26, +- 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, 26, 26, 26, 26, +- 545, 545, 545, 545, 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, +- 549, 549, 549, 549, 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, +- 552, 552, 552, 553, 552, 554, 552, 552, 555, 26, 26, 26, 26, 26, 26, 26, +- 556, 556, 556, 556, 556, 556, 556, 557, 26, 26, 26, 26, 558, 558, 558, 558, +- 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, +- 561, 26, 564, 567, 26, 26, 26, 26, 26, 26, 26, 26, 568, 569, 568, 568, +- 568, 568, 568, 569, 570, 26, 26, 26, 571, 571, 571, 571, 571, 571, 571, 571, +- 571, 26, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, +- 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 26, 26, 26, 26, +- 577, 577, 577, 577, 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, +- 582, 26, 579, 579, 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, +- 588, 589, 590, 590, 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, +- 595, 596, 597, 598, 595, 599, 26, 26, 26, 26, 26, 26, 600, 600, 600, 601, +- 602, 602, 603, 602, 602, 602, 602, 604, 602, 602, 602, 605, 26, 26, 26, 26, +- 26, 26, 26, 26, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, +- 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 26, 26, 26, 26, +- 609, 609, 609, 609, 609, 611, 612, 26, 613, 26, 26, 26, 26, 26, 26, 26, +- 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, +- 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 616, 616, 616, 616, +- 616, 616, 616, 616, 616, 616, 616, 618, 619, 619, 619, 619, 619, 619, 619, 619, +- 620, 26, 26, 26, 26, 26, 26, 26, 621, 621, 621, 621, 621, 621, 621, 622, +- 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 623, +- 624, 624, 624, 625, 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, +- 627, 629, 630, 630, 630, 631, 631, 26, 632, 632, 632, 632, 632, 632, 632, 632, +- 633, 26, 632, 634, 634, 632, 632, 635, 632, 632, 26, 26, 26, 26, 26, 26, +- 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, 638, 638, 638, 638, +- 638, 638, 638, 639, 26, 26, 26, 26, 640, 640, 640, 640, 640, 640, 640, 640, +- 640, 641, 640, 640, 640, 640, 640, 640, 640, 642, 640, 640, 26, 26, 26, 26, +- 26, 26, 26, 26, 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 644, +- 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, 645, 645, 645, 645, +- 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 26, 26, +- 26, 26, 26, 26, 26, 26, 649, 650, 651, 286, 286, 286, 286, 286, 286, 286, +- 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 652, 26, 653, 26, +- 26, 26, 654, 26, 655, 26, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, +- 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 658, 658, 658, +- 658, 658, 658, 658, 658, 659, 658, 660, 658, 661, 658, 662, 359, 26, 26, 26, +- 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 359, 26, +- 9, 9, 9, 9, 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, +- 359, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 276, 26, +- 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 664, 665, 0, 666, +- 667, 668, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, +- 246, 26, 26, 26, 26, 26, 26, 26, 0, 0, 359, 26, 0, 0, 359, 26, +- 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 0, +- 0, 0, 0, 254, 670, 671, 0, 672, 673, 0, 0, 0, 0, 0, 0, 0, +- 269, 674, 254, 254, 0, 0, 0, 675, 676, 677, 678, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 276, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, +- 679, 679, 679, 679, 679, 679, 679, 679, 679, 680, 26, 681, 682, 679, 26, 26, +- 2, 2, 2, 346, 683, 419, 26, 26, 684, 270, 270, 685, 686, 687, 18, 18, +- 18, 18, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, 26, 26, 26, 26, +- 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 26, 26, +- 26, 26, 694, 694, 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, +- 26, 26, 698, 698, 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, +- 26, 26, 26, 26, 172, 702, 170, 172, 703, 703, 703, 703, 703, 703, 703, 703, +- 704, 703, 705, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 706, 706, 706, +- 706, 707, 706, 708, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, +- 0, 0, 0, 0, 0, 0, 376, 26, 362, 0, 0, 0, 0, 0, 0, 276, +- 709, 31, 31, 31, 710, 711, 712, 713, 714, 715, 710, 716, 710, 712, 712, 717, +- 31, 718, 31, 719, 720, 718, 31, 719, 26, 26, 26, 26, 26, 26, 721, 26, +- 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 359, 26, 0, 257, 362, 0, +- 362, 0, 362, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, +- 26, 26, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, +- 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, +- 0, 0, 0, 0, 0, 0, 257, 725, 0, 0, 0, 265, 0, 359, 259, 26, +- 0, 359, 0, 0, 0, 0, 0, 0, 0, 26, 0, 265, 0, 0, 0, 0, +- 0, 26, 0, 0, 0, 276, 0, 359, 265, 26, 26, 26, 26, 26, 26, 26, +- 0, 0, 359, 26, 0, 276, 0, 376, 0, 726, 0, 0, 0, 0, 0, 0, +- 257, 722, 0, 727, 0, 265, 0, 259, 0, 0, 358, 0, 0, 0, 0, 0, +- 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 345, +- 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 345, 26, 277, 277, +- 277, 277, 277, 277, 728, 26, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, +- 277, 729, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, +- 730, 26, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, ++ 216, 219, 216, 219, 216, 220, 9, 9, 9, 9, 9, 221, 9, 222, 26, 26, ++ 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 223, 223, 223, 223, 223, 223, ++ 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228, ++ 229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232, ++ 18, 233, 165, 165, 165, 165, 165, 234, 225, 26, 235, 9, 236, 237, 238, 239, ++ 2, 2, 2, 2, 240, 241, 2, 2, 2, 2, 2, 242, 243, 244, 2, 245, ++ 2, 2, 2, 2, 2, 2, 2, 246, 9, 9, 9, 9, 9, 9, 9, 9, ++ 14, 14, 247, 247, 14, 14, 14, 14, 247, 247, 14, 248, 14, 14, 14, 247, ++ 14, 14, 14, 14, 14, 14, 249, 14, 249, 14, 250, 251, 14, 14, 252, 253, ++ 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 256, 257, ++ 0, 258, 2, 259, 0, 0, 0, 0, 260, 26, 9, 9, 9, 9, 261, 26, ++ 0, 0, 0, 0, 262, 263, 4, 0, 0, 264, 0, 0, 2, 2, 2, 2, ++ 2, 265, 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, 260, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, ++ 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, ++ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 2, 2, 2, 2, ++ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 270, 271, ++ 165, 165, 165, 165, 166, 167, 272, 272, 272, 272, 272, 272, 272, 273, 274, 273, ++ 170, 170, 172, 26, 172, 172, 172, 172, 172, 172, 172, 172, 18, 18, 18, 18, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, ++ 276, 276, 276, 277, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 278, 26, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 0, 0, ++ 280, 0, 0, 0, 281, 282, 0, 283, 284, 285, 285, 285, 285, 285, 285, 285, ++ 285, 285, 286, 287, 288, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 290, ++ 291, 292, 292, 292, 292, 292, 293, 169, 169, 169, 169, 169, 169, 169, 169, 169, ++ 169, 294, 0, 0, 292, 292, 292, 292, 0, 0, 0, 0, 275, 295, 289, 289, ++ 169, 169, 169, 294, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 296, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 289, 289, 289, 289, 297, ++ 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 0, 0, 0, 0, 0, ++ 276, 276, 276, 276, 276, 276, 276, 276, 0, 0, 0, 0, 0, 0, 0, 0, ++ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, ++ 298, 299, 298, 298, 298, 298, 298, 298, 300, 26, 301, 301, 301, 301, 301, 301, ++ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, ++ 302, 302, 302, 302, 302, 303, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, ++ 18, 18, 18, 18, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 26, ++ 0, 0, 0, 0, 305, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 306, 2, 2, 2, 2, 2, 2, 2, 2, 2, 259, 26, 26, 307, 2, ++ 308, 308, 308, 308, 308, 309, 0, 260, 310, 310, 310, 310, 310, 310, 310, 26, ++ 311, 311, 311, 311, 311, 311, 311, 311, 312, 313, 311, 314, 52, 52, 52, 52, ++ 315, 315, 315, 315, 315, 316, 317, 317, 317, 317, 318, 319, 169, 169, 169, 320, ++ 321, 321, 321, 321, 321, 321, 321, 321, 321, 322, 321, 323, 164, 164, 164, 324, ++ 325, 325, 325, 325, 325, 325, 326, 26, 325, 327, 325, 328, 164, 164, 164, 164, ++ 329, 329, 329, 329, 329, 329, 329, 329, 330, 26, 26, 331, 332, 332, 333, 26, ++ 334, 334, 334, 26, 172, 172, 2, 2, 2, 2, 2, 335, 336, 337, 176, 176, ++ 176, 176, 176, 176, 176, 176, 176, 176, 332, 332, 332, 332, 332, 338, 332, 339, ++ 169, 169, 169, 169, 340, 26, 169, 169, 294, 341, 169, 169, 169, 169, 169, 340, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 276, 276, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 342, 26, 26, 26, 26, ++ 343, 26, 344, 345, 25, 25, 346, 347, 348, 25, 31, 31, 31, 31, 31, 31, ++ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, ++ 31, 31, 31, 31, 31, 31, 31, 349, 31, 31, 31, 31, 31, 31, 31, 31, ++ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 26, 26, 26, 26, 31, 31, ++ 9, 9, 0, 260, 9, 350, 0, 0, 0, 0, 351, 0, 258, 352, 353, 31, ++ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 354, ++ 355, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 356, 289, 288, 289, ++ 289, 289, 289, 357, 169, 169, 169, 294, 358, 358, 358, 359, 258, 258, 26, 360, ++ 361, 362, 361, 361, 363, 361, 361, 364, 361, 365, 361, 365, 26, 26, 26, 26, ++ 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 366, ++ 367, 0, 0, 0, 0, 0, 368, 0, 14, 14, 14, 14, 14, 14, 14, 14, ++ 14, 253, 0, 369, 370, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 371, ++ 372, 372, 372, 373, 374, 374, 374, 374, 374, 374, 375, 26, 376, 0, 0, 352, ++ 377, 377, 377, 377, 378, 379, 380, 380, 380, 381, 382, 382, 382, 382, 382, 383, ++ 384, 384, 384, 385, 386, 386, 386, 386, 387, 386, 388, 26, 26, 26, 26, 26, ++ 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, ++ 391, 391, 391, 392, 391, 393, 394, 394, 394, 394, 395, 394, 394, 394, 394, 395, ++ 396, 396, 396, 396, 396, 26, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, ++ 400, 401, 402, 400, 403, 400, 403, 404, 405, 405, 405, 405, 405, 405, 406, 26, ++ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, ++ 407, 407, 407, 407, 407, 407, 408, 26, 407, 407, 409, 26, 407, 26, 26, 26, ++ 410, 2, 2, 2, 2, 2, 411, 412, 26, 26, 26, 26, 26, 26, 26, 26, ++ 413, 414, 415, 415, 415, 415, 416, 417, 418, 418, 419, 418, 420, 420, 420, 420, ++ 421, 421, 421, 422, 423, 421, 26, 26, 26, 26, 26, 26, 424, 424, 425, 426, ++ 427, 427, 427, 428, 429, 429, 429, 430, 431, 431, 431, 432, 26, 26, 26, 26, ++ 433, 433, 433, 433, 434, 434, 434, 435, 434, 434, 436, 434, 434, 434, 434, 434, ++ 437, 438, 439, 440, 441, 441, 442, 443, 441, 444, 441, 444, 445, 445, 445, 445, ++ 446, 446, 446, 446, 26, 26, 26, 26, 447, 447, 447, 447, 448, 449, 448, 26, ++ 450, 450, 450, 450, 450, 450, 451, 452, 453, 453, 454, 453, 455, 455, 456, 455, ++ 457, 457, 458, 459, 26, 460, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 461, 461, 461, 461, 461, 461, 461, 461, 461, 462, 26, 26, 26, 26, 26, 26, ++ 463, 463, 463, 463, 463, 463, 464, 26, 463, 463, 463, 463, 463, 463, 464, 465, ++ 466, 466, 466, 466, 466, 26, 466, 467, 468, 468, 468, 468, 469, 470, 468, 468, ++ 469, 471, 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, 31, 31, 31, 472, ++ 473, 473, 473, 473, 473, 474, 475, 26, 476, 26, 31, 477, 26, 26, 26, 476, ++ 478, 478, 478, 478, 478, 26, 479, 479, 479, 479, 479, 480, 26, 26, 481, 481, ++ 481, 482, 26, 26, 26, 26, 483, 483, 483, 484, 26, 26, 485, 485, 486, 26, ++ 487, 487, 487, 487, 487, 487, 487, 487, 487, 488, 489, 487, 487, 487, 488, 490, ++ 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 494, 494, 494, 495, 494, 496, ++ 497, 497, 497, 497, 497, 497, 498, 497, 497, 26, 499, 499, 499, 499, 500, 26, ++ 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 137, 503, 26, ++ 504, 504, 505, 504, 504, 504, 504, 504, 506, 26, 26, 26, 26, 26, 26, 26, ++ 507, 508, 509, 510, 509, 511, 512, 512, 512, 512, 512, 512, 512, 513, 512, 514, ++ 515, 516, 517, 518, 518, 519, 520, 521, 516, 522, 523, 524, 525, 526, 526, 26, ++ 527, 528, 527, 527, 527, 527, 529, 527, 530, 531, 529, 532, 533, 26, 26, 26, ++ 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 535, 536, 26, 26, 26, ++ 537, 537, 537, 537, 537, 537, 537, 537, 537, 26, 537, 538, 26, 26, 26, 26, ++ 539, 539, 539, 539, 539, 539, 540, 539, 539, 539, 539, 540, 26, 26, 26, 26, ++ 541, 541, 541, 541, 541, 541, 541, 541, 542, 26, 541, 543, 198, 544, 26, 26, ++ 545, 545, 545, 545, 545, 545, 545, 546, 545, 546, 164, 164, 547, 26, 26, 26, ++ 548, 548, 548, 549, 548, 550, 548, 548, 551, 26, 26, 26, 26, 26, 26, 26, ++ 552, 552, 552, 552, 552, 552, 552, 553, 26, 26, 26, 26, 26, 26, 26, 26, ++ 26, 26, 26, 26, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, 556, ++ 557, 558, 559, 560, 560, 560, 561, 562, 557, 26, 560, 563, 26, 26, 26, 26, ++ 26, 26, 26, 26, 564, 565, 564, 564, 564, 564, 564, 565, 566, 26, 26, 26, ++ 567, 567, 567, 567, 567, 567, 567, 567, 567, 26, 568, 568, 568, 568, 568, 568, ++ 568, 568, 568, 568, 569, 26, 178, 178, 570, 570, 570, 570, 570, 570, 570, 571, ++ 52, 572, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 501, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 573, 573, 573, 573, 574, 26, 573, 574, ++ 575, 576, 575, 575, 575, 575, 577, 575, 578, 26, 575, 575, 575, 579, 580, 580, ++ 580, 580, 581, 580, 580, 582, 583, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 584, 585, 586, 586, 586, 586, 584, 587, 586, 26, 586, 588, 589, 590, 591, 591, ++ 591, 592, 593, 594, 591, 595, 596, 596, 596, 596, 596, 597, 596, 598, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 599, 599, 599, 600, ++ 601, 601, 602, 601, 601, 601, 601, 603, 601, 601, 601, 604, 26, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 605, 26, 107, 107, 107, 107, 107, 107, 606, 607, ++ 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, ++ 608, 608, 608, 609, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 610, 611, 26, ++ 608, 608, 608, 608, 608, 608, 608, 608, 612, 26, 26, 26, 26, 26, 26, 26, ++ 26, 26, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 614, 26, ++ 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, ++ 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 616, 26, 615, 615, 615, 615, ++ 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 617, ++ 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, ++ 618, 618, 618, 618, 618, 618, 618, 618, 619, 26, 26, 26, 26, 26, 26, 26, ++ 620, 620, 620, 620, 620, 620, 620, 621, 26, 26, 26, 26, 26, 26, 26, 26, ++ 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, ++ 304, 304, 304, 304, 304, 304, 304, 622, 623, 623, 623, 624, 623, 625, 626, 626, ++ 626, 626, 626, 626, 626, 626, 626, 627, 626, 628, 629, 629, 629, 630, 630, 26, ++ 631, 631, 631, 631, 631, 631, 631, 631, 632, 26, 631, 633, 633, 631, 631, 634, ++ 631, 631, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 635, 635, 635, 635, 635, 635, 635, 636, ++ 26, 26, 26, 26, 26, 26, 26, 26, 637, 637, 637, 637, 637, 637, 637, 637, ++ 637, 637, 637, 638, 639, 639, 639, 640, 639, 639, 641, 26, 26, 26, 26, 26, ++ 642, 642, 642, 642, 642, 642, 642, 642, 642, 643, 642, 642, 642, 642, 642, 642, ++ 642, 644, 642, 642, 26, 26, 26, 26, 26, 26, 26, 26, 645, 26, 646, 26, ++ 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, ++ 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, ++ 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 649, 26, 26, 26, 26, 650, ++ 647, 647, 647, 651, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 652, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 653, 654, ++ 655, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, ++ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, ++ 285, 285, 285, 285, 656, 26, 657, 26, 26, 26, 658, 26, 659, 26, 660, 660, ++ 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, ++ 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 661, ++ 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 662, 663, 662, 664, ++ 662, 665, 662, 666, 352, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, ++ 0, 0, 0, 0, 0, 0, 352, 667, 0, 0, 668, 26, 0, 0, 668, 26, ++ 9, 9, 9, 9, 9, 221, 9, 9, 669, 26, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 352, 26, 26, 26, 26, 26, 26, 26, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, ++ 0, 0, 0, 0, 258, 355, 0, 0, 0, 0, 0, 0, 670, 671, 0, 672, ++ 673, 674, 0, 0, 0, 675, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, ++ 14, 14, 14, 14, 14, 14, 14, 14, 247, 26, 26, 26, 26, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 352, 26, 0, 0, 352, 26, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 0, 0, 0, 668, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, ++ 0, 0, 0, 255, 676, 677, 0, 678, 679, 0, 0, 0, 0, 0, 0, 0, ++ 680, 681, 255, 255, 0, 0, 0, 682, 683, 667, 684, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, ++ 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, ++ 685, 686, 26, 687, 688, 685, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 2, 2, 2, 343, 689, 412, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 690, 269, 269, 691, 692, 693, 18, 18, 18, 18, 18, 18, 18, 694, 26, 26, ++ 26, 695, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 696, 696, 696, 696, 696, 697, 696, 698, 696, 699, 26, 26, 26, 26, 26, 26, ++ 26, 26, 700, 700, 700, 701, 26, 26, 702, 702, 702, 702, 702, 702, 702, 703, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 704, 704, 704, 704, 704, 705, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 707, ++ 26, 26, 26, 26, 26, 26, 26, 26, 708, 708, 708, 709, 708, 708, 710, 711, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 712, 170, 172, ++ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, ++ 713, 713, 713, 713, 713, 713, 713, 713, 714, 713, 715, 26, 26, 26, 26, 26, ++ 716, 716, 716, 716, 716, 716, 716, 716, 716, 717, 716, 718, 26, 26, 26, 26, ++ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 355, 0, ++ 0, 0, 0, 0, 0, 0, 369, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 355, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 26, 26, ++ 719, 31, 31, 31, 720, 721, 722, 723, 724, 725, 720, 726, 720, 722, 722, 727, ++ 31, 728, 31, 729, 730, 728, 31, 729, 26, 26, 26, 26, 26, 26, 731, 26, ++ 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 352, 26, 0, 258, 355, 0, 355, 0, 355, 0, 0, 0, 275, 26, ++ 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 732, 0, 0, 0, ++ 733, 26, 0, 0, 0, 0, 0, 352, 0, 668, 260, 26, 275, 26, 26, 26, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 734, 0, 369, 0, 369, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 352, 668, 26, ++ 0, 352, 0, 0, 0, 0, 0, 0, 0, 26, 0, 260, 0, 0, 0, 0, ++ 0, 26, 0, 0, 0, 275, 0, 352, 260, 26, 0, 668, 26, 26, 26, 26, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 275, 0, 369, ++ 0, 735, 0, 0, 0, 0, 0, 0, 258, 736, 0, 737, 0, 367, 0, 668, ++ 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 26, 26, 26, 26, ++ 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, ++ 276, 276, 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 738, 26, 276, 276, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 26, ++ 276, 276, 276, 279, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 739, 276, 276, 276, 276, 276, 276, ++ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 342, ++ 740, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, + 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, +@@ -2840,8 +2688,7 @@ _hb_ucd_u16[10400] = + 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, + 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, + }; +-static const int16_t +-_hb_ucd_i16[196] = ++static const int16_t _hb_ucd_i16[196]= + { + 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, + 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, +@@ -2858,47 +2705,42 @@ _hb_ucd_i16[196] = + -1, 0, 1, -1, + }; + +-static inline uint_fast8_t +-_hb_ucd_gc (unsigned u) ++static inline uint8_t _hb_ucd_gc (unsigned u) + { +- return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; ++ return u<1114110 ? _hb_ucd_u8[7920u+((_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 uint_fast8_t +-_hb_ucd_ccc (unsigned u) ++static inline uint8_t _hb_ucd_ccc (unsigned u) + { +- return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; ++ return u<125259 ? _hb_ucd_u8[10388u+((_hb_ucd_u8[9284u+((_hb_ucd_u8[8548u+((_hb_ucd_u8[8302u+((((((u)>>2))>>3))>>4)])<<4)+((((((u)>>2))>>3))&15)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0; + } +-static inline unsigned +-_hb_ucd_b4 (const uint8_t* a, unsigned i) ++static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) + { +- return (a[i>>1]>>((i&1u)<<2))&15u; ++ return (a[i>>1]>>((i&1)<<2))&15; + } +-static inline int_fast16_t +-_hb_ucd_bmg (unsigned u) ++static inline int16_t _hb_ucd_bmg (unsigned u) + { +- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9252+(((_hb_ucd_u8[9132+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; ++ return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[11140u+((_hb_ucd_u8[11020u+((_hb_ucd_b4(_hb_ucd_u8+10892u,((((((u)>>2))>>3))>>3)))<<3)+((((((u)>>2))>>3))&7)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)] : 0; + } +-static inline uint_fast8_t +-_hb_ucd_sc (unsigned u) ++static inline uint8_t _hb_ucd_sc (unsigned u) + { +- return u<918000u?_hb_ucd_u8[10486+(((_hb_ucd_u16[3744+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9588+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15u))])<<3)+((u>>3)&7u))])<<3)+((u)&7u))]:2; ++ return u<918000 ? _hb_ucd_u8[12662u+((_hb_ucd_u16[3328u+((_hb_ucd_u8[11926u+((_hb_ucd_u8[11476u+((((((u)>>3))>>4))>>4)])<<4)+((((((u)>>3))>>4))&15)])<<4)+((((u)>>3))&15)])<<3)+((u)&7)] : 2; + } +-static inline uint_fast16_t +-_hb_ucd_dm (unsigned u) ++static inline uint16_t _hb_ucd_dm (unsigned u) + { +- return u<195102u?_hb_ucd_u16[6976+(((_hb_ucd_u8[16716+(((_hb_ucd_u8[16334+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; ++ return u<195102 ? _hb_ucd_u16[7408u+((_hb_ucd_u8[18972u+((_hb_ucd_u8[18590u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; + } + + + #elif !defined(HB_NO_UCD_UNASSIGNED) + +-static const uint8_t +-_hb_ucd_u8[17524] = ++#include ++ ++static const uint8_t _hb_ucd_u8[14800]= + { + 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, ++ 5, 29, 5, 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, +@@ -2929,23 +2771,23 @@ _hb_ucd_u8[17524] = + 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, ++ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,111,112,100,100, ++ 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,113, ++ 17,114,115,100,100,100,100,100,100,100,100,100,116,100,100,100, ++ 100,100,100,100,100,100,100,100,100,100,100,100,117, 39,118,119, ++ 120,121,122,123,124,125,126,127, 39, 39,128,100,100,100,100,129, ++ 130,131,132,100,133,134,135,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, ++ 17, 17, 17, 17, 17, 17, 17, 17,152, 17, 17, 17, 17, 17, 17, 17, ++ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,153, 17, ++ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, 17,155,100, ++ 100,100,100,100,100,100,100,100, 17, 17,156,100,100,100,100,100, ++ 17, 17, 17,157, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, ++ 17, 17, 17, 17,158,100,100,100,100,100,100,100,100,100,100,100, ++ 159,160,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,161, + 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, + 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, +@@ -2959,409 +2801,415 @@ _hb_ucd_u8[17524] = + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, +- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, +- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, +- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, +- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, +- 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, +- 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, +- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, +- 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, +- 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, +- 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, +- 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, +- 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, +- 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, +- 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, +- 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, +- 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, +- 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, +- 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, +- 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, +- 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, +- 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, +- 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, +- 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, +- 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, +- 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, +- 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, +- 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, +- 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, +- 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, +- 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, +- 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, +- 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, +- 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, +- 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, +- 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, +- 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, +- 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, +- 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, +- 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, +- 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, +- 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, +- 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, +- 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, +- 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, +- 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, +- 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, +- 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, +- 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, +- 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, +- 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, +- 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, +- 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, +- 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, +- 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, +- 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, +- 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, +- 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, +- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, +- 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, +- 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, +- 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, +- 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, +- 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, +- 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, +- 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, +- 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, +- 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, +- 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, +- 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, +- 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, +- 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, +- 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, +- 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, +- 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, +- 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, +- 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, +- 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, +- 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, +- 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, +- 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, +- 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, +- 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, +- 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, +- 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, +- 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, +- 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, +- 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, +- 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, +- 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, +- 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, +- 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, +- 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, +- 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, +- 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, +- 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, +- 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, +- 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, +- 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, +- 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, +- 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, +- 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, +- 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, +- 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, +- 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, +- 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, +- 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, +- 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, +- 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, +- 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, +- 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, +- 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, +- 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, +- 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, +- 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, +- 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, +- 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, +- 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, +- 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, +- 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, +- 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, +- 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, +- 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, +- 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, +- 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, +- 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, +- 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, +- 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, +- 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, +- 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, +- 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, +- 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, +- 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, +- 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, +- 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, +- 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, +- 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, +- 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, +- 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, +- 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, +- 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, +- 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, +- 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, +- 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, +- 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, +- 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, +- 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, +- 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, +- 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, +- 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, +- 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, +- 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, +- 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, +- 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, +- 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, +- 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, ++ 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, ++ 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, ++ 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, ++ 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 43, 44, 16, 10, ++ 43, 43, 40, 45, 11, 46, 46, 11, 34, 11, 11, 11, 11, 11, 11, 11, ++ 11, 47, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, ++ 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 48, 34, 32, 34, 11, ++ 32, 49, 42, 42, 50, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, ++ 47, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 46, 51, 2, 2, 2, ++ 16, 16, 16, 16, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, ++ 42, 42, 42, 42, 42, 42, 42, 57, 58, 59, 42, 58, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 61, ++ 36, 62, 63, 43, 43, 43, 43, 43, 64, 64, 64, 8, 9, 65, 2, 66, ++ 42, 42, 42, 42, 42, 59, 67, 2, 68, 36, 36, 36, 36, 69, 42, 42, ++ 7, 7, 7, 7, 7, 2, 2, 36, 70, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 71, 42, 42, 42, 72, 49, 42, 42, 73, 74, 75, 42, 42, 36, ++ 7, 7, 7, 7, 7, 36, 76, 77, 2, 2, 2, 2, 2, 2, 2, 78, ++ 69, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 79, 61, 36, ++ 36, 36, 36, 42, 42, 42, 42, 42, 70, 43, 43, 43, 43, 43, 43, 43, ++ 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, ++ 42, 42, 39, 21, 2, 80, 56, 20, 36, 36, 36, 42, 42, 74, 42, 42, ++ 42, 42, 74, 42, 74, 42, 42, 43, 2, 2, 2, 2, 2, 2, 2, 63, ++ 36, 36, 36, 36, 69, 42, 43, 63, 36, 36, 36, 36, 36, 60, 43, 43, ++ 36, 36, 36, 36, 81, 36, 36, 36, 64, 43, 43, 56, 42, 42, 42, 42, ++ 36, 36, 36, 36, 82, 42, 42, 42, 42, 83, 42, 42, 42, 42, 42, 42, ++ 42, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 70, 85, ++ 86, 42, 42, 42, 84, 85, 86, 85, 69, 42, 42, 42, 36, 36, 36, 36, ++ 36, 42, 2, 7, 7, 7, 7, 7, 87, 36, 36, 36, 36, 36, 36, 36, ++ 69, 85, 61, 36, 36, 36, 60, 61, 60, 61, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 60, 36, 36, 36, 60, 60, 43, 36, 36, 43, 70, 85, ++ 86, 42, 79, 88, 89, 88, 86, 60, 43, 43, 43, 88, 43, 43, 36, 61, ++ 36, 42, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 55, 62, 79, ++ 56, 84, 61, 36, 36, 60, 43, 61, 60, 36, 61, 60, 36, 43, 79, 85, ++ 86, 79, 43, 56, 79, 56, 42, 43, 56, 43, 43, 43, 61, 36, 60, 60, ++ 43, 43, 43, 7, 7, 7, 7, 7, 42, 36, 69, 63, 43, 43, 43, 43, ++ 56, 84, 61, 36, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, ++ 60, 36, 61, 36, 36, 43, 70, 85, 86, 42, 42, 56, 84, 88, 86, 43, ++ 60, 43, 43, 43, 43, 43, 43, 43, 65, 43, 43, 43, 61, 42, 42, 42, ++ 56, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 43, 70, 86, ++ 86, 42, 79, 88, 89, 88, 86, 43, 43, 43, 56, 84, 43, 43, 36, 61, ++ 77, 27, 27, 27, 43, 43, 43, 43, 43, 70, 61, 36, 36, 60, 43, 36, ++ 60, 36, 36, 43, 61, 60, 60, 36, 43, 61, 60, 43, 36, 60, 43, 36, ++ 36, 36, 36, 36, 36, 43, 43, 85, 84, 89, 43, 85, 89, 85, 86, 43, ++ 60, 43, 43, 88, 43, 43, 43, 43, 27, 90, 66, 66, 55, 91, 43, 43, ++ 84, 85, 70, 36, 36, 36, 60, 36, 60, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 43, 70, 42, 84, 85, 89, 42, 79, 42, 42, 43, ++ 43, 43, 56, 79, 36, 60, 36, 43, 43, 43, 43, 92, 27, 27, 27, 90, ++ 69, 85, 71, 36, 36, 36, 60, 36, 36, 36, 61, 36, 36, 43, 70, 86, ++ 85, 85, 89, 84, 89, 85, 42, 43, 43, 43, 88, 89, 43, 43, 36, 60, ++ 61, 93, 43, 43, 43, 43, 43, 43, 42, 85, 36, 36, 36, 36, 60, 36, ++ 36, 36, 36, 36, 36, 69, 70, 85, 86, 42, 79, 85, 89, 85, 86, 76, ++ 43, 43, 36, 93, 27, 27, 27, 94, 27, 27, 27, 27, 90, 36, 36, 36, ++ 56, 85, 61, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, 36, 36, 36, ++ 36, 61, 36, 36, 36, 36, 61, 43, 36, 36, 36, 60, 43, 79, 43, 88, ++ 85, 42, 79, 79, 85, 85, 85, 85, 43, 85, 63, 43, 43, 43, 43, 43, ++ 61, 36, 36, 36, 36, 36, 36, 36, 69, 36, 42, 42, 42, 79, 43, 95, ++ 36, 36, 36, 74, 42, 42, 42, 59, 7, 7, 7, 7, 7, 2, 43, 43, ++ 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 60, 36, 36, 60, 36, 36, ++ 36, 36, 61, 61, 36, 36, 36, 36, 69, 36, 42, 42, 42, 42, 70, 43, ++ 36, 36, 60, 80, 42, 42, 42, 79, 7, 7, 7, 7, 7, 43, 36, 36, ++ 76, 66, 2, 2, 2, 2, 2, 2, 2, 96, 96, 66, 42, 66, 66, 66, ++ 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 49, 49, 49, 4, 4, 85, ++ 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 43, ++ 56, 42, 42, 42, 42, 42, 42, 84, 42, 42, 59, 42, 36, 36, 69, 42, ++ 42, 42, 42, 42, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 79, 66, ++ 66, 66, 66, 75, 66, 66, 91, 66, 2, 2, 96, 66, 21, 63, 43, 43, ++ 36, 36, 36, 36, 36, 93, 86, 42, 84, 42, 42, 42, 86, 84, 86, 70, ++ 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 85, 42, 36, 36, 42, ++ 70, 85, 97, 93, 85, 85, 85, 36, 69, 42, 70, 36, 36, 36, 36, 36, ++ 36, 84, 86, 84, 85, 85, 86, 93, 7, 7, 7, 7, 7, 85, 86, 66, ++ 11, 11, 11, 47, 43, 43, 47, 43, 16, 16, 16, 16, 16, 52, 44, 16, ++ 36, 36, 36, 36, 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, ++ 60, 36, 36, 43, 36, 36, 36, 60, 60, 36, 36, 43, 36, 36, 36, 36, ++ 36, 36, 36, 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 56, 42, ++ 2, 2, 2, 2, 98, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, ++ 66, 66, 66, 66, 66, 43, 43, 43, 11, 11, 11, 43, 16, 16, 16, 43, ++ 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 71, ++ 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,102,103, 43, ++ 36, 36, 36, 36, 36, 62, 2,104,105, 36, 36, 36, 60, 43, 43, 43, ++ 36, 42, 84, 43, 43, 43, 43, 61, 36, 42,106, 63, 43, 43, 43, 43, ++ 36, 42, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 60, 36, ++ 60, 42, 43, 43, 43, 43, 43, 43, 36, 36, 42, 86, 42, 42, 42, 85, ++ 85, 85, 85, 84, 86, 42, 42, 42, 42, 42, 2, 87, 2, 65, 69, 43, ++ 7, 7, 7, 7, 7, 43, 43, 43, 27, 27, 27, 27, 27, 43, 43, 43, ++ 2, 2, 2,107, 2, 58, 42, 83, 36, 82, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 60, 43, 43, 43, 36, 36, 69, 70, 36, 36, 36, 36, ++ 36, 36, 36, 36, 69, 60, 43, 43, 36, 36, 36, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 60, 42, 84, 85, 86, 84, 85, 43, 43, ++ 85, 84, 85, 85, 86, 42, 43, 43, 91, 43, 2, 7, 7, 7, 7, 7, ++ 36, 36, 36, 36, 36, 36, 36, 43, 36, 36, 60, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 43, 43, 36, 36, 36, 36, 36, 43, 43, 43, ++ 7, 7, 7, 7, 7, 99, 43, 66, 66, 66, 66, 66, 66, 66, 66, 66, ++ 36, 36, 36, 69, 84, 86, 43, 2, 36, 36, 93, 84, 42, 42, 42, 79, ++ 84, 84, 86, 42, 42, 42, 84, 85, 85, 86, 42, 42, 42, 42, 79, 56, ++ 2, 2, 2, 87, 2, 2, 2, 43, 42, 42, 42, 42, 42, 42, 42,108, ++ 42, 42, 42, 42, 42, 42, 42, 43, 42, 42, 42, 42, 42, 42, 43, 43, ++ 42, 42, 97, 36, 36, 36, 36, 36, 36, 36, 84, 42, 42, 84, 84, 85, ++ 85, 84, 97, 36, 36, 36, 60, 2, 96, 66, 66, 66, 66, 49, 42, 42, ++ 42, 42, 66, 66, 66, 66, 21, 2, 42, 97, 36, 36, 36, 36, 36, 36, ++ 93, 42, 42, 85, 42, 86, 42, 36, 36, 36, 36, 84, 42, 85, 86, 86, ++ 42, 85, 43, 43, 43, 43, 2, 2, 36, 36, 85, 85, 85, 85, 42, 42, ++ 42, 42, 85, 42, 43, 92, 2, 2, 7, 7, 7, 7, 7, 43, 61, 36, ++ 36, 36, 36, 36, 39, 39, 39, 2, 16, 16, 16, 16, 34,109, 43, 43, ++ 11, 11, 11, 11, 11, 46, 47, 11, 2, 2, 2, 2, 43, 43, 43, 43, ++ 42, 59, 42, 42, 42, 42, 42, 42, 84, 42, 42, 42, 70, 36, 69, 36, ++ 36, 36, 70, 93, 42, 60, 43, 43, 16, 16, 16, 16, 16, 16, 39, 39, ++ 39, 39, 39, 39, 39, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, ++ 16, 16, 16, 16, 16,110, 39, 39, 32, 32, 32, 16, 16, 16, 16, 32, ++ 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 43, 11, 11, 11, 43, ++ 16, 16, 16, 16, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 16, 43, ++ 16, 16, 16, 16,111,111,111,111, 16, 16,109, 16, 11, 11,112,113, ++ 40, 16,109, 16, 11, 11,112, 40, 16, 16, 43, 16, 11, 11,114, 40, ++ 16, 16, 16, 16, 11, 11,115, 40, 43, 16,109, 16, 11, 11,112,116, ++ 117,117,117,117,117,118, 64, 64,119,119,119, 2,120,121,120,121, ++ 2, 2, 2, 2,122, 64, 64,123, 2, 2, 2, 2,124,125, 2,126, ++ 127, 2,128,129, 2, 2, 2, 2, 2, 9,127, 2, 2, 2, 2,130, ++ 64, 64,131, 64, 64, 64, 64, 64,132, 43, 27, 27, 27, 8,128,133, ++ 27, 27, 27, 27, 27, 8,128,103, 39, 39, 39, 39, 39, 39, 80, 43, ++ 20, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43, 43, ++ 42, 42, 42, 42, 42, 42,134, 50,108, 50,108, 42, 42, 42, 42, 42, ++ 79, 43, 43, 43, 43, 43, 43, 43, 66,135, 66,136, 66, 34, 11, 16, ++ 11, 32,136, 66, 48, 11, 11, 66, 66, 66,135,135,135, 11, 11,137, ++ 11, 11, 35, 36,138, 66, 16, 11, 8, 8, 48, 16, 16, 26, 66,139, ++ 27, 27, 27, 27, 27, 27, 27, 27,104,104,104,104,104,104,104,104, ++ 104,140,141,104,142, 66, 43, 43, 8, 8,143, 66, 66, 8, 66, 66, ++ 143, 26, 66,143, 66, 66, 66,143, 66, 66, 66, 66, 66, 66, 66, 8, ++ 66,143,143, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, 66, 66, 66, 66, 4, 4, 66, 66, ++ 8, 66, 66, 66,144,145, 66, 66, 66, 66, 66, 66, 66, 66,143, 66, ++ 66, 66, 66, 66, 66, 26, 8, 8, 8, 8, 66, 66, 66, 66, 66, 66, ++ 66, 66, 66, 66, 66, 66, 8, 8, 8, 66, 66, 66, 66, 66, 66, 66, ++ 66, 66, 66, 66, 66, 91, 43, 43, 27, 27, 27, 27, 27, 27, 66, 66, ++ 66, 66, 66, 66, 66, 27, 27, 27, 66, 66, 66, 26, 66, 66, 66, 66, ++ 26, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, ++ 66, 66, 66, 66, 66, 66, 66, 26, 66, 66, 66, 66, 4, 4, 4, 4, ++ 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, ++ 8, 8,128,146, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, ++ 8,128,147,147,147,147,147,147,147,147,147,147,146, 8, 8, 8, ++ 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, ++ 8, 8,143, 26, 8, 8,143, 66, 66, 66, 43, 66, 66, 66, 66, 66, ++ 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 39, 11, ++ 32, 32,139, 66, 66,136, 34,148, 42, 32, 43, 43, 92, 2, 98, 2, ++ 16, 16, 16,149, 43, 43,149, 43, 36, 36, 36, 36, 43, 43, 43, 51, ++ 63, 43, 43, 43, 43, 43, 43, 56, 36, 36, 36, 60, 43, 43, 43, 43, ++ 36, 36, 36, 60, 36, 36, 36, 60, 2,120,120, 2,124,125,120, 2, ++ 2, 2, 2, 6, 2,107,120, 2,120, 4, 4, 4, 4, 2, 2, 87, ++ 2, 2, 2, 2, 2,119, 2, 2,107,150, 2, 2, 2, 2, 2, 2, ++ 66, 2,151,147,147,147,152, 43, 66, 66, 66, 66, 66, 54, 66, 66, ++ 66, 66, 43, 43, 43, 43, 43, 43, 66, 66, 66, 43, 43, 43, 43, 43, ++ 1, 2,153,154, 4, 4, 4, 4, 4, 66, 4, 4, 4, 4,155,156, ++ 157,104,104,104,104, 42, 42, 85,158, 39, 39, 66,104,159, 62, 66, ++ 36, 36, 36, 60, 56,160,161, 68, 36, 36, 36, 36, 36, 62, 39, 68, ++ 43, 43, 61, 36, 36, 36, 36, 36, 66, 27, 27, 66, 66, 66, 66, 66, ++ 66, 66, 66, 43, 43, 43, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, ++ 27, 27, 27, 27, 27, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, ++ 162, 27, 27, 27, 27, 27, 27, 27, 36, 36, 82, 36, 36, 36, 36, 36, ++ 66, 66, 66, 91, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 2, ++ 7, 7, 7, 7, 7, 36, 43, 43, 32, 32, 32, 32, 32, 32, 32, 69, ++ 50,164, 42, 42, 42, 42, 42, 87, 32, 32, 32, 32, 32, 32, 39, 42, ++ 36, 36, 36,104,104,104,104,104, 42, 2, 2, 2, 43, 43, 43, 43, ++ 40, 40, 40,161, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, ++ 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, ++ 32, 32, 32, 32, 41,165, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, +- 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, +- 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, +- 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, +- 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, +- 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, +- 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, +- 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, +- 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, +- 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, +- 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, +- 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, +- 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, +- 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, +- 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, +- 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, +- 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, +- 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, +- 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, +- 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, +- 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, +- 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, +- 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, +- 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, +- 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, +- 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, +- 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, +- 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, +- 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, +- 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, +- 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, +- 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, +- 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, +- 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, +- 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, +- 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, +- 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, +- 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, +- 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, +- 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, +- 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, +- 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, +- 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, +- 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, +- 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, +- 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, +- 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, +- 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, +- 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, +- 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, +- 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, +- 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, +- 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, +- 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, +- 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, +- 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, +- 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, +- 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, +- 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, +- 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, +- 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, +- 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, +- 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, +- 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, +- 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, +- 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, +- 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, +- 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, +- 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, +- 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, +- 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, +- 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, +- 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, +- 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, +- 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, +- 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, +- 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, +- 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, +- 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, +- 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, +- 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, +- 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, +- 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, +- 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, +- 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, +- 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, +- 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, +- 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, +- 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, +- 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, +- 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, +- 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, +- 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, +- 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, +- 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, +- 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, +- 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, +- 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, +- 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, +- 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, +- 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, +- 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, +- 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, +- 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, +- 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, +- 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, +- 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, +- 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, +- 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, +- 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, +- 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, +- 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, +- 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, +- 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, +- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, +- 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, +- 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, +- 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, +- 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, +- 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, +- 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, +- 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, +- 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, +- 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, +- 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, +- 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, +- 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, +- 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, +- 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, +- 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, +- 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, +- 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, +- 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, +- 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, +- 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, +- 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, +- 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, +- 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, +- 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, +- 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, +- 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, +- 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, +- 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, +- 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, +- 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, +- 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, +- 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, +- 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, +- 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, +- 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, +- 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, +- 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, +- 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, +- 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, +- 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, +- 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, +- 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, +- 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, +- 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, +- 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, +- 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, +- 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, +- 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, +- 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, +- 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, +- 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, +- 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, +- 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, +- 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, +- 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, +- 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, +- 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, +- 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, +- 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, +- 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, +- 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, +- 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, +- 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, +- 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, +- 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, +- 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, +- 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, +- 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, +- 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, +- 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, +- 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, +- 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +- 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 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, ++ 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 46, 43, ++ 51, 39,166, 35, 39, 35, 36, 36, 36, 70, 36, 70, 36, 69, 36, 36, ++ 36, 93, 86, 84, 66, 66, 79, 43, 27, 27, 27, 66,167, 43, 43, 43, ++ 36, 36, 2, 2, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 85, 85, 85, 85, 85, 85, 85, 85, 42, 43, 43, 43, 43, 2, ++ 42, 36, 36, 36, 2, 71, 71, 69, 36, 36, 36, 42, 42, 42, 42, 2, ++ 36, 36, 36, 69, 42, 42, 42, 42, 42, 85, 43, 43, 43, 43, 43, 92, ++ 36, 69, 85, 42, 42, 85, 42, 85,106, 2, 2, 2, 2, 2, 2, 51, ++ 7, 7, 7, 7, 7, 43, 43, 2, 36, 36, 69, 68, 36, 36, 36, 36, ++ 7, 7, 7, 7, 7, 36, 36, 60, 36, 36, 36, 36, 69, 42, 42, 84, ++ 86, 84, 86, 79, 43, 43, 43, 43, 36, 69, 36, 36, 36, 36, 84, 43, ++ 7, 7, 7, 7, 7, 43, 2, 2, 68, 36, 36, 76, 66, 93, 84, 36, ++ 70, 42, 70, 69, 70, 36, 36, 42, 69, 60, 43, 43, 43, 43, 43, 43, ++ 43, 43, 43, 43, 43, 61, 82, 2, 36, 36, 36, 36, 36, 93, 42, 85, ++ 2, 82,168, 79, 43, 43, 43, 43, 61, 36, 36, 60, 61, 36, 36, 60, ++ 61, 36, 36, 60, 43, 43, 43, 43, 16, 16, 16, 16, 16,113, 39, 39, ++ 16, 16, 16, 16,110, 40, 43, 43, 36, 93, 86, 85, 84,106, 86, 43, ++ 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 43, 61, 36, 36, ++ 169,169,169,169,169,169,169,169,170,170,170,170,170,170,170,170, ++ 16, 16, 16,109, 43, 43, 43, 43, 43,149, 16, 16, 43, 43, 61, 70, ++ 36, 36, 36, 36,171, 36, 36, 36, 36, 36, 36, 60, 36, 36, 60, 60, ++ 36, 61, 60, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, ++ 40, 22, 66, 66, 66, 66, 66, 66, 66, 77, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 36,147, 66, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 66, 66, 66, 66, 36, 36, 36, 36, 36, 36,167, 66, ++ 2, 2, 2,151,129, 43, 43, 43, 6,172,173,147,147,147,147,147, ++ 147,147,129,151,129, 2,126,174, 2, 63, 2, 2,155,147,147,129, ++ 2,175, 8,176, 65, 2, 43, 43, 36, 36, 60, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 60, 78, 92, 2, 3, 2, 4, 5, 6, 2, ++ 16, 16, 16, 16, 16, 17, 18,128,129, 4, 2, 36, 36, 36, 36, 36, ++ 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, ++ 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 36, 36, 43, 36, 60, 43, ++ 20,177, 55,178, 26, 8,143, 91, 43, 43, 43, 43, 78, 64, 66, 43, ++ 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 60, 36, 61, ++ 2, 63, 43,179, 27, 27, 27, 27, 27, 27, 43, 54, 66, 66, 66, 66, ++ 104,104,142, 27, 90, 66, 66, 66, 66, 66, 66, 66, 66, 27, 66, 91, ++ 66, 66, 66, 66, 66, 66, 91, 43, 91, 43, 43, 43, 43, 43, 43, 43, ++ 66, 66, 66, 66, 66, 66, 49, 43,180, 27, 27, 27, 27, 27, 27, 27, ++ 27, 27, 27, 27, 27, 27, 43, 43, 27, 27, 43, 43, 43, 43, 61, 36, ++ 154, 36, 36, 36, 36,181, 43, 43, 36, 36, 36, 42, 42, 79, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 92, 36, 36, 43, 43, 36, 36, 36, 36, ++ 182,104,104, 43, 43, 43, 43, 43, 11, 11, 11, 11, 16, 16, 16, 16, ++ 11, 11, 43, 43, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 43, 43, ++ 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, 43, 92, ++ 11, 11, 11, 11, 11, 46, 11, 11, 11, 46, 11,149, 16, 16, 16, 16, ++ 16,149, 16, 16, 16, 16, 16, 16, 16,149, 16, 16, 16,149,109, 43, ++ 39, 39, 39, 51, 39, 39, 39, 39, 80, 39, 39, 39, 39, 80, 43, 43, ++ 36, 36, 36, 43, 60, 36, 36, 36, 36, 36, 36, 61, 60, 43, 60, 61, ++ 36, 36, 36, 92, 27, 27, 27, 27, 36, 36, 36, 76,162, 27, 27, 27, ++ 43, 43, 43,179, 27, 27, 27, 27, 36, 60, 36, 43, 43,179, 27, 27, ++ 36, 36, 36, 27, 27, 27, 43, 92, 36, 36, 36, 36, 36, 43, 43, 92, ++ 36, 36, 36, 36, 43, 43, 27, 36, 43, 27, 27, 27, 27, 27, 27, 27, ++ 69, 42, 56, 79, 43, 43, 42, 42, 36, 36, 61, 36, 61, 36, 36, 36, ++ 36, 36, 36, 43, 42, 79, 43, 56, 27, 27, 27, 27, 99, 43, 43, 43, ++ 2, 2, 2, 2, 63, 43, 43, 43, 36, 36, 36, 36, 36, 36,183, 30, ++ 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 77, 36, 36, 36, ++ 36, 36, 69, 79, 43,179, 27, 27, 2, 2, 2, 63, 43, 43, 43, 43, ++ 36, 36, 36, 43, 92, 2, 2, 2, 36, 36, 36, 43, 27, 27, 27, 27, ++ 36, 60, 43, 43, 27, 27, 27, 27, 36, 43, 43, 43, 92, 2, 63, 43, ++ 43, 43, 43, 43,179, 27, 27, 27, 11, 46, 43, 43, 43, 43, 43, 43, ++ 16,109, 43, 43, 43, 27, 27, 27, 36, 36, 42, 42, 43, 43, 43, 43, ++ 7, 7, 7, 7, 7, 36, 36, 68, 11, 11, 11, 43, 56, 42, 42,158, ++ 16, 16, 16, 43, 43, 43, 43, 8, 27, 27, 27, 27, 27, 27, 27, 99, ++ 36, 36, 36, 36, 36, 56,184, 43, 36, 43, 43, 43, 43, 43, 43, 43, ++ 43, 36, 82, 36, 43, 43, 43, 43, 96, 66, 66, 66, 91, 43, 43, 43, ++ 43, 43, 43, 43, 43, 42, 42, 42, 27, 27, 27, 94, 43, 43, 43, 43, ++ 180, 27, 30, 2, 2, 43, 43, 43, 36, 42, 42, 2, 2, 43, 43, 43, ++ 36, 36,183, 27, 27, 27, 43, 43, 86, 97, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 42, 59, 2, 2, 2, 43, ++ 27, 27, 27, 7, 7, 7, 7, 7, 70, 69, 70, 43, 43, 43, 43, 56, ++ 85, 86, 42, 84, 86, 59,185, 2, 2, 79, 43, 43, 43, 43, 78, 43, ++ 42, 70, 36, 36, 36, 36, 36, 36, 36, 36, 36, 69, 42, 42, 86, 42, ++ 42, 42, 79, 7, 7, 7, 7, 7, 2, 2, 93, 97, 43, 43, 43, 43, ++ 36, 69, 2, 60, 43, 43, 43, 43, 36, 93, 85, 42, 42, 42, 42, 84, ++ 97, 36, 62, 2, 58, 42, 59, 86, 7, 7, 7, 7, 7, 62, 62, 2, ++ 179, 27, 27, 27, 27, 27, 27, 27, 27, 27, 99, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 85, 86, 42, 85, 84, 42, 2, 2, 2, 70, ++ 69, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 60, 60, 36, 36, 61, ++ 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 62, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 69, 85, 86, 42, 42, 42, 79, 43, 43, ++ 42, 85, 61, 36, 36, 36, 60, 61, 60, 36, 61, 36, 36, 56, 70, 85, ++ 84, 85, 89, 88, 89, 88, 85, 43, 60, 43, 43, 88, 43, 43, 61, 36, ++ 36, 85, 43, 42, 42, 42, 79, 43, 42, 42, 79, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 61, 43, 60, 36, 36, 36, 61, 85, 86, 42, 42, ++ 79, 89, 88, 88, 85, 89, 85, 84, 70, 70, 2, 92, 63, 43, 43, 43, ++ 56, 79, 43, 43, 43, 43, 43, 43, 36, 36, 93, 85, 42, 42, 42, 42, ++ 85, 42, 84, 70, 36, 62, 2, 2, 7, 7, 7, 7, 7, 2, 92, 70, ++ 85, 86, 42, 42, 84, 84, 85, 86, 84, 42, 36, 71, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 93, 85, 42, 42, 43, 85, 85, 42, 86, ++ 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 43, ++ 85, 86, 42, 42, 42, 84, 86, 86, 59, 2, 60, 43, 43, 43, 43, 43, ++ 2, 2, 2, 2, 2, 2, 63, 43, 36, 36, 36, 36, 36, 69, 86, 85, ++ 42, 42, 42, 86, 62, 43, 43, 43, 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 56, 86, ++ 85, 42, 42, 86, 42, 42, 43, 43, 7, 7, 7, 7, 7, 27, 2, 96, ++ 42, 42, 42, 42, 86, 59, 43, 43, 27, 99, 43, 43, 43, 43, 43, 61, ++ 36, 36, 36, 60, 61, 43, 36, 36, 36, 36, 61, 60, 36, 36, 36, 36, ++ 85, 85, 85, 88, 89, 56, 84, 70, 97, 86, 2, 63, 43, 43, 43, 43, ++ 36, 36, 36, 36, 43, 36, 36, 36, 93, 85, 42, 42, 43, 42, 85, 85, ++ 70, 71, 89, 43, 43, 43, 43, 43, 69, 42, 42, 42, 42, 70, 36, 36, ++ 36, 69, 42, 42, 84, 69, 42, 59, 2, 2, 2, 58, 43, 43, 43, 43, ++ 69, 42, 42, 84, 86, 42, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, ++ 42, 42, 42, 84, 42, 2, 71, 2, 2, 63, 43, 43, 43, 43, 43, 43, ++ 2, 2, 2, 2, 2, 43, 43, 43, 84, 42, 84, 84, 43, 43, 43, 43, ++ 62, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 42, 42, 42, 86, ++ 62, 2, 2, 43, 43, 43, 43, 43, 2, 36, 36, 36, 36, 36, 36, 36, ++ 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 88, 42, 42, 42, ++ 84, 42, 86, 79, 43, 43, 43, 43, 36, 36, 36, 60, 36, 61, 36, 36, ++ 69, 42, 42, 79, 43, 79, 42, 56, 42, 42, 42, 69, 43, 43, 43, 43, ++ 36, 36, 36, 61, 60, 36, 36, 36, 36, 36, 36, 36, 36, 85, 85, 89, ++ 42, 88, 86, 86, 60, 43, 43, 43, 36, 36, 36, 36, 82, 36, 43, 43, ++ 36, 69, 84,106, 63, 43, 43, 43, 42, 93, 36, 36, 36, 36, 36, 36, ++ 36, 36, 85, 42, 42, 79, 43, 85, 84, 59, 2, 2, 2, 2, 2, 2, ++ 7, 7, 7, 7, 7, 79, 43, 43, 27, 27, 90, 66, 66, 66, 55, 20, ++ 167, 66, 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 43, 43, 92, ++ 104,104,104,104,104,104,104,181, 2, 2, 63, 43, 43, 43, 43, 43, ++ 62, 63, 43, 43, 43, 43, 43, 43, 64, 64, 64, 64, 64, 64, 64, 64, ++ 70, 36, 36, 69, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 85, 86, 42, ++ 42, 42, 59, 43, 43, 43, 43, 43, 42, 42, 42, 59, 2, 2, 66, 66, ++ 39, 39, 96, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7,179, 27, 27, ++ 27, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 61, 36, ++ 39, 68, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82,163, 2, ++ 27, 27, 27, 30, 2, 63, 43, 43, 11, 11, 11, 11, 46,149, 16, 16, ++ 16, 16, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 60, 43, 56, ++ 93, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 43, 43, 43, 56, 42, 73, 39, 39, 39, 39, 39, 39, ++ 39, 87, 79, 43, 43, 43, 43, 43, 85, 39,104,181, 43, 43, 43, 43, ++ 43, 43, 43, 43, 43, 43, 43, 61, 36, 60, 43, 43, 43, 43, 43, 43, ++ 39, 39, 51, 39, 39, 39, 51, 80, 43, 60, 43, 43, 43, 43, 43, 43, ++ 36, 60, 61, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 43, 43, 43, ++ 36, 36, 36, 36, 36, 43, 49, 59, 64, 64, 43, 43, 43, 43, 43, 43, ++ 7, 7, 7, 7, 7, 66, 91, 43, 66, 66, 43, 43, 43, 66, 66, 66, ++ 176, 43, 43, 43, 43, 43, 43, 43, 42, 42, 42, 79, 43, 43, 43, 43, ++ 66, 66, 66, 91, 54, 66, 66, 66, 66, 66,186, 86, 42, 66,186, 85, ++ 85,187, 64, 64, 64, 83, 42, 42, 42, 75, 49, 42, 42, 42, 66, 66, ++ 66, 66, 66, 66, 66, 42, 42, 66, 66, 42, 75, 43, 43, 43, 43, 43, ++ 27, 27, 43, 43, 43, 43, 43, 43, 11, 11, 11, 11, 11, 16, 16, 16, ++ 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, ++ 16, 16,109, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, ++ 16, 16, 16, 16, 16, 16, 46, 11, 43, 46, 47, 46, 47, 11, 46, 11, ++ 11, 11, 11, 16, 16,149,149, 16, 16, 16,149, 16, 16, 16, 16, 16, ++ 16, 16, 11, 47, 11, 46, 47, 11, 11, 11, 46, 11, 11, 11, 46, 16, ++ 16, 16, 16, 16, 11, 47, 11, 46, 11, 11, 46, 46, 43, 11, 11, 11, ++ 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, ++ 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 43, 11, 11, 11, 11, ++ 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, ++ 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, ++ 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, ++ 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, ++ 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 43, 7, ++ 42, 42, 42, 75, 66, 49, 42, 42, 42, 42, 42, 42, 42, 42, 75, 66, ++ 66, 66, 49, 66, 66, 66, 66, 66, 66, 66, 75, 21, 2, 2, 43, 43, ++ 43, 43, 43, 43, 43, 56, 42, 42, 16, 16, 16, 16, 16,138, 16, 16, ++ 16, 16, 16, 16, 16, 16, 16,109, 43, 43,149, 16, 16,109, 43, 43, ++ 42, 42, 42, 79, 42, 42, 42, 42, 42, 42, 42, 42, 79, 56, 42, 42, ++ 42, 56, 79, 42, 42, 79, 43, 43, 39, 39, 39, 39, 39, 39, 39, 43, ++ 43, 43, 43, 43, 43, 43, 43, 56, 42, 42, 42, 73, 39, 39, 39, 43, ++ 7, 7, 7, 7, 7, 43, 43, 76, 36, 36, 36, 36, 36, 36, 36, 79, ++ 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 43, 43, 95, ++ 36, 36, 36, 36, 36, 82, 42, 42,188, 7, 7, 7, 7,189, 43, 92, ++ 36, 69, 36, 70, 36, 36, 36, 42, 36, 36, 69, 43, 43, 43, 43, 82, ++ 36, 36, 36, 60, 36, 36, 61, 60, 36, 36, 60,179, 27, 27, 27, 27, ++ 16, 16, 42, 42, 42, 73, 43, 43, 27, 27, 27, 27, 27, 27,162, 27, ++ 190, 27, 99, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 27,162, ++ 27, 27, 27, 27, 27, 27, 27, 43, 36, 36, 61, 36, 36, 36, 36, 36, ++ 61, 60, 60, 61, 61, 36, 36, 36, 36, 60, 36, 36, 61, 61, 43, 43, ++ 43, 60, 43, 61, 61, 61, 61, 36, 61, 60, 60, 61, 61, 61, 61, 61, ++ 61, 60, 60, 61, 36, 60, 36, 36, 36, 60, 36, 36, 61, 36, 60, 60, ++ 36, 36, 36, 36, 36, 61, 36, 36, 61, 36, 61, 36, 36, 61, 36, 36, ++ 8, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 66, 43, 43, ++ 54, 66, 66, 66, 66, 66, 66, 66, 27, 27, 27, 27, 27, 27, 90, 66, ++ 66, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, 66, 66, 66, 66, 66, ++ 66, 91, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 91, 43, 43, 43, ++ 66, 43, 43, 43, 43, 43, 43, 43, 66, 66, 66, 66, 66, 25, 40, 40, ++ 66, 66, 66, 66, 91, 43, 66, 66, 66, 66, 66, 66, 43, 43, 43, 43, ++ 8, 8, 8, 8,176, 43, 43, 43, 66, 66, 66, 66, 66, 91, 43, 66, ++ 66, 66, 66, 91, 91, 43, 54, 66, 66, 66, 66, 66, 66, 66, 91, 54, ++ 66, 66, 66, 66, 66, 91, 43, 54, 66, 91, 66, 66, 66, 66, 66, 66, ++ 7, 7, 7, 7, 7, 91, 43, 43, 78, 43, 43, 43, 43, 43, 43, 43, ++ 170,170,170,170,170,170,170, 43,170,170,170,170,170,170,170, 0, ++ 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, ++ 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, ++ 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, ++ 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, ++ 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, ++ 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, ++ 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, ++ 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, ++ 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, ++ 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, ++ 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, ++ 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, ++ 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, ++ 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, ++ 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, ++ 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, ++ 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 12, 11, 9, 26, ++ 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, ++ 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, ++ 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, ++ 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, ++ 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, ++ 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, ++ 12, 17, 21, 1, 26, 10, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, ++ 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, ++ 0, 0, 0, 0, 15, 0, 16, 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, 17, 18, 19, 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, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 17, 18, 19, 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, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, ++ 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 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, 35, 0, ++ 0, 0, 0, 36, 0, 37, 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, 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, ++ 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, 44, 45, 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, 0, 0, 0, 0, 0, 0,118, ++ 0,119, 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, +@@ -3371,629 +3219,451 @@ _hb_ucd_u8[17524] = + 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, 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, +- 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, +- 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, 33, +- 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, ++ 0, 0, 57, 58, 0, 0, 0, 59, 60, 61, 62, 0, 0, 0, 0, 63, ++ 52, 0, 64, 65, 0, 0, 66, 0, 0, 0, 67, 68, 0, 0, 0, 69, ++ 0, 70, 71, 72, 73, 74, 1, 75, 0, 76, 77, 78, 0, 0, 79, 80, ++ 0, 0, 0, 81, 0, 0, 1, 1, 0, 0, 82, 0, 0, 83, 0, 0, ++ 0, 0, 79, 84, 0, 85, 0, 0, 0, 0, 0, 80, 86, 0, 87, 0, ++ 52, 0, 1, 80, 0, 0, 88, 0, 0, 89, 0, 0, 0, 0, 0, 90, ++ 57, 0, 0, 0, 0, 0, 0, 91, 92, 0, 0, 86, 0, 0, 33, 0, ++ 0, 93, 0, 0, 0, 0, 94, 0, 0, 0, 0, 49, 0, 0, 95, 0, ++ 0, 0, 0, 96, 97, 0, 0, 98, 0, 0, 99, 0, 0, 0,100, 0, ++ 0, 0,101, 0, 0, 0,102, 0, 0, 0, 0,103,104, 95, 0, 0, ++ 105, 0, 0, 0, 86, 0, 0,106, 0, 0, 0,107,108, 0, 0,109, ++ 110, 0, 0, 0, 0, 0, 0,111, 0, 0,112, 0, 0, 0, 0,113, ++ 33, 0,114,115,116, 57, 0, 0,117, 35, 0, 0,118, 0, 0, 0, ++ 119, 0, 0, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,122, ++ 90, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,123, 0, 0, 0, ++ 0,124, 0, 0,125, 0, 0, 0, 0,123, 0, 0,126, 0, 0, 0, ++ 0, 0, 81, 0, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,129, ++ 0,130, 0, 0, 0, 0,131,132,133, 0,134, 0,135, 0, 0, 0, ++ 136,137,138, 0, 79, 0, 0, 0, 0, 0, 35, 0, 0, 0,139, 0, ++ 0, 0,140, 0, 0, 0,141, 0, 0, 0,142,143, 0,144, 0, 0, ++ 145, 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, 1, 1, 1, 1, 41, 1, 21, 87, 0, ++ 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, 90, 9, 12, 4, ++ 91, 8, 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, 94, 1, 1, 1, ++ 1, 95, 96, 97, 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, ++ 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,102,103, ++ 0, 0,104, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, ++ 0, 0, 0, 62, 0, 0,105, 68, 61, 0, 0, 0, 78, 0, 0, 0, ++ 106,107, 58, 38, 81, 0, 0, 0, 0, 0, 0,108, 1, 14, 4, 12, ++ 84, 0, 0, 0, 0, 38, 90, 0, 0, 0, 0,109, 0, 0,110, 61, ++ 0,111, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, ++ 0, 0,112, 51, 0,112, 14, 52,113, 41, 0, 0, 62, 0, 0, 61, ++ 0, 0,114, 0, 90, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, ++ 0,114, 0, 0, 0, 0,115, 0, 0, 0, 78, 55, 0, 38, 1, 58, ++ 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,116, 0, 0, 0, ++ 55, 0, 0, 0, 0,116, 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, 92, 0, 0, 1, 90, 0, 0,117, 0, 0, 0, 0, 0, 0,118, ++ 0,119,120,121,122, 0,105, 4,123, 49, 23, 0, 0, 0, 38, 50, ++ 38, 58, 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, ++ 0, 0, 0, 1, 0, 0, 0,124, 0, 0, 0,113, 19, 59, 0, 38, ++ 0, 81, 0, 0, 4,123, 0, 0, 0, 1,125, 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,234, 0, 0, 9, 9, ++ 0, 0, 7, 0,230,230,230, 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, 33, 17, 49, 17, 17, 84, 97,135,145, ++ 26, 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,177, 0, 1, 2, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, +- 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, +- 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, +- 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, +- 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, +- 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, +- 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, +- 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, +- 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, +- 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, +- 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, +- 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, +- 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, +- 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, +- 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, +- 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, +- 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, +- 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, +- 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, +- 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, +- 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, +- 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, +- 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, +- 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, +- 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, +- 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, +- 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, +- 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, +- 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, +- 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, +- 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, +- 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, +- 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, +- 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 9, 16, 17, 18, 9, 19, 20, 21, 22, 23, 24, 5, 5, 5, 5, +- 5, 5, 5, 5, 5, 5, 25, 26, 27, 5, 28, 29, 5, 30, 31, 9, ++ 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, ++ 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, ++ 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, ++ 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, ++ 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, ++ 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, ++ 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, ++ 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, ++ 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, ++ 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, ++ 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, ++ 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, ++ 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, ++ 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, ++ 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, ++ 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, ++ 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, ++ 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, ++ 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, ++ 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, ++ 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, ++ 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, ++ 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, ++ 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, ++ 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, ++ 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, ++ 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, ++ 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, ++ 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, ++ 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, ++ 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, ++ 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, ++ 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, ++ 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, ++ 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 13, 13, ++ 24, 25, 26, 26, 26, 27, 13, 13, 13, 28, 29, 30, 13, 31, 32, 33, ++ 34, 35, 36, 37, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, 38, 7, 7, 39, 7, 40, 7, 7, ++ 7, 41, 13, 42, 7, 7, 43, 7, 7, 7, 44, 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, 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, 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, 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, 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, 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, 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, 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, ++ 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, ++ 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, ++ 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ++ 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, ++ 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 59, 63, 64, ++ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 59, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 78, 69, 69, 69, 69, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, ++ 81, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95, 95, 95, 69, 69, 96, 97, 98, 99, 99, 99, ++ 100,101,102,103,104,105,106,107,108,109, 95,110,111,112,113,114, ++ 115,116,117,117,118,119,120,121,122,123,124,125,126,127,128,129, ++ 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, ++ 95,146,147,148,149, 95,150,151,152,153,154,155,156,157,158,159, ++ 160,161, 95,162,163,164,165,165,165,165,165,165,165,166,167,165, ++ 168, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95,169,170,170,170,170,170,170,170,170,171,170, ++ 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, ++ 170,170,170,170,170,170,170,170,170,170,170,170,170,172,173,173, ++ 173,173,174, 95, 95, 95, 95, 95,175, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95,176,176,176,176,177,178,179,180, 95, 95, ++ 181, 95,182,183,184,185,186,186,186,186,186,186,186,186,186,186, ++ 186,186,186,186,186,186,186,186,186,186,186,186,187,187,187,188, ++ 189,190, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95,191,192,193,194,195,195,196, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,197,198, ++ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 59,199, ++ 59, 59, 59,200,201,202, 59,203,204,205,206,207,208, 95,209,210, ++ 211, 59, 59,212, 59,213,214,214,214,214,214,215, 95, 95, 95, 95, ++ 95, 95, 95, 95,216, 95,217,218,219, 95, 95,220, 95, 95, 95,221, ++ 95,222, 95,223, 95,224,225,226,227, 95, 95, 95, 95, 95,228,229, ++ 230, 95,231,232, 95, 95,233,234, 59,235,236, 95, 59, 59, 59, 59, ++ 59, 59, 59,237, 59,238,239,240, 59, 59,241,242, 59,243, 95, 95, ++ 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69,244, 69, 69,245, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, ++ 69, 69, 69,246, 69, 69, 69, 69, 69, 69, 69, 69, 69,247, 69, 69, ++ 69, 69,248, 95, 95, 95, 69, 69, 69, 69,249, 95, 95, 95, 95, 95, ++ 95, 95, 95, 95, 95, 95, 69, 69, 69, 69, 69, 69,250, 69, 69, 69, ++ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,251, 95, ++ 95, 95, 95, 95, 95, 95,252, 95,253,254, 0, 1, 2, 2, 0, 1, ++ 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, ++ 26, 26, 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, 2, 9, 9, 9, 55, 55, 55, 55, ++ 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, ++ 4, 4, 4, 4, 4, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, ++ 14, 2, 2, 2, 2, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, ++ 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, ++ 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, ++ 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 2, 2, 64, 64, ++ 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, ++ 2, 2, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 3, 3, ++ 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, ++ 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, ++ 5, 5, 5, 2, 2, 5, 5, 2, 5, 5, 5, 2, 5, 2, 2, 2, ++ 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, ++ 2, 5, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, ++ 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, ++ 2, 2, 2, 11, 2, 2, 11, 2, 11, 2, 2, 2, 11, 11, 2, 10, ++ 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, ++ 2, 2, 10, 2, 2, 2, 2, 2, 10, 10, 2, 21, 21, 21, 21, 21, ++ 21, 21, 21, 2, 2, 21, 21, 2, 21, 21, 21, 21, 2, 2, 21, 21, ++ 2, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, ++ 22, 2, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, ++ 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 23, 23, 23, 23, 23, 2, ++ 23, 23, 23, 23, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 2, ++ 23, 23, 2, 2, 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, ++ 16, 16, 16, 16, 2, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, ++ 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 2, 2, 20, 20, 2, 36, ++ 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, ++ 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 2, ++ 36, 2, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++ 24, 2, 2, 2, 2, 0, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, ++ 18, 2, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 2, 2, 18, 2, ++ 18, 2, 25, 25, 25, 25, 2, 25, 25, 25, 25, 2, 2, 2, 25, 2, ++ 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 33, 33, 33, 33, 8, 8, ++ 8, 8, 8, 8, 2, 8, 2, 8, 2, 2, 8, 8, 8, 0, 12, 12, ++ 12, 12, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, ++ 30, 2, 2, 30, 30, 30, 30, 2, 2, 2, 29, 29, 29, 29, 29, 29, ++ 2, 2, 28, 28, 28, 28, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, ++ 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 45, 45, ++ 45, 45, 45, 45, 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 0, ++ 0, 2, 43, 43, 43, 43, 46, 46, 46, 46, 46, 2, 46, 46, 31, 31, ++ 31, 31, 31, 31, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, ++ 32, 32, 32, 32, 2, 2, 32, 2, 2, 2, 32, 32, 32, 2, 28, 28, ++ 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, ++ 52, 52, 52, 52, 2, 2, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, ++ 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 2, 2, ++ 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, 2, 2, 91, 91, 91, ++ 2, 2, 1, 1, 2, 2, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, ++ 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, ++ 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 6, 6, 6, 2, 8, 8, ++ 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, ++ 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, ++ 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, ++ 19, 19, 19, 19, 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, ++ 9, 9, 1, 1, 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, ++ 0, 19, 0, 0, 0, 2, 19, 2, 2, 2, 0, 0, 2, 2, 1, 2, ++ 2, 2, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, ++ 0, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2, ++ 2, 61, 61, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, ++ 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, ++ 12, 12, 2, 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, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, ++ 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, ++ 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 2, 19, ++ 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 75, 75, ++ 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69, 69, 69, 69, 69, ++ 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2, 2, 2, 84, 84, ++ 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, ++ 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, 2, 2, 92, 92, ++ 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87, 87, 87, 87, 87, ++ 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87, 2, 2, 2, 2, ++ 2, 12, 19, 19, 19, 2, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14, ++ 2, 14, 14, 2, 14, 14, 3, 3, 0, 0, 1, 1, 6, 6, 3, 2, ++ 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 17, 17, 17, 17, ++ 0, 0, 2, 2, 12, 12, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, ++ 49, 2, 49, 49, 2, 49, 49, 49, 2, 2, 0, 2, 2, 2, 9, 2, ++ 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, ++ 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42, 42, 42, 41, 41, ++ 41, 41, 41, 41, 41, 2,118,118,118,118,118,118,118, 2, 53, 53, ++ 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, ++ 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 2, 2,135,135, ++ 135,135,106,106,106,106,104,104,104,104, 2, 2, 2,104,161,161, ++ 161,161,161,161,161, 2,161,161, 2,161,161, 2, 2, 2,170,170, ++ 170,170,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 19, ++ 2, 19, 19, 2, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, ++ 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, ++ 81, 81, 81, 81, 2, 81,120,120,120,120,116,116,116,116,116,116, ++ 116, 2, 2, 2, 2,116,128,128,128,128,128,128,128, 2,128,128, ++ 2, 2, 2, 2, 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, ++ 72, 72, 72, 72, 2, 2, 2, 2, 2, 72,173,173,173,173,173,173, ++ 2, 2, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2, 97, 97, 57, 57, ++ 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57, 2, 2, 57, 57, ++ 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88, 88, 88,117,117, ++ 117,117,112,112,112,112,112,112,112, 2, 2, 2, 2,112, 78, 78, ++ 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83, 83, 83, 83, 83, ++ 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122,122,122,122,122, ++ 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89, 89, 89, 89, 2, ++ 2, 2,130,130,130,130,130,130,130, 2, 2, 2,130,130,144,144, ++ 144,144,144,144, 2, 2,165,165,165,165,165,165, 2, 2, 2,165, ++ 165,165, 2, 2,165,165, 3, 3, 3, 2,156,156,156,156,156,156, ++ 2,156,156,156, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2,147,147, ++ 147,147,148,148,148,148,148,148, 2, 2,158,158,158,158,158,158, ++ 2, 2,153,153,153,153,149,149,149,149,149,149,149, 2, 94, 94, ++ 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, ++ 85, 85, 85, 85, 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, ++ 2, 2,101,101, 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111, ++ 111,111,111,111,111, 2,100,100,100,100,108,108,108,108,108,108, ++ 2,108,108,108, 2, 2,129,129,129,129,129,129,129, 2,129, 2, ++ 129,129,129,129, 2,129,129,129, 2, 2,109,109,109,109,109,109, ++ 109, 2,109,109, 2, 2,107,107,107,107, 2,107,107,107,107, 2, ++ 2,107,107, 2,107,107,107,107, 2, 1,107,107, 2, 2,107, 2, ++ 2, 2, 2, 2, 2,107, 2, 2,107,107,171,171,171,171,171,171, ++ 2,171, 2, 2,171, 2,171, 2,171, 2, 2,171, 2,171,171,171, ++ 171, 2,171, 2, 2, 2, 2,171,171, 2,137,137,137,137, 2,137, ++ 137,137,137,137, 2, 2,124,124,124,124,124,124, 2, 2,123,123, ++ 123,123,123,123, 2, 2,114,114,114,114,114, 2, 2, 2,114,114, ++ 2, 2,102,102,102,102,102,102, 2, 2,126,126,126,126,126,126, ++ 126, 2, 2,126,126,126,142,142,142,142,125,125,125,125,125,125, ++ 125, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, ++ 2, 2, 2,154,154, 2,154,154, 2,154,154, 2, 2,154,154,154, ++ 2, 2,150,150,150,150, 2, 2,150,150,150, 2, 2, 2,141,141, ++ 141,141,140,140,140,140,140,140,140, 2,121,121,121,121,121, 2, ++ 2, 2, 7, 7, 2, 2,169,169,169,169,169,169, 2, 2,133,133, ++ 133,133,133, 2,133,133,133,133,133, 2,133,133, 2, 2,133, 2, ++ 2, 2,134,134,134,134, 2, 2,134,134, 2,134,134,134,134,134, ++ 134, 2,138,138,138,138,138,138,138, 2,138,138, 2,138, 2, 2, ++ 138, 2,138,138, 2, 2,143,143,143,143,143,143, 2,143,143, 2, ++ 143,143,143,143,143, 2,143, 2, 2, 2,143,143, 2, 2,175,175, ++ 175,175,175,175, 2, 2,145,145,145,145,145, 2, 2, 2,163,163, ++ 163,163,163, 2,163,163,163,163,163, 2, 2, 2,163,163, 86, 2, ++ 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2, ++ 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80, ++ 2, 2, 80, 80, 80, 2,127,127,127,127,127,127,127, 2,166,166, ++ 166,166,166,166, 2, 2, 79, 2, 2, 2,115,115,115,115,115,115, ++ 115, 2,115,115, 2, 2, 2, 2,115,115,159,159,159,159,159,159, ++ 159, 2,159,159, 2, 2,103,103,103,103,103,103, 2, 2,119,119, ++ 119,119,119,119, 2, 2,119,119, 2,119, 2,119,119,119,167,167, ++ 167,167,167,167, 2, 2,146,146,146,146,146,146,146, 2,172,172, ++ 172,172,172, 2, 2,172, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, ++ 2, 99,136,139, 13, 13,155, 2, 2, 2, 13, 13, 13, 2,136,136, ++ 136,136,155,155,155,155,155,155, 2, 2, 2, 2, 2,155,136,136, ++ 136, 2, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, ++ 17, 2, 2, 2, 15, 2, 2, 17, 2, 2,139,139,139,139,105,105, ++ 105,105,105,105,105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, ++ 1, 2, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, ++ 0, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2,131,131, ++ 131,131, 2, 2, 2,131, 2,131,131,131, 56, 56, 56, 2, 56, 2, ++ 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, 2, 2, 2, ++ 2, 6,151,151,151,151,151, 2, 2, 2,151,151, 2, 2, 2, 2, ++ 151,151,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, ++ 2, 2, 2, 2, 2,152,164,164,164,164,164,164, 2, 2,168,168, ++ 168,168,168,168,168, 2, 2, 2, 2,168,174,174,174,174,174,174, ++ 174, 2,174,174, 2, 2, 2, 2,174,174, 2, 30, 30, 2,113,113, ++ 113,113,113, 2, 2,113,113,113,113, 2,132,132,132,132,132,132, ++ 2, 2, 2, 2,132,132, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, ++ 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, ++ 2, 3, 15, 0, 0, 2, 0, 2, 2, 0, 13, 2, 2, 2, 2, 0, ++ 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, 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, 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, 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, 32, 0, 0, 1, +- 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, +- 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 1, 29, 30, 31, +- 32, 32, 33, 32, 32, 32, 34, 32, 32, 35, 36, 37, 38, 39, 40, 41, +- 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 44, 44, 44, 44, +- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, +- 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 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, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, +- 56, 56, 56, 56, 56, 56, 56, 44, 57, 58, 59, 60, 61, 62, 63, 64, +- 65, 66, 67, 68, 69, 70, 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, 95, +- 95, 96, 97, 98, 56, 56, 56, 56, 56, 56, 56, 56, 56, 99,100,100, +- 100,100,101,100,100,100,100,100,100,100,100,100,100,100,100,100, +- 100,102,103,103,104, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,105, +- 56, 56, 56, 56, 56, 56,106,106,107,108, 56,109,110,111,112,112, +- 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +- 112,112,112,112,112,113,112,112,112,114,115,116, 56, 56, 56, 56, +- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,117,118,119, +- 120, 56, 56, 56, 56, 56, 56, 56, 56, 56,121, 56, 56, 56, 56, 56, +- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,122, 32,123,124,125,126, +- 127,128,129,130,131,132,133,133,134, 56, 56, 56, 56,135,136,137, +- 138, 56,139,140, 56,141,142,143, 56, 56,144,145,146, 56,147,148, +- 149, 32, 32, 32,150,151,152, 32,153,154, 56, 56, 56, 56, 44, 44, +- 44, 44, 44, 44,155, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +- 44, 44, 44, 44, 44,156,157, 44, 44, 44, 44, 44, 44, 44, 44, 44, +- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,158, 44, 44, 44, +- 44, 44, 44, 44, 44, 44, 44, 44, 44,159, 44, 44,160, 56, 56, 56, +- 56, 56, 56, 56, 56, 56, 44, 44,161, 56, 56, 56, 56, 56, 44, 44, +- 44,162, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, +- 44,163, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,164,165, +- 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 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, 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, 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, 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, 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, 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, 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, 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, ++ 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, ++ 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, 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, 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, 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, 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, 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, +- 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,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, 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, ++ 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,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,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, +- 0, 0, 0, 0, 0, 0, 0,173, 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, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,175, 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, 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,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, +- 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[9668] = ++static const uint16_t _hb_ucd_u16[10904]= + { + 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, +@@ -4020,23 +3690,23 @@ _hb_ucd_u16[9668] = + 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, + 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, +- 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, +- 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, +- 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, +- 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, +- 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, +- 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, +- 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, +- 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, +- 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, +- 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, +- 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, +- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, +- 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, +- 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, ++ 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 32, 216, 217, 140, ++ 218, 48, 48, 219, 220, 160, 221, 222, 223, 48, 224, 64, 48, 48, 225, 226, ++ 48, 48, 227, 228, 229, 64, 48, 230, 231, 9, 9, 232, 233, 234, 235, 236, ++ 11, 11, 237, 27, 27, 27, 238, 239, 11, 240, 27, 27, 32, 32, 32, 32, ++ 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, ++ 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, ++ 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, ++ 267, 268, 269, 270, 271, 272, 273, 273, 274, 275, 276, 209, 277, 278, 209, 279, ++ 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, ++ 281, 209, 282, 209, 209, 209, 209, 283, 209, 284, 280, 285, 209, 286, 287, 209, ++ 209, 209, 176, 140, 288, 140, 272, 272, 272, 289, 209, 209, 209, 209, 290, 272, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, ++ 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, ++ 209, 209, 209, 209, 209, 209, 295, 296, 272, 297, 209, 209, 298, 280, 299, 280, + 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, +- 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, ++ 280, 280, 280, 280, 280, 280, 280, 280, 300, 301, 280, 280, 280, 302, 280, 303, ++ 209, 209, 209, 280, 304, 209, 209, 305, 209, 209, 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, + 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, +@@ -4046,7 +3716,7 @@ _hb_ucd_u16[9668] = + 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 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, 151, 209, 209, 209, 338, 48, 48, 229, ++ 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 230, + 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, +@@ -4062,547 +3732,623 @@ _hb_ucd_u16[9668] = + 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, + 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, +- 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, ++ 422, 272, 272, 423, 273, 273, 273, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, + 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, 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, ++ 48, 454, 48, 455, 48, 207, 140, 140, 48, 48, 48, 456, 272, 457, 272, 272, + 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, + 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, + 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, +- 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, +- 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, +- 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, +- 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, +- 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, +- 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, +- 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, +- 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, +- 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, +- 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, +- 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, +- 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, +- 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, +- 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, +- 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, +- 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, ++ 140, 140, 140, 140, 140, 140, 272, 479, 48, 48, 480, 481, 482, 483, 140, 484, ++ 48, 464, 485, 48, 62, 486, 140, 48, 487, 140, 140, 48, 488, 140, 48, 313, ++ 489, 48, 48, 490, 491, 457, 492, 493, 223, 48, 48, 494, 495, 48, 196, 192, ++ 496, 48, 497, 498, 499, 48, 48, 500, 223, 48, 48, 501, 502, 503, 504, 505, ++ 48, 97, 506, 507, 508, 140, 140, 140, 509, 510, 511, 48, 48, 512, 513, 192, ++ 514, 83, 84, 515, 516, 517, 518, 519, 520, 48, 48, 521, 522, 523, 524, 140, ++ 48, 48, 48, 525, 526, 527, 481, 140, 48, 48, 48, 528, 529, 192, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 530, 531, 532, 533, 140, 140, ++ 48, 48, 48, 534, 535, 192, 536, 140, 48, 48, 537, 538, 192, 539, 540, 140, ++ 48, 541, 542, 543, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 48, 48, 506, 544, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 545, ++ 546, 547, 48, 548, 549, 192, 140, 140, 140, 140, 550, 48, 48, 551, 552, 140, ++ 553, 48, 48, 554, 555, 556, 48, 48, 557, 558, 559, 48, 48, 48, 48, 196, ++ 560, 140, 140, 140, 140, 140, 561, 140, 140, 140, 140, 140, 48, 48, 562, 192, ++ 84, 48, 530, 563, 564, 148, 175, 565, 48, 566, 567, 568, 140, 140, 140, 140, ++ 569, 48, 48, 570, 571, 192, 572, 48, 573, 574, 192, 48, 48, 575, 192, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 576, ++ 577, 115, 48, 578, 579, 580, 140, 140, 140, 140, 140, 100, 272, 581, 582, 583, + 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, ++ 273, 273, 273, 273, 273, 273, 584, 585, 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, 48, 48, 48, 48, 48, 48, 583, +- 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 586, ++ 48, 48, 48, 587, 588, 589, 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, +- 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, 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, 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, 606, +- 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, ++ 48, 590, 591, 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, 592, ++ 48, 48, 48, 593, 594, 595, 596, 597, 48, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 598, 48, 599, 192, 140, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 9, 9, 11, 11, 272, 600, 9, 601, 11, 602, 140, 140, ++ 48, 48, 48, 48, 603, 604, 605, 605, 606, 607, 140, 140, 140, 140, 608, 609, ++ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 610, ++ 48, 200, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 611, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 612, ++ 48, 48, 611, 613, 140, 614, 615, 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, +- 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 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, 322, 140, 140, 140, 140, +- 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, ++ 48, 48, 48, 48, 48, 48, 71, 151, 196, 616, 617, 140, 140, 140, 140, 140, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 618, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 619, 209, 427, 209, 620, ++ 32, 32, 216, 32, 621, 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, +- 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, +- 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, +- 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, +- 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, +- 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, +- 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 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, 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, 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, +- 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, +- 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, +- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, +- 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, 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, ++ 209, 209, 622, 209, 209, 209, 623, 624, 625, 209, 626, 209, 209, 209, 288, 140, ++ 209, 209, 209, 209, 627, 140, 140, 140, 140, 140, 140, 140, 272, 628, 272, 628, ++ 209, 209, 209, 209, 209, 338, 272, 461, 140, 140, 140, 140, 140, 140, 140, 140, ++ 9, 629, 11, 630, 631, 632, 242, 9, 633, 634, 635, 636, 637, 9, 629, 11, ++ 638, 639, 11, 640, 641, 642, 643, 9, 644, 11, 9, 629, 11, 630, 631, 11, ++ 242, 9, 633, 643, 9, 644, 11, 9, 629, 11, 645, 9, 646, 647, 648, 649, ++ 11, 650, 9, 651, 652, 653, 654, 11, 655, 9, 656, 11, 657, 539, 539, 539, ++ 32, 32, 32, 658, 32, 32, 659, 660, 661, 662, 45, 140, 140, 140, 140, 140, ++ 663, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 666, 667, 668, 27, 27, 27, 669, 140, 670, 140, 140, 140, 140, 140, 140, 140, ++ 48, 48, 151, 671, 672, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 673, 140, 48, 48, 674, 675, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 676, 192, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 590, 677, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 200, 678, 679, ++ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 680, 200, ++ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 681, 621, 140, 140, ++ 9, 9, 633, 11, 682, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 140, 140, 140, 140, 140, 140, 140, 504, 272, 272, 683, 684, 140, 140, 140, 140, ++ 504, 272, 685, 686, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 687, 48, 688, 689, 690, 691, 692, 693, 694, 206, 695, 206, 140, 140, 140, 696, ++ 209, 209, 697, 209, 209, 209, 209, 209, 209, 322, 333, 698, 698, 698, 209, 323, ++ 699, 209, 209, 209, 209, 209, 209, 209, 209, 209, 700, 140, 140, 140, 701, 209, ++ 702, 209, 209, 697, 703, 704, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 705, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 706, 426, 426, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 176, 697, 427, ++ 697, 209, 209, 209, 707, 176, 209, 209, 707, 209, 700, 697, 704, 708, 140, 140, ++ 209, 209, 209, 209, 209, 707, 700, 426, 709, 209, 209, 209, 710, 711, 712, 703, ++ 209, 209, 209, 209, 209, 209, 209, 209, 209, 713, 209, 209, 209, 209, 209, 714, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, +- 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, 481, 48, 48, 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, 100, 48, + 48, 48, 48, 48, 48, 204, 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, + 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, 140, 140, 140, 140, 140, +- 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, ++ 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, 140, 140, ++ 715, 140, 587, 587, 587, 587, 587, 587, 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, 705, +- 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, +- 0, 0, 1, 1, 0, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, +- 4, 4, 4, 4, 4, 5, 0, 6, 7, 7, 7, 8, 9, 10, 11, 12, +- 13, 13, 13, 13, 14, 13, 13, 13, 13, 15, 16, 17, 18, 19, 20, 21, +- 22, 23, 24, 25, 23, 23, 26, 23, 27, 28, 29, 23, 30, 31, 32, 33, +- 34, 35, 36, 37, 38, 23, 23, 39, 40, 40, 41, 42, 43, 44, 45, 46, +- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, +- 79, 80, 81, 82, 83, 84, 85, 82, 86, 86, 87, 88, 89, 90, 91, 82, +- 92, 92, 92, 92, 92, 93, 94, 95, 96, 96, 96, 96, 96, 96, 96, 96, +- 97, 97, 98, 97, 99, 100, 101, 97, 102, 97, 103, 104, 105, 106, 106, 107, +- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, +- 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 120, 122, 108, 123, +- 124, 125, 126, 127, 128, 129, 130, 116, 131, 132, 133, 134, 135, 136, 137, 82, +- 138, 138, 139, 138, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, +- 4, 151, 152, 153, 4, 154, 7, 7, 155, 11, 156, 157, 11, 158, 159, 160, +- 161, 0, 0, 162, 163, 0, 164, 165, 0, 166, 167, 4, 168, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, +- 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 172, 173, 0, 0, 0, +- 174, 174, 174, 4, 175, 175, 175, 176, 93, 177, 178, 179, 180, 181, 181, 13, +- 0, 0, 182, 82, 183, 184, 184, 185, 184, 184, 184, 184, 184, 184, 186, 187, +- 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 96, 96, 198, 199, 0, 200, +- 201, 0, 0, 202, 0, 0, 203, 204, 194, 194, 205, 0, 0, 0, 0, 0, +- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 0, 0, +- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 206, 208, 209, +- 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 13, 13, 13, 212, 212, 213, +- 0, 214, 4, 4, 215, 4, 216, 217, 218, 219, 220, 221, 222, 222, 223, 40, +- 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 92, 234, 234, 235, 236, +- 237, 238, 239, 240, 106, 106, 241, 242, 96, 96, 96, 96, 96, 243, 244, 245, +- 82, 82, 82, 82, 82, 82, 82, 82, 184, 184, 184, 246, 184, 184, 247, 82, +- 248, 249, 250, 23, 23, 23, 251, 23, 23, 23, 23, 23, 23, 23, 23, 23, +- 23, 252, 23, 23, 253, 23, 254, 255, 256, 257, 258, 259, 23, 23, 23, 260, +- 261, 1, 1, 262, 263, 201, 264, 265, 266, 267, 268, 82, 269, 269, 269, 270, +- 271, 272, 11, 11, 273, 274, 187, 275, 82, 82, 82, 82, 276, 277, 278, 279, +- 280, 281, 282, 283, 284, 285, 286, 82, 287, 287, 288, 289, 290, 291, 292, 293, +- 294, 295, 296, 297, 298, 299, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, +- 302, 303, 304, 305, 306, 307, 82, 82, 308, 309, 310, 311, 312, 313, 82, 314, +- 315, 316, 82, 82, 317, 318, 319, 320, 321, 322, 323, 324, 325, 82, 326, 327, +- 328, 329, 330, 331, 332, 333, 82, 82, 334, 334, 335, 82, 336, 337, 336, 338, +- 339, 340, 341, 342, 343, 82, 82, 82, 82, 82, 82, 344, 345, 346, 347, 348, +- 349, 350, 351, 352, 353, 354, 355, 356, 357, 357, 358, 359, 360, 360, 361, 362, +- 363, 364, 365, 366, 367, 367, 367, 368, 369, 370, 371, 82, 372, 373, 374, 375, +- 376, 377, 378, 379, 380, 381, 382, 383, 384, 384, 385, 386, 387, 387, 388, 82, +- 82, 82, 82, 82, 389, 390, 391, 82, 392, 392, 393, 394, 395, 396, 397, 398, +- 399, 400, 401, 82, 82, 82, 82, 82, 402, 403, 82, 82, 82, 404, 404, 405, +- 406, 407, 408, 82, 82, 409, 410, 411, 412, 412, 413, 414, 414, 415, 416, 417, +- 418, 82, 82, 82, 82, 82, 419, 420, 421, 422, 423, 424, 425, 426, 82, 82, +- 427, 428, 429, 430, 431, 432, 82, 82, 82, 82, 82, 82, 82, 82, 82, 433, +- 434, 435, 436, 82, 82, 437, 438, 439, 440, 440, 440, 440, 440, 440, 440, 440, +- 440, 440, 440, 440, 441, 82, 82, 82, 440, 440, 440, 442, 440, 440, 440, 440, +- 440, 440, 443, 82, 82, 82, 82, 82, 82, 82, 82, 82, 444, 445, 445, 446, +- 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 447, 447, 447, 447, 447, +- 447, 447, 447, 447, 447, 447, 447, 449, 450, 450, 450, 450, 450, 450, 450, 450, +- 450, 450, 451, 82, 82, 82, 82, 82, 452, 453, 82, 82, 82, 82, 82, 82, +- 212, 212, 212, 212, 212, 212, 212, 212, 212, 454, 455, 456, 457, 458, 459, 460, +- 461, 461, 462, 463, 464, 82, 82, 82, 82, 82, 465, 466, 82, 82, 82, 82, +- 82, 82, 467, 467, 468, 82, 82, 82, 469, 469, 470, 469, 471, 82, 82, 472, +- 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, +- 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 477, +- 478, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 479, +- 480, 191, 191, 191, 191, 191, 191, 191, 191, 481, 482, 483, 484, 484, 484, 484, +- 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 486, 487, 488, 489, 82, 82, +- 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 491, 82, 82, +- 7, 492, 493, 0, 0, 0, 489, 82, 0, 0, 0, 0, 0, 0, 0, 494, +- 0, 495, 0, 496, 497, 498, 0, 170, 11, 11, 499, 82, 82, 82, 491, 491, +- 0, 0, 500, 501, 82, 82, 82, 82, 0, 0, 502, 0, 503, 504, 505, 0, +- 506, 507, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, +- 0, 0, 0, 0, 0, 0, 510, 0, 511, 511, 511, 511, 511, 511, 511, 511, +- 511, 511, 511, 511, 512, 513, 82, 82, 514, 515, 82, 82, 82, 82, 82, 82, +- 516, 517, 13, 518, 519, 82, 82, 82, 520, 521, 522, 82, 82, 82, 82, 82, +- 82, 82, 82, 82, 523, 524, 525, 526, 82, 82, 82, 82, 82, 82, 527, 528, +- 82, 82, 82, 82, 82, 82, 529, 530, 82, 82, 82, 82, 82, 82, 82, 531, +- 532, 532, 532, 532, 532, 532, 533, 82, 534, 534, 535, 82, 82, 82, 82, 82, +- 82, 82, 82, 536, 0, 537, 82, 82, 261, 182, 82, 82, 82, 82, 82, 82, +- 538, 539, 540, 541, 542, 543, 82, 544, 0, 545, 0, 0, 491, 546, 547, 494, +- 0, 0, 0, 0, 0, 548, 82, 549, 550, 551, 552, 553, 82, 82, 82, 82, +- 0, 0, 0, 0, 0, 0, 554, 555, 0, 0, 0, 556, 0, 0, 490, 557, +- 545, 0, 558, 0, 559, 560, 561, 82, 0, 0, 491, 562, 563, 0, 564, 565, +- 0, 0, 0, 0, 258, 0, 0, 490, 184, 184, 184, 184, 184, 184, 184, 82, +- 184, 247, 184, 184, 184, 184, 184, 184, 566, 184, 184, 184, 184, 184, 184, 184, +- 184, 184, 184, 184, 184, 567, 184, 184, 184, 184, 184, 184, 184, 184, 184, 568, +- 184, 184, 566, 82, 82, 82, 82, 82, 566, 82, 82, 82, 82, 82, 82, 82, +- 184, 184, 569, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 570, 82, 82, +- 571, 0, 0, 0, 82, 82, 82, 82, 7, 7, 7, 7, 7, 7, 7, 572, +- 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 4, 2, 2, 5, 2, +- 2, 2, 2, 2, 2, 2, 2, 6, 7, 8, 0, 0, 9, 9, 9, 9, +- 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, +- 16, 17, 14, 14, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 20, 21, +- 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, +- 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, +- 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 29, 37, 38, 37, 37, +- 37, 37, 37, 37, 37, 39, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, +- 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, +- 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 52, 31, 31, 31, +- 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, +- 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, +- 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, +- 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, +- 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, +- 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, +- 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, +- 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, +- 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, +- 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, +- 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, +- 153, 152, 152, 154, 155, 156, 152, 157, 158, 158, 158, 158, 158, 159, 158, 158, +- 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, +- 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, +- 169, 169, 169, 169, 170, 170, 170, 170, 170, 171, 172, 171, 170, 171, 170, 170, +- 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 171, 170, 170, 170, 170, 173, +- 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 177, 177, +- 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, 181, 183, +- 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, +- 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, +- 198, 198, 198, 198, 198, 198, 198, 200, 198, 201, 178, 178, 178, 178, 202, 26, +- 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, +- 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 214, 214, 214, 215, +- 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, +- 216, 220, 9, 9, 9, 221, 26, 26, 222, 222, 222, 222, 222, 223, 222, 222, +- 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, 228, 228, 228, 228, +- 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, 18, 232, 165, 165, +- 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, 239, 240, 2, 2, +- 2, 2, 2, 241, 242, 243, 2, 244, 2, 2, 2, 245, 14, 14, 246, 246, +- 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 248, 14, 248, 14, 249, 250, +- 14, 14, 251, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, +- 259, 26, 9, 9, 9, 9, 260, 26, 261, 262, 4, 0, 0, 263, 0, 0, +- 2, 264, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 267, 267, 267, 267, +- 0, 0, 268, 0, 0, 0, 269, 0, 270, 270, 270, 270, 17, 17, 17, 17, +- 17, 17, 271, 272, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, +- 170, 170, 172, 26, 172, 172, 172, 172, 0, 0, 0, 276, 277, 277, 277, 278, +- 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 280, 26, 26, 26, 0, 0, +- 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, +- 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, +- 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, +- 276, 296, 290, 290, 169, 169, 169, 295, 169, 169, 169, 297, 0, 0, 290, 290, +- 290, 290, 290, 298, 290, 290, 290, 0, 299, 299, 299, 299, 299, 300, 299, 299, +- 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 304, 26, 26, +- 305, 305, 305, 305, 305, 305, 305, 26, 306, 2, 2, 2, 2, 307, 2, 2, +- 2, 308, 309, 258, 26, 26, 310, 2, 311, 311, 311, 311, 311, 312, 0, 265, +- 313, 313, 313, 313, 313, 313, 313, 26, 314, 314, 314, 314, 315, 316, 314, 317, +- 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, +- 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, 328, 328, 328, 328, +- 328, 328, 329, 26, 328, 330, 328, 331, 332, 332, 332, 332, 333, 26, 26, 334, +- 335, 335, 336, 26, 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, +- 339, 340, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, 343, 26, 169, 169, +- 295, 344, 169, 169, 169, 169, 169, 343, 277, 280, 277, 277, 277, 277, 277, 345, +- 346, 26, 347, 348, 25, 25, 349, 350, 351, 25, 31, 31, 352, 26, 353, 31, +- 31, 31, 31, 354, 31, 31, 355, 31, 31, 356, 26, 26, 26, 26, 31, 31, +- 9, 9, 0, 265, 9, 357, 0, 0, 0, 0, 358, 0, 257, 359, 360, 31, +- 31, 31, 31, 361, 362, 0, 0, 0, 363, 290, 289, 290, 290, 290, 290, 364, +- 365, 365, 365, 366, 257, 257, 26, 367, 368, 369, 368, 368, 370, 368, 368, 371, +- 368, 372, 368, 372, 368, 368, 368, 368, 368, 368, 368, 373, 374, 0, 0, 0, +- 0, 0, 375, 0, 14, 252, 0, 376, 377, 26, 26, 26, 0, 0, 0, 378, +- 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, +- 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, +- 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 396, 396, 396, 396, +- 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, 398, 399, 398, 400, 401, 401, +- 401, 401, 402, 401, 401, 401, 401, 402, 403, 403, 403, 403, 403, 26, 404, 404, +- 404, 404, 404, 404, 405, 406, 407, 408, 407, 408, 409, 407, 410, 407, 410, 411, +- 412, 412, 412, 412, 412, 412, 413, 26, 414, 414, 414, 414, 414, 414, 415, 26, +- 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, +- 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, +- 428, 428, 428, 429, 430, 428, 26, 26, 431, 431, 432, 433, 434, 434, 434, 435, +- 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, 439, 439, 441, 439, +- 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, 446, 449, 446, 449, +- 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 454, 453, 26, +- 455, 455, 455, 455, 455, 455, 456, 457, 458, 458, 459, 458, 460, 460, 461, 460, +- 462, 462, 463, 464, 26, 465, 26, 26, 466, 466, 466, 466, 466, 467, 26, 26, +- 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 469, 470, 471, 471, 471, 471, +- 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, 474, 476, 26, 26, +- 31, 31, 31, 50, 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, +- 26, 26, 26, 481, 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, +- 26, 26, 485, 485, 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, +- 489, 489, 490, 26, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, +- 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, 501, 501, 501, 501, +- 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, 505, 505, 505, 505, +- 506, 137, 507, 26, 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, +- 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, +- 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, +- 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, +- 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, 541, 541, 541, 541, +- 541, 26, 541, 542, 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, +- 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, 549, 549, 549, 549, +- 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, 552, 552, 552, 553, +- 552, 554, 552, 552, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 557, +- 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, +- 561, 26, 564, 567, 568, 569, 568, 568, 568, 568, 568, 569, 570, 26, 26, 26, +- 571, 571, 571, 571, 571, 26, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, +- 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 577, 577, 577, 577, +- 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, 582, 26, 579, 579, +- 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, 588, 589, 590, 590, +- 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, 595, 596, 597, 598, +- 595, 599, 26, 26, 600, 600, 600, 601, 602, 602, 603, 602, 602, 602, 602, 604, +- 602, 602, 602, 605, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, +- 609, 609, 609, 609, 609, 609, 609, 610, 609, 611, 612, 26, 613, 26, 26, 26, +- 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, 616, 616, 616, 616, +- 616, 616, 617, 26, 616, 616, 616, 618, 619, 619, 619, 619, 620, 26, 26, 26, +- 621, 621, 621, 621, 621, 621, 621, 622, 305, 305, 305, 623, 624, 624, 624, 625, +- 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, 627, 629, 630, 630, +- 630, 631, 631, 26, 632, 632, 632, 632, 633, 26, 632, 634, 634, 632, 632, 635, +- 632, 632, 26, 26, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, +- 638, 638, 638, 639, 640, 640, 640, 640, 640, 641, 640, 640, 640, 642, 640, 640, +- 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, +- 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 649, 650, +- 651, 286, 286, 286, 652, 26, 653, 26, 26, 26, 654, 26, 655, 26, 656, 656, +- 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 659, 658, 660, +- 658, 661, 658, 662, 359, 26, 26, 26, 0, 0, 0, 265, 0, 0, 359, 26, +- 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 276, 26, 257, 362, 0, 0, +- 664, 665, 0, 666, 667, 668, 0, 0, 0, 669, 0, 0, 246, 26, 26, 26, +- 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 254, +- 670, 671, 0, 672, 673, 0, 0, 0, 269, 674, 254, 254, 0, 0, 0, 675, +- 676, 677, 678, 0, 276, 0, 0, 0, 0, 268, 0, 0, 679, 679, 679, 679, +- 679, 680, 26, 681, 682, 679, 26, 26, 2, 2, 2, 346, 683, 419, 26, 26, +- 684, 270, 270, 685, 686, 687, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, +- 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 694, 694, +- 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, 26, 26, 698, 698, +- 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, 172, 702, 170, 172, +- 703, 703, 703, 703, 704, 703, 705, 26, 706, 706, 706, 706, 706, 707, 706, 708, +- 26, 26, 362, 0, 0, 0, 376, 26, 709, 31, 31, 31, 710, 711, 712, 713, +- 714, 715, 710, 716, 710, 712, 712, 717, 31, 718, 31, 719, 720, 718, 31, 719, +- 26, 26, 721, 26, 0, 359, 0, 0, 0, 257, 362, 0, 362, 0, 362, 0, +- 0, 276, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, +- 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, +- 0, 0, 257, 725, 0, 359, 259, 26, 0, 26, 0, 265, 0, 26, 0, 0, +- 0, 276, 0, 359, 265, 26, 26, 26, 0, 276, 0, 376, 0, 726, 0, 0, +- 257, 722, 0, 727, 0, 265, 0, 259, 277, 277, 277, 280, 345, 26, 277, 277, +- 728, 26, 277, 277, 277, 729, 277, 277, 277, 277, 26, 26, 730, 26, 26, 26, +- 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976, +- 1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082, +- 1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161, +- 1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269, +- 1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, +- 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, +- 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191, +- 1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025, +- 1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0, +- 1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252, +- 1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271, +- 1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120, +- 1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 716, ++ 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 717, ++ 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, ++ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, ++ 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, ++ 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, ++ 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, ++ 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, ++ 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, ++ 39, 39, 40, 41, 42, 43, 44, 27, 27, 45, 27, 27, 27, 27, 46, 27, ++ 47, 47, 47, 47, 47, 48, 49, 47, 50, 51, 52, 53, 54, 55, 56, 57, ++ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 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, 104, 105, ++ 106, 107, 108, 108, 109, 110, 111, 108, 112, 113, 114, 115, 116, 117, 118, 119, ++ 120, 121, 121, 122, 121, 123, 124, 124, 125, 126, 127, 128, 129, 130, 124, 124, ++ 131, 131, 131, 131, 132, 131, 133, 134, 131, 132, 131, 135, 135, 136, 124, 124, ++ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 138, 139, 138, 138, 140, ++ 141, 141, 141, 141, 141, 141, 141, 141, 142, 142, 142, 142, 143, 144, 142, 142, ++ 143, 142, 142, 145, 146, 147, 142, 142, 142, 146, 142, 142, 142, 148, 142, 149, ++ 142, 150, 151, 151, 151, 151, 151, 152, 153, 153, 153, 153, 153, 153, 153, 153, ++ 154, 155, 156, 156, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, ++ 167, 167, 167, 167, 167, 168, 169, 169, 170, 171, 172, 172, 172, 172, 172, 173, ++ 172, 172, 174, 153, 153, 153, 153, 175, 176, 177, 178, 178, 179, 180, 181, 182, ++ 183, 183, 184, 183, 185, 186, 167, 167, 187, 188, 189, 189, 189, 190, 189, 191, ++ 192, 192, 193, 8, 8, 194, 195, 124, 196, 196, 196, 196, 197, 196, 196, 196, ++ 198, 198, 198, 198, 199, 199, 199, 200, 201, 201, 201, 202, 203, 204, 204, 204, ++ 205, 138, 138, 206, 207, 208, 209, 210, 4, 4, 211, 4, 4, 212, 213, 214, ++ 4, 4, 4, 215, 8, 8, 8, 8, 11, 216, 11, 11, 216, 217, 11, 218, ++ 11, 11, 11, 219, 219, 220, 11, 221, 222, 0, 0, 0, 0, 0, 223, 224, ++ 225, 226, 0, 0, 227, 8, 8, 228, 0, 0, 229, 230, 231, 0, 4, 4, ++ 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 233, 124, 234, 124, 0, 0, 235, 235, 235, 235, 235, 235, 235, 235, ++ 0, 0, 0, 0, 0, 0, 0, 236, 237, 237, 237, 237, 237, 237, 4, 4, ++ 238, 238, 238, 238, 238, 238, 238, 239, 138, 138, 139, 240, 240, 240, 241, 242, ++ 142, 243, 244, 244, 244, 244, 14, 14, 0, 0, 0, 0, 0, 245, 124, 124, ++ 246, 247, 246, 246, 246, 246, 246, 248, 246, 246, 246, 246, 246, 246, 246, 246, ++ 246, 246, 246, 246, 246, 249, 124, 0, 250, 0, 251, 252, 253, 254, 254, 254, ++ 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 261, 141, 141, 141, 141, ++ 262, 0, 260, 260, 0, 0, 263, 257, 141, 262, 0, 0, 0, 0, 141, 264, ++ 0, 0, 0, 0, 0, 257, 257, 265, 257, 257, 257, 257, 257, 266, 0, 0, ++ 246, 246, 246, 246, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, ++ 268, 267, 267, 267, 269, 270, 270, 270, 271, 271, 271, 271, 271, 271, 271, 271, ++ 271, 271, 272, 124, 14, 14, 14, 14, 14, 14, 273, 273, 273, 273, 273, 274, ++ 0, 0, 275, 4, 4, 4, 4, 4, 276, 4, 4, 4, 4, 226, 124, 277, ++ 278, 278, 279, 233, 280, 280, 280, 281, 282, 282, 282, 282, 283, 284, 47, 47, ++ 285, 285, 286, 287, 287, 288, 141, 289, 290, 290, 290, 290, 291, 292, 137, 293, ++ 294, 294, 294, 295, 296, 297, 137, 137, 298, 298, 298, 298, 299, 300, 301, 302, ++ 303, 304, 244, 4, 4, 305, 306, 151, 151, 151, 151, 151, 301, 301, 307, 308, ++ 141, 141, 309, 141, 310, 141, 141, 311, 124, 124, 124, 124, 124, 124, 124, 124, ++ 246, 246, 246, 246, 246, 246, 312, 246, 246, 246, 246, 246, 246, 313, 124, 124, ++ 314, 315, 21, 316, 317, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, ++ 27, 27, 27, 318, 27, 27, 27, 27, 27, 27, 27, 27, 27, 124, 124, 27, ++ 8, 233, 319, 0, 0, 320, 321, 322, 27, 27, 27, 27, 27, 27, 27, 323, ++ 324, 0, 1, 2, 1, 2, 325, 256, 257, 326, 141, 262, 327, 328, 329, 330, ++ 331, 332, 333, 334, 335, 335, 124, 124, 332, 332, 332, 332, 332, 332, 332, 336, ++ 337, 0, 0, 338, 11, 11, 11, 11, 339, 340, 341, 124, 124, 0, 0, 342, ++ 343, 344, 345, 345, 345, 346, 347, 348, 349, 349, 350, 351, 352, 353, 353, 354, ++ 355, 356, 357, 357, 358, 359, 124, 124, 360, 360, 360, 360, 360, 361, 361, 361, ++ 362, 363, 364, 365, 365, 366, 365, 367, 368, 368, 369, 370, 370, 370, 371, 372, ++ 372, 373, 374, 375, 376, 376, 376, 377, 378, 378, 378, 378, 378, 378, 378, 378, ++ 378, 378, 378, 379, 378, 380, 381, 124, 382, 4, 4, 383, 124, 124, 124, 124, ++ 384, 385, 385, 386, 387, 388, 389, 389, 390, 391, 392, 124, 124, 124, 393, 394, ++ 395, 396, 397, 398, 399, 400, 124, 124, 401, 401, 402, 403, 402, 404, 402, 402, ++ 405, 406, 407, 408, 409, 409, 410, 410, 411, 411, 124, 124, 412, 412, 413, 414, ++ 415, 415, 415, 416, 417, 418, 419, 420, 421, 422, 423, 124, 124, 124, 124, 124, ++ 424, 424, 424, 424, 425, 124, 124, 124, 426, 426, 426, 427, 426, 426, 426, 428, ++ 429, 429, 430, 431, 432, 432, 433, 432, 434, 124, 124, 124, 124, 124, 124, 124, ++ 124, 124, 124, 124, 124, 124, 27, 435, 436, 436, 437, 438, 439, 440, 124, 441, ++ 442, 442, 443, 444, 444, 445, 124, 446, 447, 124, 124, 448, 449, 124, 450, 451, ++ 452, 452, 452, 452, 453, 454, 452, 455, 456, 456, 456, 456, 457, 458, 459, 460, ++ 461, 461, 461, 462, 463, 464, 464, 465, 466, 466, 466, 466, 466, 466, 467, 468, ++ 469, 470, 469, 469, 471, 124, 124, 124, 472, 473, 474, 475, 475, 475, 476, 477, ++ 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 487, 488, 489, 490, 491, 124, ++ 492, 492, 492, 492, 492, 493, 494, 124, 495, 495, 495, 495, 496, 497, 124, 124, ++ 498, 498, 498, 499, 498, 500, 124, 124, 501, 501, 501, 501, 502, 503, 504, 124, ++ 505, 505, 505, 506, 506, 137, 507, 124, 508, 509, 510, 508, 511, 124, 124, 124, ++ 512, 512, 512, 513, 124, 124, 124, 124, 124, 124, 514, 514, 514, 514, 514, 515, ++ 516, 517, 518, 519, 520, 521, 124, 124, 124, 124, 522, 523, 523, 522, 524, 124, ++ 525, 525, 525, 525, 526, 527, 527, 527, 527, 527, 528, 153, 529, 529, 529, 530, ++ 531, 124, 124, 124, 124, 124, 532, 124, 124, 124, 124, 124, 533, 533, 534, 535, ++ 536, 537, 537, 538, 539, 537, 540, 541, 541, 542, 543, 544, 124, 124, 124, 124, ++ 545, 546, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 555, 556, 557, 124, ++ 124, 124, 124, 124, 124, 124, 558, 559, 560, 561, 560, 562, 560, 563, 124, 124, ++ 124, 124, 124, 564, 565, 565, 565, 566, 567, 567, 567, 567, 567, 567, 567, 567, ++ 567, 568, 124, 124, 124, 124, 124, 124, 567, 567, 567, 567, 567, 567, 569, 570, ++ 567, 567, 567, 567, 571, 124, 124, 124, 124, 572, 572, 572, 572, 572, 572, 573, ++ 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 575, 574, 574, ++ 574, 574, 574, 574, 574, 574, 574, 576, 577, 577, 577, 577, 577, 577, 577, 577, ++ 577, 577, 577, 577, 578, 124, 124, 124, 579, 579, 579, 580, 124, 124, 124, 124, ++ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 581, 582, 583, 584, 585, ++ 585, 585, 585, 586, 587, 588, 589, 590, 591, 591, 591, 591, 592, 593, 594, 595, ++ 591, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 596, 596, 596, 597, ++ 124, 124, 124, 124, 598, 598, 598, 598, 598, 599, 600, 601, 600, 602, 124, 124, ++ 603, 603, 603, 603, 604, 603, 603, 603, 605, 603, 124, 124, 124, 124, 606, 607, ++ 608, 608, 608, 608, 608, 608, 608, 608, 609, 609, 609, 609, 609, 609, 609, 609, ++ 609, 609, 609, 609, 609, 610, 124, 611, 608, 612, 124, 124, 124, 124, 124, 124, ++ 608, 608, 608, 608, 608, 608, 608, 613, 124, 124, 124, 124, 124, 124, 124, 614, ++ 615, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, ++ 254, 254, 616, 617, 124, 618, 619, 620, 620, 620, 620, 620, 620, 620, 620, 620, ++ 620, 620, 620, 620, 620, 620, 620, 621, 622, 622, 622, 622, 622, 622, 623, 624, ++ 625, 626, 627, 124, 124, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 340, ++ 0, 0, 0, 628, 0, 629, 0, 629, 8, 8, 194, 8, 630, 0, 0, 0, ++ 0, 0, 0, 0, 627, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 631, ++ 0, 0, 632, 0, 0, 0, 633, 634, 635, 0, 636, 0, 0, 0, 234, 124, ++ 11, 11, 11, 11, 637, 124, 124, 124, 124, 124, 124, 124, 0, 627, 0, 627, ++ 0, 0, 0, 0, 0, 638, 0, 639, 0, 0, 0, 0, 0, 223, 0, 0, ++ 0, 640, 641, 642, 643, 0, 0, 0, 644, 645, 0, 646, 647, 648, 0, 0, ++ 0, 0, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 650, 0, 0, 0, ++ 651, 651, 651, 651, 651, 651, 651, 651, 652, 653, 654, 124, 124, 124, 124, 124, ++ 4, 655, 656, 124, 124, 124, 124, 124, 657, 658, 659, 14, 14, 14, 660, 124, ++ 661, 124, 124, 124, 124, 124, 124, 124, 662, 662, 663, 664, 665, 124, 124, 124, ++ 124, 666, 667, 124, 668, 668, 668, 669, 124, 124, 124, 124, 124, 670, 670, 671, ++ 124, 124, 124, 124, 124, 672, 672, 673, 124, 124, 124, 124, 674, 675, 674, 676, ++ 124, 124, 124, 124, 124, 124, 677, 678, 679, 679, 679, 679, 679, 679, 679, 679, ++ 679, 679, 679, 679, 680, 681, 124, 124, 682, 682, 682, 682, 683, 684, 124, 124, ++ 124, 124, 124, 124, 124, 124, 124, 324, 0, 0, 0, 685, 124, 124, 124, 124, ++ 324, 0, 0, 245, 124, 124, 124, 124, 686, 27, 687, 688, 689, 690, 691, 692, ++ 693, 694, 695, 694, 124, 124, 124, 696, 0, 0, 348, 0, 0, 0, 0, 0, ++ 0, 627, 225, 324, 324, 324, 0, 631, 0, 0, 245, 124, 124, 124, 697, 0, ++ 698, 0, 0, 348, 639, 227, 631, 124, 0, 0, 0, 0, 0, 699, 340, 340, ++ 0, 0, 0, 0, 0, 233, 348, 629, 348, 0, 0, 0, 700, 233, 0, 0, ++ 700, 0, 245, 348, 227, 639, 124, 124, 0, 0, 0, 0, 0, 700, 245, 340, ++ 701, 0, 0, 0, 702, 703, 704, 639, 0, 320, 0, 0, 0, 0, 0, 234, ++ 246, 246, 246, 246, 246, 246, 124, 124, 246, 312, 246, 246, 246, 246, 246, 246, ++ 246, 246, 312, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 705, 246, ++ 246, 246, 246, 246, 246, 312, 124, 124, 246, 312, 124, 124, 124, 124, 124, 124, ++ 246, 246, 246, 246, 706, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 313, ++ 707, 124, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, ++ 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, ++ 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, ++ 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18, ++ 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22, ++ 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25, ++ 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31, ++ 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29, ++ 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36, ++ 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42, ++ 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47, ++ 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 50, 51, 29, 29, ++ 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53, 53, 56, 53, 53, ++ 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57, 61, 62, 63, 57, ++ 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57, 57, 57, 57, 64, ++ 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71, 72, 73, 74, 72, ++ 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71, 71, 68, 12, 12, ++ 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79, 81, 78, 82, 79, ++ 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79, 82, 12, 78, 79, ++ 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86, 88, 85, 89, 86, ++ 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86, 86, 86, 12, 12, ++ 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92, 100, 100, 96, 92, ++ 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100, 100, 100, 94, 12, ++ 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101, 101, 101, 103, 101, ++ 101, 102, 102, 103, 12, 104, 105, 103, 101, 106, 101, 101, 12, 107, 101, 101, ++ 108, 108, 108, 109, 109, 108, 108, 108, 108, 108, 109, 108, 108, 110, 111, 108, ++ 108, 109, 109, 111, 12, 112, 12, 113, 108, 114, 108, 108, 110, 12, 12, 12, ++ 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, 115, ++ 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119, 119, 120, 121, 119, ++ 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125, 119, 126, 119, 119, ++ 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129, 129, 129, 129, 129, ++ 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12, 132, 133, 134, 135, ++ 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137, 135, 138, 135, 134, ++ 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139, 139, 139, 139, 141, ++ 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12, 145, 145, 145, 145, ++ 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146, 150, 150, 150, 150, ++ 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153, 152, 153, 151, 154, ++ 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155, 151, 151, 151, 156, ++ 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158, 159, 159, 159, 159, ++ 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, 162, 162, 163, 164, ++ 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168, 169, 169, 169, 169, ++ 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12, 172, 172, 172, 173, ++ 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175, 174, 174, 175, 12, ++ 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178, 178, 178, 180, 12, ++ 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183, 183, 183, 183, 184, ++ 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186, 186, 186, 186, 187, ++ 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12, 189, 189, 190, 12, ++ 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194, 195, 195, 195, 195, ++ 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12, 195, 195, 195, 198, ++ 7, 7, 7, 199, 7, 7, 7, 12, 200, 200, 200, 200, 200, 200, 200, 201, ++ 202, 202, 202, 202, 203, 203, 203, 203, 203, 12, 12, 203, 204, 204, 204, 204, ++ 204, 204, 205, 204, 204, 204, 206, 207, 208, 208, 208, 208, 19, 19, 209, 12, ++ 146, 146, 210, 211, 202, 202, 12, 12, 212, 7, 7, 7, 213, 7, 214, 215, ++ 0, 214, 216, 12, 2, 217, 218, 2, 2, 2, 2, 219, 220, 217, 221, 2, ++ 2, 2, 222, 2, 2, 2, 2, 223, 8, 224, 8, 224, 8, 8, 225, 225, ++ 8, 8, 8, 224, 8, 15, 8, 8, 8, 10, 8, 226, 10, 15, 8, 14, ++ 0, 0, 0, 227, 0, 228, 0, 0, 229, 0, 0, 230, 0, 0, 0, 231, ++ 2, 2, 2, 232, 233, 12, 12, 12, 234, 12, 12, 12, 0, 235, 236, 0, ++ 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12, 0, 0, 233, 12, ++ 0, 0, 231, 12, 237, 237, 237, 237, 0, 238, 0, 0, 239, 239, 239, 239, ++ 18, 18, 18, 18, 18, 12, 240, 18, 241, 241, 241, 241, 241, 241, 12, 242, ++ 243, 12, 12, 242, 151, 154, 12, 12, 151, 154, 151, 154, 0, 0, 0, 233, ++ 244, 244, 244, 244, 244, 244, 245, 244, 244, 12, 12, 12, 244, 246, 12, 12, ++ 0, 247, 0, 0, 248, 244, 249, 250, 0, 0, 244, 0, 251, 252, 252, 252, ++ 252, 252, 252, 252, 252, 253, 254, 255, 256, 257, 257, 257, 257, 257, 257, 257, ++ 257, 257, 258, 256, 12, 259, 260, 260, 260, 260, 260, 260, 261, 150, 150, 150, ++ 150, 150, 150, 262, 0, 233, 12, 131, 150, 150, 150, 263, 257, 257, 257, 258, ++ 257, 257, 0, 0, 264, 264, 264, 264, 264, 264, 264, 265, 264, 266, 12, 12, ++ 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 12, 269, 269, 269, 269, ++ 269, 269, 12, 12, 236, 2, 2, 2, 2, 2, 230, 2, 270, 2, 2, 2, ++ 271, 271, 271, 271, 271, 271, 271, 272, 273, 273, 273, 273, 273, 273, 12, 12, ++ 274, 274, 274, 274, 274, 275, 12, 276, 274, 274, 275, 12, 277, 277, 277, 277, ++ 277, 277, 277, 278, 279, 279, 279, 279, 279, 12, 12, 280, 150, 150, 150, 281, ++ 282, 282, 282, 282, 282, 282, 282, 283, 282, 282, 284, 285, 145, 145, 145, 286, ++ 287, 287, 287, 287, 287, 288, 12, 12, 287, 287, 287, 289, 287, 287, 289, 287, ++ 290, 290, 290, 290, 291, 12, 12, 12, 12, 12, 292, 290, 293, 293, 293, 293, ++ 293, 294, 12, 12, 155, 154, 155, 154, 155, 154, 12, 12, 2, 2, 3, 2, ++ 2, 295, 296, 12, 293, 293, 293, 297, 293, 293, 297, 12, 150, 12, 12, 12, ++ 150, 262, 298, 150, 150, 150, 150, 12, 244, 244, 244, 246, 244, 244, 246, 12, ++ 2, 299, 12, 12, 300, 22, 12, 24, 25, 26, 25, 301, 302, 303, 25, 25, ++ 29, 29, 29, 304, 7, 7, 7, 305, 231, 0, 0, 0, 0, 231, 0, 12, ++ 29, 306, 29, 29, 29, 29, 29, 307, 308, 0, 0, 0, 0, 309, 257, 257, ++ 257, 257, 257, 310, 311, 150, 311, 150, 311, 150, 311, 281, 0, 231, 0, 231, ++ 12, 12, 308, 233, 312, 312, 312, 313, 312, 312, 312, 312, 312, 314, 312, 312, ++ 312, 312, 314, 315, 312, 312, 312, 316, 312, 312, 314, 12, 231, 131, 0, 0, ++ 0, 131, 0, 0, 8, 8, 8, 14, 0, 0, 0, 317, 318, 12, 12, 12, ++ 0, 0, 0, 319, 320, 320, 320, 320, 320, 320, 320, 321, 322, 322, 322, 322, ++ 323, 12, 12, 12, 214, 0, 0, 0, 0, 0, 0, 12, 324, 324, 324, 324, ++ 324, 12, 12, 325, 326, 326, 326, 326, 326, 326, 327, 12, 328, 328, 328, 328, ++ 328, 328, 329, 12, 330, 330, 330, 330, 330, 330, 330, 331, 332, 332, 332, 332, ++ 332, 12, 332, 332, 332, 333, 12, 12, 334, 334, 334, 334, 335, 335, 335, 335, ++ 336, 336, 336, 336, 336, 336, 336, 337, 336, 336, 337, 12, 338, 338, 338, 338, ++ 338, 12, 338, 338, 338, 338, 338, 12, 339, 339, 339, 339, 339, 339, 12, 12, ++ 340, 340, 340, 340, 340, 12, 12, 341, 342, 342, 343, 342, 343, 344, 342, 342, ++ 344, 342, 342, 342, 344, 342, 344, 345, 346, 346, 346, 346, 346, 12, 12, 12, ++ 347, 347, 347, 347, 347, 348, 12, 12, 347, 349, 12, 12, 347, 347, 12, 12, ++ 2, 350, 2, 2, 351, 2, 299, 12, 352, 353, 354, 352, 352, 352, 352, 352, ++ 352, 355, 356, 357, 358, 358, 358, 358, 358, 359, 358, 358, 360, 360, 360, 360, ++ 361, 361, 361, 361, 361, 361, 361, 362, 12, 363, 361, 361, 364, 364, 364, 364, ++ 365, 366, 367, 364, 368, 368, 368, 368, 368, 368, 368, 369, 370, 370, 370, 370, ++ 370, 370, 371, 372, 373, 373, 373, 373, 373, 373, 374, 12, 375, 375, 375, 375, ++ 376, 376, 376, 376, 376, 376, 12, 376, 377, 376, 376, 376, 378, 379, 12, 378, ++ 378, 380, 380, 378, 378, 378, 378, 378, 378, 381, 382, 383, 378, 378, 384, 12, ++ 385, 385, 385, 385, 386, 386, 386, 386, 387, 387, 387, 387, 387, 388, 389, 387, ++ 387, 388, 12, 12, 390, 390, 390, 390, 390, 391, 392, 390, 393, 393, 393, 393, ++ 393, 394, 393, 393, 395, 395, 395, 395, 396, 12, 395, 395, 397, 397, 397, 397, ++ 398, 12, 399, 400, 12, 12, 399, 397, 401, 401, 401, 401, 401, 401, 402, 12, ++ 403, 403, 403, 403, 404, 12, 12, 12, 404, 12, 405, 403, 406, 406, 406, 406, ++ 406, 406, 12, 12, 406, 406, 407, 12, 408, 408, 408, 408, 408, 409, 410, 408, ++ 408, 409, 12, 411, 29, 29, 29, 412, 413, 413, 413, 413, 413, 413, 414, 415, ++ 415, 12, 12, 12, 416, 29, 12, 12, 29, 29, 417, 12, 12, 12, 416, 29, ++ 418, 418, 418, 418, 418, 418, 12, 12, 419, 419, 419, 419, 419, 419, 420, 12, ++ 421, 421, 421, 421, 421, 421, 422, 12, 423, 423, 423, 423, 423, 423, 423, 12, ++ 424, 424, 424, 424, 424, 425, 12, 12, 426, 426, 426, 426, 426, 426, 426, 427, ++ 428, 426, 426, 426, 426, 427, 12, 429, 430, 430, 430, 430, 431, 12, 12, 432, ++ 433, 433, 433, 433, 433, 433, 434, 12, 433, 433, 435, 12, 436, 436, 436, 436, ++ 436, 437, 436, 436, 436, 436, 12, 12, 438, 438, 438, 438, 438, 439, 12, 12, ++ 440, 440, 440, 440, 118, 119, 119, 119, 119, 127, 12, 12, 441, 441, 441, 441, ++ 442, 441, 441, 441, 443, 12, 12, 12, 444, 445, 446, 447, 444, 444, 444, 447, ++ 444, 444, 448, 12, 449, 449, 449, 449, 449, 449, 450, 12, 449, 449, 451, 12, ++ 452, 453, 452, 454, 454, 452, 452, 452, 452, 452, 455, 452, 455, 453, 456, 452, ++ 452, 454, 454, 457, 458, 459, 12, 453, 452, 460, 452, 458, 452, 458, 12, 12, ++ 461, 461, 462, 463, 461, 461, 461, 461, 461, 462, 461, 461, 464, 465, 466, 461, ++ 461, 462, 467, 12, 468, 12, 12, 12, 469, 469, 469, 469, 469, 469, 469, 470, ++ 471, 12, 12, 12, 472, 472, 472, 472, 472, 472, 12, 12, 472, 472, 473, 12, ++ 474, 474, 474, 474, 474, 475, 474, 474, 474, 474, 474, 475, 476, 476, 476, 476, ++ 476, 477, 12, 12, 476, 476, 478, 12, 178, 178, 178, 180, 479, 479, 479, 479, ++ 479, 479, 480, 12, 145, 12, 12, 12, 481, 481, 481, 481, 481, 481, 482, 483, ++ 481, 481, 481, 12, 481, 482, 12, 12, 484, 484, 484, 484, 484, 484, 484, 12, ++ 485, 485, 485, 485, 486, 12, 12, 487, 488, 489, 490, 488, 488, 491, 488, 488, ++ 488, 488, 488, 488, 488, 492, 493, 488, 488, 489, 12, 12, 488, 488, 494, 12, ++ 495, 495, 496, 495, 495, 495, 495, 495, 495, 497, 12, 12, 498, 498, 498, 498, ++ 498, 498, 12, 12, 499, 499, 499, 499, 500, 12, 12, 12, 501, 501, 501, 501, ++ 501, 501, 502, 12, 53, 53, 503, 12, 440, 440, 12, 12, 504, 504, 504, 504, ++ 505, 12, 12, 12, 504, 504, 505, 12, 506, 506, 507, 506, 506, 506, 506, 506, ++ 506, 508, 506, 506, 506, 509, 12, 12, 506, 506, 506, 510, 511, 511, 511, 511, ++ 512, 511, 511, 511, 511, 511, 513, 511, 511, 514, 12, 12, 515, 516, 517, 515, ++ 515, 515, 515, 515, 515, 516, 518, 517, 515, 515, 12, 12, 515, 515, 519, 12, ++ 520, 521, 522, 520, 520, 520, 520, 520, 520, 520, 520, 523, 521, 520, 524, 12, ++ 520, 520, 525, 12, 526, 526, 526, 526, 526, 526, 526, 12, 526, 526, 527, 12, ++ 528, 528, 528, 528, 528, 528, 529, 12, 530, 530, 530, 530, 531, 530, 530, 530, ++ 530, 530, 532, 533, 530, 530, 532, 12, 534, 12, 12, 12, 100, 100, 100, 100, ++ 96, 12, 12, 98, 535, 535, 535, 535, 535, 535, 536, 12, 535, 535, 535, 537, ++ 535, 538, 12, 12, 535, 12, 12, 12, 539, 539, 539, 539, 540, 12, 12, 12, ++ 541, 541, 541, 541, 541, 542, 12, 12, 541, 541, 543, 12, 544, 544, 544, 544, ++ 544, 545, 12, 12, 546, 546, 546, 546, 546, 546, 547, 12, 269, 269, 548, 12, ++ 549, 549, 549, 549, 549, 549, 549, 550, 549, 549, 551, 552, 553, 553, 553, 553, ++ 553, 553, 553, 554, 553, 553, 555, 12, 556, 556, 556, 556, 556, 556, 556, 557, ++ 556, 557, 12, 12, 558, 558, 558, 558, 558, 559, 12, 12, 558, 558, 560, 558, ++ 560, 558, 558, 558, 558, 558, 12, 561, 562, 562, 562, 562, 562, 562, 563, 12, ++ 564, 564, 564, 564, 564, 564, 565, 12, 566, 566, 566, 566, 566, 566, 567, 566, ++ 566, 12, 12, 12, 568, 568, 568, 568, 568, 568, 569, 570, 568, 568, 12, 570, ++ 571, 572, 12, 12, 244, 573, 12, 12, 574, 574, 574, 574, 575, 575, 575, 575, ++ 575, 576, 12, 12, 12, 12, 12, 577, 574, 574, 574, 578, 578, 12, 12, 12, ++ 257, 579, 257, 580, 581, 252, 252, 252, 582, 12, 12, 12, 583, 12, 12, 12, ++ 253, 584, 12, 12, 12, 257, 12, 12, 585, 585, 585, 585, 585, 585, 585, 12, ++ 586, 586, 586, 586, 586, 586, 587, 12, 586, 586, 586, 588, 586, 586, 588, 12, ++ 586, 586, 589, 586, 0, 12, 12, 12, 0, 12, 238, 0, 317, 12, 12, 12, ++ 7, 590, 12, 12, 0, 233, 12, 12, 0, 231, 308, 0, 0, 591, 227, 0, ++ 0, 0, 591, 7, 212, 592, 7, 0, 0, 0, 593, 227, 8, 224, 12, 12, ++ 0, 231, 12, 12, 0, 0, 317, 12, 0, 0, 0, 228, 594, 595, 308, 228, ++ 0, 0, 596, 308, 0, 308, 0, 0, 0, 596, 231, 308, 0, 228, 0, 228, ++ 0, 0, 596, 231, 0, 597, 238, 0, 228, 0, 0, 0, 0, 233, 0, 0, ++ 0, 0, 0, 238, 598, 598, 598, 598, 598, 598, 598, 12, 12, 12, 599, 598, ++ 600, 598, 598, 598, 2, 2, 2, 299, 12, 270, 299, 12, 239, 601, 239, 239, ++ 239, 239, 602, 239, 603, 604, 601, 12, 19, 19, 19, 605, 12, 12, 12, 606, ++ 607, 607, 607, 607, 607, 607, 607, 608, 607, 607, 607, 609, 607, 607, 609, 610, ++ 611, 611, 611, 611, 611, 611, 611, 612, 613, 613, 613, 613, 613, 613, 614, 615, ++ 616, 616, 616, 616, 616, 616, 617, 12, 618, 618, 618, 618, 618, 618, 619, 620, ++ 621, 621, 621, 621, 621, 621, 621, 622, 621, 623, 12, 624, 151, 154, 151, 625, ++ 151, 151, 151, 154, 626, 626, 626, 626, 626, 627, 626, 626, 626, 628, 12, 12, ++ 629, 629, 629, 629, 629, 629, 629, 12, 629, 629, 630, 631, 0, 317, 12, 12, ++ 29, 632, 29, 29, 633, 634, 632, 29, 412, 29, 635, 12, 636, 51, 635, 632, ++ 633, 634, 635, 635, 633, 634, 412, 29, 412, 29, 632, 637, 29, 29, 638, 29, ++ 29, 29, 29, 12, 632, 632, 638, 29, 50, 12, 12, 12, 12, 238, 0, 0, ++ 639, 12, 12, 12, 0, 0, 317, 0, 0, 0, 12, 12, 0, 0, 231, 238, ++ 0, 231, 317, 308, 0, 0, 0, 640, 0, 0, 231, 131, 641, 12, 12, 12, ++ 244, 244, 573, 12, 642, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, ++ 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, ++ 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, ++ 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, ++ 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, ++ 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, ++ 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, ++ 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, ++ 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, ++ 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, ++ 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, ++ 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, ++ 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, ++ 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, ++ 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, ++ 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, ++ 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, ++ 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, ++ 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, ++ 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, ++ 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, ++ 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, ++ 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, ++ 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, ++ 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339, +- 1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241, +- 1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348, +- 1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197, +- 1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, +- 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364, +- 1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0, +- 1450, 0,1455,1461,1514, 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,1446,1458, +- 1468,1476,1480,1486,1517, 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,1489,1503, +- 1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0, +- 1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, +- 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0, +- 1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571, +- 1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573, +- 1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, +- 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, +- 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617, +- 1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628, +- 1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, +- 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638, +- 1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644, +- 1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, +- 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653, +- 1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0, +- 1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0, +- 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, +- 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, +- 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0, +- 1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0, +- 1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, +- 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, +- 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170, +- 1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185, +- 1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213, +- 1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224, +- 1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249, +- 1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259, +- 1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393, +- 1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295, +- 1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, +- 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345, +- 1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, +- 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198, +- 1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401, +- 1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410, +- 1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, +- 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719, +- 1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735, +- 1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755, +- 1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774, +- 1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783, +- 1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, +- 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812, +- 1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28, +- 1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724, +- 1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760, +- 1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817, +- 1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12, +- 1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14, +- 1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, +- 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17, +- 1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18, +- 1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, ++ 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0, +- 1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, +- 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, +- 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, ++ 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872, +- 1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, ++ 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0, +- 1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, +- 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0, +- 1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0, +- 1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, +- 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0, +- 1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, +- 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, +- 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, +- 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, +- 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, +- 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, +- 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, +- 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, +- 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, +- 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, +- 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, +- 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, +- 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, +- 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, +- 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, +- 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, +- 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, +- 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, +- 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, +- 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, +- 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, +- 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, +- 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, +- 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, +- 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, +- 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, +- 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, +- 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, +- 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, +- 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, +- 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, ++ 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, ++ 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, ++ 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, ++ 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, ++ 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, ++ 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603, +- 1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589, +- 1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582, +- 1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, +- 1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, ++ 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, ++ 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, ++ 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, ++ 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, ++ 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, ++ 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, ++ 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, ++ 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, ++ 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, ++ 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, ++ 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, ++ 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, ++ 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, ++ 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, ++ 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, ++ 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, ++ 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, ++ 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, ++ 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, ++ 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, ++ 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, ++ 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, ++ 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, ++ 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, ++ 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, ++ 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, ++ 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, ++ 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, ++ 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, ++ 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, ++ 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, ++ 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, ++ 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, ++ 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, ++ 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, ++ 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, ++ 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, ++ 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, ++ 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, ++ 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, ++ 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, ++ 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, ++ 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, ++ 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, ++ 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, ++ 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, ++ 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, ++ 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, ++ 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, ++ 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, ++ 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, ++ 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, ++ 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, ++ 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, ++ 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, ++ 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, ++ 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, ++ 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, ++ 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, ++ 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, ++ 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, ++ 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, ++ 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, ++ 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, ++ 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, ++ 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, ++ 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, ++ 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, ++ 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, ++ 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, ++ 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, ++ 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, ++ 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, ++ 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, ++ 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, ++ 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, ++ 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, ++ 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943, +- 1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, +- 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953, +- 1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, +- 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, ++ 0, 0,1938, 0,1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1943,1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, ++ 0, 0, 0, 0, 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949, ++ 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1953,1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0,1955,1956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1957, 0, 0, 0, 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964, ++ 1963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1967,1966,1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976, +- 1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, +- 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, +- 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, +- 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, +- 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, +- 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, +- 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, +- 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, +- 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, +- 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, +- 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, +- 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, +- 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, +- 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, +- 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, +- 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, +- 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, +- 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, +- 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, +- 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, +- 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, +- 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, +- 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, +- 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, +- 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, +- 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, +- 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, +- 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, +- 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, +- 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, +- 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, +- 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, +- 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, +- 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, +- 821, 935, 0, 0, ++ 0, 0, 0,1976,1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, ++ 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, ++ 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, ++ 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, ++ 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, ++ 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, ++ 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, ++ 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, ++ 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, ++ 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, ++ 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, ++ 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, ++ 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, ++ 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, ++ 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, ++ 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, ++ 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, ++ 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, ++ 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, ++ 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, ++ 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, ++ 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, ++ 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, ++ 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, ++ 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, ++ 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, ++ 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, ++ 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, ++ 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, ++ 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, ++ 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, ++ 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, ++ 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, ++ 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, ++ 817, 818, 819, 820, 821, 935, 0, 0, + }; +-static const int16_t +-_hb_ucd_i16[92] = ++static const int16_t _hb_ucd_i16[92]= + { + 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, + 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, +@@ -4612,42 +4358,37 @@ _hb_ucd_i16[92] = + 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, + }; + +-static inline uint_fast8_t +-_hb_ucd_gc (unsigned u) ++static inline uint8_t _hb_ucd_gc (unsigned u) + { +- return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; ++ return u<1114110 ? _hb_ucd_u8[6560u+((_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 uint_fast8_t +-_hb_ucd_ccc (unsigned u) ++static inline uint8_t _hb_ucd_ccc (unsigned u) + { +- return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; ++ return u<125259 ? _hb_ucd_u8[8620u+((_hb_ucd_u8[8036u+((_hb_ucd_u8[7556u+((_hb_ucd_u8[7188u+((_hb_ucd_u8[6942u+((((((((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 unsigned +-_hb_ucd_b4 (const uint8_t* a, unsigned i) ++static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) + { +- return (a[i>>1]>>((i&1u)<<2))&15u; ++ return (a[i>>1]>>((i&1)<<2))&15; + } +-static inline int_fast16_t +-_hb_ucd_bmg (unsigned u) ++static inline int16_t _hb_ucd_bmg (unsigned u) + { +- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9396+(((_hb_ucd_u8[9164+(((_hb_ucd_u8[9068+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; ++ return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9516u+((_hb_ucd_u8[9284u+((_hb_ucd_u8[9188u+((_hb_ucd_b4(_hb_ucd_u8+9124u,((((((((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 uint_fast8_t +-_hb_ucd_sc (unsigned u) ++static inline uint8_t _hb_ucd_sc (unsigned u) + { +- return u<918000u?_hb_ucd_u8[10398+(((_hb_ucd_u16[3952+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9870+(((_hb_ucd_u8[9644+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15u))])<<3)+((u>>3>>2)&7u))])<<2)+((u>>3)&3u))])<<3)+((u)&7u))]:2; ++ return u<918000 ? _hb_ucd_u8[10950u+((_hb_ucd_u16[4648u+((_hb_ucd_u16[2608u+((_hb_ucd_u8[10214u+((_hb_ucd_u8[9764u+((((((((u)>>2))>>2))>>3))>>4)])<<4)+((((((((u)>>2))>>2))>>3))&15)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2; + } +-static inline uint_fast16_t +-_hb_ucd_dm (unsigned u) ++static inline uint16_t _hb_ucd_dm (unsigned u) + { +- return u<195102u?_hb_ucd_u16[6244+(((_hb_ucd_u8[16628+(((_hb_ucd_u8[16246+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; ++ return u<195102 ? _hb_ucd_u16[7480u+((_hb_ucd_u8[13904u+((_hb_ucd_u8[13522u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; + } + + + #else + +-static const uint8_t +-_hb_ucd_u8[13730] = ++#include ++ ++static const uint8_t _hb_ucd_u8[13937]= + { + 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, +@@ -4655,7 +4396,7 @@ _hb_ucd_u8[13730] = + 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, +- 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, ++ 7, 7, 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, +@@ -4708,20 +4449,20 @@ _hb_ucd_u8[13730] = + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, + 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, +- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, ++ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, + 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, +- 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67, 67,178, 67, +- 67, 67,179,180,181,131, 65,111,182,183,184,185,186,187,188,189, +- 67, 67, 67, 67,190,191,111,111,111,111,111,111,111,111,192,111, +- 193,194,195,111,111,196,111,111,111,197,111,198,111,111,111, 34, +- 34,199,200,111,111,111,111,111,131,201,202,111, 34,203,111,111, +- 67, 67,204, 67, 67,111, 67,205, 67, 67, 67, 67, 67, 67, 67, 67, +- 67, 67, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, ++ 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67,178,179, 67, ++ 67, 67,180,181,182,131, 65,111,183,184,185,186,187,188,189,190, ++ 67, 67, 67, 67,191,192,111,111,111,111,111,111,111,111,193,111, ++ 194,195,196,111,111,197,111,111,111,198,111,199,111,200,111, 34, ++ 34,201,202,111,111,111,111,111,131,203,204,111, 34,205,111,111, ++ 67, 67,206, 67, 67,111, 67,207, 67, 67, 67, 67, 67, 67, 67, 67, ++ 67,208, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, +- 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, +- 206,111,194,194,111,111,111,111,111,111,111,111,111,111,111,111, ++ 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111, ++ 209,111,195,195,111,111,111,111,111,111,111,111,111,111,111,111, + 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, +@@ -4735,228 +4476,232 @@ _hb_ucd_u8[13730] = + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, +- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, +- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, +- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, +- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10, +- 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, ++ 16, 16, 36, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 39, ++ 39, 40, 40, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, ++ 39, 39, 41, 40, 40, 40, 41, 41, 40, 40, 40, 40, 40, 40, 40, 40, ++ 42, 42, 42, 42, 42, 42, 42, 42, 32, 32, 41, 32, 16, 43, 16, 10, ++ 40, 40, 40, 44, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, +- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11, +- 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, +- 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53, +- 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55, +- 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36, +- 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61, +- 43, 43, 43, 43, 43, 57, 62, 2, 63, 36, 36, 36, 36, 64, 43, 43, +- 7, 7, 7, 7, 7, 2, 2, 36, 65, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 66, 43, 43, 43, 67, 47, 43, 43, 68, 69, 70, 43, 43, 36, +- 7, 7, 7, 7, 7, 36, 71, 72, 2, 2, 2, 2, 2, 2, 2, 73, +- 64, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 65, 36, +- 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36, +- 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, +- 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, +- 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, +- 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 75, 43, 43, 43, 43, +- 36, 36, 36, 36, 76, 43, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, +- 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, +- 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, +- 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, +- 64, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 78, +- 79, 43, 43, 77, 78, 78, 79, 36, 36, 36, 36, 82, 78, 78, 36, 36, +- 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43, +- 43, 77, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 78, +- 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 65, 36, 36, 36, +- 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 64, 2, 2, 2, 2, 2, +- 79, 43, 43, 43, 77, 78, 79, 43, 60, 20, 20, 20, 83, 43, 43, 43, +- 43, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 79, +- 79, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 77, 78, 78, 36, 36, +- 72, 27, 27, 27, 27, 27, 27, 27, 43, 65, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 36, 78, 77, 78, 78, 78, 78, 78, 79, 43, +- 36, 36, 36, 82, 78, 78, 78, 78, 78, 78, 78, 7, 7, 7, 7, 7, +- 27, 84, 61, 61, 53, 61, 61, 61, 77, 78, 65, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 65, 43, 77, 78, 78, 43, 43, 43, 43, 43, +- 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 85, 27, 27, 27, 84, +- 64, 78, 66, 36, 36, 36, 36, 36, 78, 78, 78, 77, 78, 78, 43, 43, +- 43, 43, 77, 78, 78, 78, 81, 36, 86, 82, 78, 78, 78, 78, 78, 78, +- 43, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 78, +- 79, 43, 43, 78, 78, 78, 79, 71, 61, 61, 36, 82, 27, 27, 27, 87, +- 27, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 77, +- 78, 43, 43, 43, 78, 78, 78, 78, 7, 78, 2, 2, 2, 2, 2, 2, +- 64, 36, 43, 43, 43, 43, 43, 88, 36, 36, 36, 69, 43, 43, 43, 57, +- 7, 7, 7, 7, 7, 2, 2, 2, 64, 36, 43, 43, 43, 43, 65, 36, +- 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36, +- 71, 61, 2, 2, 2, 2, 2, 2, 2, 89, 89, 61, 43, 61, 61, 61, +- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 78, +- 64, 43, 43, 43, 43, 43, 43, 77, 43, 43, 57, 43, 36, 36, 64, 43, +- 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 70, 61, 61, 61, 61, +- 2, 2, 89, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 82, 79, 43, +- 77, 43, 43, 43, 79, 77, 79, 65, 36, 36, 36, 78, 43, 36, 36, 43, +- 65, 78, 81, 82, 78, 78, 78, 36, 64, 43, 65, 36, 36, 36, 36, 36, +- 36, 77, 79, 77, 78, 78, 79, 82, 7, 7, 7, 7, 7, 78, 79, 61, +- 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 64, 43, +- 2, 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +- 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16, +- 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 71, 66, +- 92, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 94, 94, +- 36, 36, 36, 36, 36, 58, 2, 95, 96, 36, 36, 36, 36, 36, 36, 36, +- 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, +- 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, +- 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, +- 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 75, +- 36, 76, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, +- 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, +- 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, +- 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, +- 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, +- 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, +- 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 2, +- 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, +- 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, +- 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, +- 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, +- 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, +- 16, 16, 16, 16, 34, 16, 16, 16, 43, 57, 43, 43, 43, 43, 43, 43, +- 77, 43, 43, 43, 65, 36, 64, 36, 36, 36, 65, 82, 43, 36, 36, 36, +- 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, +- 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16,100, 40, 40, ++ 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 45, 34, 32, 34, 11, ++ 32, 46, 42, 42, 47, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, ++ 11, 11, 11, 11, 48, 2, 2, 2, 16, 16, 16, 16, 49, 50, 51, 52, ++ 53, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 54, ++ 55, 56, 42, 55, 42, 42, 42, 42, 36, 36, 36, 36, 36, 36, 36, 36, ++ 36, 57, 2, 2, 2, 2, 2, 2, 58, 58, 58, 8, 9, 59, 2, 60, ++ 42, 42, 42, 42, 42, 56, 61, 2, 62, 36, 36, 36, 36, 63, 42, 42, ++ 7, 7, 7, 7, 7, 2, 2, 36, 64, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 65, 42, 42, 42, 66, 46, 42, 42, 67, 68, 69, 42, 42, 36, ++ 7, 7, 7, 7, 7, 36, 70, 71, 2, 2, 2, 2, 2, 2, 2, 72, ++ 63, 36, 36, 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 64, 36, ++ 36, 36, 36, 42, 42, 42, 42, 42, 7, 7, 7, 7, 7, 36, 36, 36, ++ 36, 36, 36, 36, 36, 63, 42, 42, 42, 42, 39, 21, 2, 39, 68, 20, ++ 36, 36, 36, 42, 42, 68, 42, 42, 42, 42, 68, 42, 68, 42, 42, 42, ++ 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 63, 42, 42, 2, ++ 36, 36, 36, 36, 73, 36, 36, 36, 58, 58, 58, 74, 42, 42, 42, 42, ++ 36, 36, 36, 36, 75, 42, 42, 42, 42, 74, 42, 42, 42, 42, 42, 42, ++ 42, 76, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 76, 64, 77, ++ 78, 42, 42, 42, 76, 77, 78, 77, 63, 42, 42, 42, 36, 36, 36, 36, ++ 36, 42, 2, 7, 7, 7, 7, 7, 79, 36, 36, 36, 36, 36, 36, 36, ++ 63, 77, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 77, ++ 78, 42, 42, 76, 77, 77, 78, 36, 36, 36, 36, 81, 77, 77, 36, 36, ++ 36, 42, 42, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 52, 57, 42, ++ 42, 76, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 42, 77, ++ 78, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 64, 36, 36, 36, ++ 36, 36, 36, 7, 7, 7, 7, 7, 42, 36, 63, 2, 2, 2, 2, 2, ++ 78, 42, 42, 42, 76, 77, 78, 42, 59, 20, 20, 20, 82, 42, 42, 42, ++ 42, 77, 80, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 78, ++ 78, 42, 42, 76, 77, 77, 78, 42, 42, 42, 42, 76, 77, 77, 36, 36, ++ 71, 27, 27, 27, 27, 27, 27, 27, 42, 64, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 36, 77, 76, 77, 77, 77, 77, 77, 78, 42, ++ 36, 36, 36, 81, 77, 77, 77, 77, 77, 77, 77, 7, 7, 7, 7, 7, ++ 27, 83, 60, 60, 52, 60, 60, 60, 76, 77, 64, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 64, 42, 76, 77, 77, 42, 42, 42, 42, 42, ++ 42, 42, 42, 42, 36, 36, 36, 36, 7, 7, 7, 84, 27, 27, 27, 83, ++ 63, 77, 65, 36, 36, 36, 36, 36, 77, 77, 77, 76, 77, 77, 42, 42, ++ 42, 42, 76, 77, 77, 77, 36, 36, 85, 81, 77, 77, 77, 77, 77, 77, ++ 42, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 77, ++ 78, 42, 42, 77, 77, 77, 78, 70, 60, 60, 36, 81, 27, 27, 27, 86, ++ 27, 27, 27, 27, 83, 36, 36, 36, 36, 36, 36, 36, 36, 42, 42, 76, ++ 77, 42, 42, 42, 77, 77, 77, 77, 7, 77, 2, 2, 2, 2, 2, 2, ++ 63, 36, 42, 42, 42, 42, 42, 87, 36, 36, 36, 68, 42, 42, 42, 56, ++ 7, 7, 7, 7, 7, 2, 2, 2, 63, 36, 42, 42, 42, 42, 64, 36, ++ 36, 36, 36, 39, 42, 42, 42, 42, 7, 7, 7, 7, 7, 7, 36, 36, ++ 70, 60, 2, 2, 2, 2, 2, 2, 2, 88, 88, 60, 42, 60, 60, 60, ++ 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 46, 46, 46, 4, 4, 77, ++ 63, 42, 42, 42, 42, 42, 42, 76, 42, 42, 56, 42, 36, 36, 63, 42, ++ 42, 42, 42, 42, 42, 42, 42, 60, 60, 60, 60, 69, 60, 60, 60, 60, ++ 2, 2, 88, 60, 21, 2, 2, 2, 36, 36, 36, 36, 36, 81, 78, 42, ++ 76, 42, 42, 42, 78, 76, 78, 64, 36, 36, 36, 77, 42, 36, 36, 42, ++ 64, 77, 80, 81, 77, 77, 77, 36, 63, 42, 64, 36, 36, 36, 36, 36, ++ 36, 76, 78, 76, 77, 77, 78, 81, 7, 7, 7, 7, 7, 77, 78, 60, ++ 16, 16, 16, 16, 16, 49, 43, 16, 36, 36, 36, 36, 36, 36, 63, 42, ++ 2, 2, 2, 2, 89, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, ++ 60, 60, 60, 60, 60, 60, 60, 60, 11, 11, 11, 11, 16, 16, 16, 16, ++ 90, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 65, ++ 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 92, 93, 93, ++ 36, 36, 36, 36, 36, 57, 2, 94, 95, 36, 36, 36, 36, 36, 36, 36, ++ 36, 42, 76, 77, 77, 77, 77, 80, 36, 42, 96, 2, 2, 2, 2, 2, ++ 36, 42, 42, 42, 42, 42, 42, 42, 36, 36, 42, 78, 42, 42, 42, 77, ++ 77, 77, 77, 76, 78, 42, 42, 42, 42, 42, 2, 79, 2, 59, 63, 42, ++ 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 97, 2, 55, 42, 74, ++ 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 36, 36, 36, 36, ++ 36, 36, 36, 36, 63, 36, 36, 36, 42, 76, 77, 78, 76, 77, 77, 77, ++ 77, 76, 77, 77, 78, 42, 42, 42, 60, 60, 2, 7, 7, 7, 7, 7, ++ 7, 7, 7, 7, 7, 27, 27, 60, 36, 36, 36, 63, 76, 78, 42, 2, ++ 36, 36, 81, 76, 42, 42, 42, 42, 76, 76, 78, 42, 42, 42, 76, 77, ++ 77, 78, 42, 42, 42, 42, 42, 42, 2, 2, 2, 79, 2, 2, 2, 2, ++ 42, 42, 42, 42, 42, 42, 42, 98, 42, 42, 80, 36, 36, 36, 36, 36, ++ 36, 36, 76, 42, 42, 76, 76, 77, 77, 76, 80, 36, 36, 36, 36, 2, ++ 88, 60, 60, 60, 60, 46, 42, 42, 42, 42, 60, 60, 60, 60, 21, 2, ++ 42, 80, 36, 36, 36, 36, 36, 36, 81, 42, 42, 77, 42, 78, 42, 36, ++ 36, 36, 36, 76, 42, 77, 78, 78, 42, 77, 77, 77, 77, 77, 2, 2, ++ 36, 36, 77, 77, 77, 77, 42, 42, 42, 42, 77, 42, 42, 56, 2, 2, ++ 7, 7, 7, 7, 7, 7, 85, 36, 36, 36, 36, 36, 39, 39, 39, 2, ++ 16, 16, 16, 16, 34, 16, 16, 16, 42, 56, 42, 42, 42, 42, 42, 42, ++ 76, 42, 42, 42, 64, 36, 63, 36, 36, 36, 64, 81, 42, 36, 36, 36, ++ 16, 16, 16, 16, 16, 16, 39, 39, 39, 39, 39, 39, 39, 43, 16, 16, ++ 16, 16, 16, 16, 43, 16, 16, 16, 16, 16, 16, 16, 16, 99, 39, 39, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, +- 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,101,101,101,101, +- 16, 16, 16, 16, 11, 11,102,103, 41, 16, 16, 16, 11, 11,102, 41, +- 16, 16, 16, 16, 11, 11,104, 41,105,105,105,105,105,106, 59, 59, +- 51, 51, 51, 2,107,108,107,108, 2, 2, 2, 2,109, 59, 59,110, +- 2, 2, 2, 2,111,112, 2,113,114, 2,115,116, 2, 2, 2, 2, +- 2, 9,114, 2, 2, 2, 2,117, 59, 59, 59, 59, 59, 59, 59, 59, +- 118, 40, 27, 27, 27, 8,115,119, 27, 27, 27, 27, 27, 8,115, 94, +- 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,120, 48, +- 99, 48, 99, 43, 43, 43, 43, 43, 61,121, 61,122, 61, 34, 11, 16, +- 11, 32,122, 61, 46, 11, 11, 61, 61, 61,121,121,121, 11, 11,123, +- 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,124, +- 95, 95, 95, 95, 95, 95, 95, 95, 95,125,126, 95,127, 61, 61, 61, +- 8, 8,128, 61, 61, 8, 61, 61,128, 26, 61,128, 61, 61, 61,128, +- 61, 61, 61, 61, 61, 61, 61, 8, 61,128,128, 61, 61, 61, 61, 61, +- 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,129,130, 61, 61, +- 61, 61, 61, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 26, 8, 8, +- 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, +- 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, +- 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, +- 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, +- 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, +- 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, +- 8, 8,115,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, +- 8,115,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, ++ 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,100,100,100,100, ++ 16, 16, 16, 16, 11, 11,101,102, 40, 16, 16, 16, 11, 11,101, 40, ++ 16, 16, 16, 16, 11, 11,103, 40,104,104,104,104,104,105, 58, 58, ++ 50, 50, 50, 2,106,107,106,107, 2, 2, 2, 2,108, 58, 58,109, ++ 2, 2, 2, 2,110,111, 2,112,113, 2,114,115, 2, 2, 2, 2, ++ 2, 9,113, 2, 2, 2, 2,116, 58, 58, 58, 58, 58, 58, 58, 58, ++ 117, 39, 27, 27, 27, 8,114,118, 27, 27, 27, 27, 27, 8,114, 93, ++ 20, 20, 20, 20, 20, 20, 20, 20, 42, 42, 42, 42, 42, 42,119, 47, ++ 98, 47, 98, 42, 42, 42, 42, 42, 60,120, 60,121, 60, 34, 11, 16, ++ 11, 32,121, 60, 45, 11, 11, 60, 60, 60,120,120,120, 11, 11,122, ++ 11, 11, 35, 36,123, 60, 16, 11, 8, 8, 45, 16, 16, 26, 60,124, ++ 94, 94, 94, 94, 94, 94, 94, 94, 94,125,126, 94,127, 60, 60, 60, ++ 8, 8,128, 60, 60, 8, 60, 60,128, 26, 60,128, 60, 60, 60,128, ++ 60, 60, 60, 60, 60, 60, 60, 8, 60,128,128, 60, 60, 60, 60, 60, ++ 60, 60, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ++ 60, 60, 60, 60, 4, 4, 60, 60, 8, 60, 60, 60,129,130, 60, 60, ++ 60, 60, 60, 60, 60, 60,128, 60, 60, 60, 60, 60, 60, 26, 8, 8, ++ 8, 8, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 8, 8, ++ 8, 60, 60, 60, 60, 60, 60, 60, 27, 27, 27, 27, 27, 27, 60, 60, ++ 60, 60, 60, 60, 60, 27, 27, 27, 60, 60, 60, 26, 60, 60, 60, 60, ++ 26, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 8, 8, 8, 8, ++ 60, 60, 60, 60, 60, 60, 60, 26, 60, 60, 60, 60, 4, 4, 4, 4, ++ 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 60, 60, 60, 60, 60, 60, ++ 8, 8,114,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, ++ 8,114,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, +- 8, 8,128, 26, 8, 8,128, 61, 32, 11, 32, 34, 34, 34, 34, 11, +- 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,124, 61, 61,122, 34,133, +- 43, 32, 16, 16, 50, 2, 90, 2, 36, 36, 36, 36, 36, 36, 36, 76, +- 2, 2, 2, 2, 2, 2, 2, 56, 2,107,107, 2,111,112,107, 2, +- 2, 2, 2, 6, 2, 98,107, 2,107, 4, 4, 4, 4, 2, 2, 80, +- 2, 2, 2, 2, 2, 51, 2, 2, 98,134, 2, 2, 2, 2, 2, 2, +- 61, 2,135,132,132,132,136, 51, 51, 51, 51, 51, 51, 51, 51, 51, +- 1, 2,137,138, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,139, 94, +- 140, 95, 95, 95, 95, 43, 43, 78,141, 40, 40, 61, 95,142, 58, 61, +- 72, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64,143,144, 63, +- 36, 36, 36, 36, 36, 58, 40, 63, 61, 27, 27, 61, 61, 61, 61, 61, +- 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, +- 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 76, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 64, +- 48,147, 43, 43, 43, 43, 43, 80, 32, 32, 32, 32, 32, 32, 40, 43, +- 36, 36, 36, 95, 95, 95, 95, 95, 43, 2, 2, 2, 2, 2, 2, 2, +- 41, 41, 41,144, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, +- 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, +- 32, 32, 32, 32, 42,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, ++ 8, 8,128, 26, 8, 8,128, 60, 32, 11, 32, 34, 34, 34, 34, 11, ++ 32, 32, 34, 16, 16, 16, 39, 11, 32, 32,124, 60, 60,121, 34,133, ++ 42, 32, 16, 16, 49, 2, 89, 2, 36, 36, 36, 36, 36, 36, 36, 75, ++ 2, 2, 2, 2, 2, 2, 2, 55, 2,106,106, 2,110,111,106, 2, ++ 2, 2, 2, 6, 2, 97,106, 2,106, 4, 4, 4, 4, 2, 2, 79, ++ 2, 2, 2, 2, 2, 50, 2, 2, 97,134, 2, 2, 2, 2, 2, 2, ++ 60, 2,135,132,132,132,136, 50, 50, 50, 50, 50, 50, 50, 50, 50, ++ 1, 2,137,138, 4, 4, 4, 4, 4, 60, 4, 4, 4, 4,139, 93, ++ 140, 94, 94, 94, 94, 42, 42, 77,141, 39, 39, 60, 94,142, 57, 60, ++ 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63,143,144, 62, ++ 36, 36, 36, 36, 36, 57, 39, 62, 60, 27, 27, 60, 60, 60, 60, 60, ++ 27, 27, 27, 27, 27, 60, 60, 60, 60, 60, 60, 60, 27, 27, 27, 27, ++ 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 75, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 63, ++ 47,147, 42, 42, 42, 42, 42, 79, 32, 32, 32, 32, 32, 32, 39, 42, ++ 36, 36, 36, 94, 94, 94, 94, 94, 42, 2, 2, 2, 2, 2, 2, 2, ++ 40, 40, 40,144, 39, 39, 39, 39, 40, 32, 32, 32, 32, 32, 32, 32, ++ 16, 32, 32, 32, 32, 32, 32, 32, 43, 16, 16, 16, 34, 34, 34, 32, ++ 32, 32, 32, 32, 41,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, +- 32, 32, 11, 11, 34, 34, 32, 16, 32, 16, 16, 32, 32, 32, 11, 11, +- 11, 40,149, 35, 40, 35, 36, 36, 36, 65, 36, 65, 36, 64, 36, 36, +- 36, 82, 79, 77, 61, 61, 43, 43, 27, 27, 27, 61,150, 61, 61, 61, +- 36, 36, 2, 2, 2, 2, 2, 2, 78, 36, 36, 36, 36, 36, 36, 36, +- 36, 36, 78, 78, 78, 78, 78, 78, 78, 78, 43, 43, 43, 43, 43, 2, +- 43, 36, 36, 36, 2, 66, 66, 64, 36, 36, 36, 43, 43, 43, 43, 2, +- 36, 36, 36, 64, 43, 43, 43, 43, 43, 78, 78, 78, 78, 78, 78, 97, +- 36, 64, 78, 43, 43, 78, 43, 78, 97, 2, 2, 2, 2, 2, 2, 80, +- 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 64, 63, 36, 36, 36, 36, +- 36, 36, 36, 36, 64, 43, 43, 77, 79, 77, 79, 43, 43, 43, 43, 43, +- 36, 64, 36, 36, 36, 36, 77, 78, 7, 7, 7, 7, 7, 7, 2, 2, +- 63, 36, 36, 71, 61, 82, 77, 36, 65, 43, 65, 64, 65, 36, 36, 43, +- 36, 36, 36, 36, 36, 36, 76, 2, 36, 36, 36, 36, 36, 82, 43, 78, +- 2, 76,151, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,103, 40, 40, +- 16, 16, 16, 16,100, 41, 41, 41, 36, 82, 79, 78, 77, 97, 79, 43, ++ 32, 32, 11, 11, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, ++ 48, 39,149, 35, 39, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36, ++ 36, 81, 78, 76, 60, 60, 42, 42, 27, 27, 27, 60,150, 60, 60, 60, ++ 36, 36, 2, 2, 2, 2, 2, 2, 77, 36, 36, 36, 36, 36, 36, 36, ++ 36, 36, 77, 77, 77, 77, 77, 77, 77, 77, 42, 42, 42, 42, 42, 2, ++ 42, 36, 36, 36, 2, 65, 65, 63, 36, 36, 36, 42, 42, 42, 42, 2, ++ 36, 36, 36, 63, 42, 42, 42, 42, 42, 77, 77, 77, 77, 77, 77, 96, ++ 36, 63, 77, 42, 42, 77, 42, 77, 96, 2, 2, 2, 2, 2, 2, 79, ++ 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 63, 62, 36, 36, 36, 36, ++ 36, 36, 36, 36, 63, 42, 42, 76, 78, 76, 78, 42, 42, 42, 42, 42, ++ 36, 63, 36, 36, 36, 36, 76, 77, 7, 7, 7, 7, 7, 7, 2, 2, ++ 62, 36, 36, 70, 60, 81, 76, 36, 64, 42, 64, 63, 64, 36, 36, 42, ++ 36, 36, 36, 36, 36, 36, 75, 2, 36, 36, 36, 36, 36, 81, 42, 77, ++ 2, 75,151, 42, 42, 42, 42, 42, 16, 16, 16, 16, 16,102, 39, 39, ++ 16, 16, 16, 16, 99, 40, 40, 40, 36, 81, 78, 77, 76, 96, 78, 42, + 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, +- 16, 16, 16, 16, 16, 16, 35, 65, 36, 36, 36, 36,154, 36, 36, 36, +- 36, 41, 41, 41, 41, 41, 41, 41, 41, 74, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 36, 36,132, 36, 36, 36, 36, 36, 36, 36, 71, +- 36, 36, 36, 36, 36, 36,150, 61, 2, 2, 2,135,116, 2, 2, 2, +- 6,155,156,132,132,132,132,132,132,132,116,135,116, 2,113,157, +- 2, 2, 2, 2,139,132,132,116, 2,158, 8, 8, 60, 2, 2, 2, ++ 16, 16, 16, 16, 16, 16, 35, 64, 36, 36, 36, 36,154, 36, 36, 36, ++ 36, 40, 40, 40, 40, 40, 40, 40, 40, 22, 60, 60, 60, 60, 60, 60, ++ 60, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132, ++ 60, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 60, 60, 60, 60, ++ 36, 36, 36, 36, 36, 36,150, 60, 2, 2, 2,135,115, 2, 2, 2, ++ 6,155,156,132,132,132,132,132,132,132,115,135,115, 2,112,157, ++ 2, 2, 2, 2,139,132,132,115, 2,158, 8, 8, 59, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, +- 16, 16, 16, 16, 16, 17, 18,115,116, 4, 2, 36, 36, 36, 36, 36, +- 63, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, +- 20,160, 53, 20, 26, 8,128, 61, 61, 61, 61, 61,161, 59, 61, 61, +- 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, +- 95, 95,127, 27, 84, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, +- 61, 61, 61, 61, 61, 61, 47, 43,162,162,162,162,162,162,162,162, +- 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 87, 36, +- 138, 36, 36, 36, 36, 95, 95, 95, 36, 36, 36, 36, 36, 36, 36, 58, +- 164, 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 32, 16, 16, 16, 16, +- 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 71,145, 27, 27, 27, ++ 16, 16, 16, 16, 16, 17, 18,114,115, 4, 2, 36, 36, 36, 36, 36, ++ 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 39, ++ 20,160, 52, 20, 26, 8,128, 60, 60, 60, 60, 60,161, 58, 60, 60, ++ 2, 2, 2, 89, 27, 27, 27, 27, 27, 27, 27, 83, 60, 60, 60, 60, ++ 94, 94,127, 27, 83, 60, 60, 60, 60, 60, 60, 60, 60, 27, 60, 60, ++ 60, 60, 60, 60, 60, 60, 46, 42,162,162,162,162,162,162,162,162, ++ 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 86, 36, ++ 138, 36, 36, 36, 36, 94, 94, 94, 36, 36, 36, 36, 36, 36, 36, 57, ++ 164, 94, 94, 94, 94, 94, 94, 94, 11, 11, 11, 32, 16, 16, 16, 16, ++ 36, 36, 36, 57, 27, 27, 27, 27, 36, 36, 36, 70,145, 27, 27, 27, + 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, + 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, +- 64, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, ++ 63, 42, 42, 42, 42, 42, 42, 42, 36, 36, 36, 36, 42, 42, 42, 42, + 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, +- 36, 36, 36, 36, 72, 36, 36, 36, 36, 36, 64, 43, 43,163, 27, 27, +- 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, +- 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, +- 7, 7, 7, 7, 7, 36, 36, 63, 11, 11, 11, 11,166, 43, 43,141, +- 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 64,167, 51, +- 36, 36, 36, 36, 36, 36, 43, 43, 27, 27, 27, 87, 36, 36, 36, 36, +- 163, 27, 30, 2, 2, 2, 2, 2, 36, 43, 43, 2, 2, 2, 2, 2, +- 36, 36,165, 27, 27, 27, 27, 27, 79, 81, 36, 36, 36, 36, 36, 36, +- 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, +- 27, 27, 27, 7, 7, 7, 7, 7, 65, 64, 65, 36, 36, 36, 36, 64, +- 78, 79, 43, 77, 79, 57, 73, 2, 2, 43, 43, 43, 43, 43, 67, 59, +- 36, 36, 36, 64, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, +- 2, 2, 82, 81, 36, 36, 36, 36, 36, 64, 2, 36, 36, 36, 36, 36, +- 36, 82, 78, 43, 43, 43, 43, 77, 81, 36, 58, 2, 56, 43, 57, 79, +- 7, 7, 7, 7, 7, 58, 58, 2, 90, 27, 27, 27, 27, 27, 27, 27, +- 36, 36, 36, 36, 36, 36, 78, 79, 43, 78, 77, 43, 2, 2, 2, 65, +- 36, 36, 36, 36, 36, 36, 36, 64, 77, 78, 78, 78, 78, 78, 78, 78, +- 36, 36, 36, 82, 78, 78, 81, 36, 36, 78, 78, 43, 43, 43, 43, 43, +- 36, 36, 36, 36, 78, 79, 43, 43, 43, 78, 78, 78, 78, 78, 78, 77, +- 65, 65, 2, 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 43, 43, +- 36, 36, 82, 78, 43, 43, 43, 43, 78, 43, 77, 65, 36, 58, 2, 2, +- 7, 7, 7, 7, 7, 2, 2, 65, 78, 79, 43, 43, 77, 77, 78, 79, +- 77, 43, 36, 66, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82, +- 78, 43, 43, 43, 78, 78, 43, 79, 57, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 36, 36, 43, 43, 78, 79, 43, 43, 43, 77, 79, 79, +- 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 79, 78, +- 43, 43, 43, 79, 58, 2, 2, 2, 36, 36, 36, 36, 36, 36, 64, 79, +- 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, +- 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, +- 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, +- 82, 78, 43, 43, 43, 43, 78, 78, 65, 66, 78, 78, 78, 78, 78, 78, +- 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, +- 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, +- 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, +- 43, 43, 43, 77, 43, 2, 66, 2, 58, 2, 2, 2, 2, 2, 2, 2, +- 43, 43, 43, 43, 43, 43, 43, 79, 2, 36, 36, 36, 36, 36, 36, 36, +- 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, +- 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, +- 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, +- 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78, +- 77, 57, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 43, 43, 43, +- 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, +- 61, 61, 61, 61, 61, 61, 61, 21, 65, 36, 36, 64, 43, 43, 43, 43, +- 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 78, 79, 43, +- 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, +- 40, 40, 89, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,168, 27, 27, +- 27, 87, 36, 36, 36, 36, 36, 36, 40, 63, 36, 36, 36, 36, 36, 36, +- 36, 36, 36, 36, 36, 76,146, 2, 27, 27, 27, 30, 2, 2, 2, 2, +- 82, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, +- 43, 68, 40, 40, 40, 40, 40, 40, 40, 80, 43, 43, 43, 43, 43, 43, +- 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,169, 79, 43, 61,169, 78, +- 78,170, 59, 59, 59, 75, 43, 43, 43, 70, 47, 43, 43, 43, 61, 61, +- 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 70, 61, 61, 61, 61, 61, ++ 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 63, 42, 42,163, 27, 27, ++ 36, 36, 36, 36, 57, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, ++ 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 42, 42, 42, 42, 42, 42, ++ 7, 7, 7, 7, 7, 36, 36, 62, 11, 11, 11, 11,166, 42, 42,141, ++ 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 63,167, 50, ++ 88, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 42, 42, 42, ++ 27, 27, 27, 86, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2, ++ 36, 42, 42, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27, ++ 78, 80, 36, 36, 36, 36, 36, 36, 42, 42, 42, 56, 2, 2, 2, 2, ++ 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, ++ 64, 63, 64, 36, 36, 36, 36, 63, 77, 78, 42, 76, 78, 56, 72, 2, ++ 2, 42, 42, 42, 42, 42, 66, 58, 36, 36, 36, 63, 42, 42, 78, 42, ++ 42, 42, 42, 7, 7, 7, 7, 7, 2, 2, 81, 80, 36, 36, 36, 36, ++ 36, 63, 2, 36, 36, 36, 36, 36, 36, 81, 77, 42, 42, 42, 42, 76, ++ 80, 36, 57, 2, 55, 42, 56, 78, 7, 7, 7, 7, 7, 57, 57, 2, ++ 89, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 77, 78, ++ 42, 77, 76, 42, 2, 2, 2, 64, 36, 36, 36, 36, 36, 36, 36, 63, ++ 76, 77, 77, 77, 77, 77, 77, 77, 36, 36, 36, 81, 77, 77, 80, 36, ++ 36, 77, 77, 42, 42, 42, 42, 42, 36, 36, 36, 36, 77, 78, 42, 42, ++ 42, 77, 77, 77, 77, 77, 77, 76, 64, 64, 2, 2, 2, 2, 2, 2, ++ 55, 42, 42, 42, 42, 42, 42, 42, 36, 36, 81, 77, 42, 42, 42, 42, ++ 77, 42, 76, 64, 36, 57, 2, 2, 7, 7, 7, 7, 7, 2, 2, 64, ++ 77, 78, 42, 42, 76, 76, 77, 78, 76, 42, 36, 65, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 36, 36, 81, 77, 42, 42, 42, 77, 77, 42, 78, ++ 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 42, 42, ++ 77, 78, 42, 42, 42, 76, 78, 78, 56, 2, 36, 36, 36, 36, 36, 36, ++ 36, 36, 36, 36, 36, 63, 78, 77, 42, 42, 42, 78, 57, 2, 2, 2, ++ 36, 36, 36, 36, 36, 36, 63, 78, 77, 42, 42, 78, 42, 42, 42, 42, ++ 7, 7, 7, 7, 7, 27, 2, 88, 42, 42, 42, 42, 78, 56, 2, 2, ++ 27, 27, 27, 27, 27, 27, 27, 86, 77, 77, 77, 77, 77, 78, 76, 64, ++ 80, 78, 2, 2, 2, 2, 2, 2, 81, 77, 42, 42, 42, 42, 77, 77, ++ 64, 65, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, ++ 63, 42, 42, 42, 42, 64, 36, 36, 36, 63, 42, 42, 76, 63, 42, 56, ++ 2, 2, 2, 55, 42, 42, 42, 42, 63, 42, 42, 76, 78, 42, 36, 36, ++ 36, 36, 36, 36, 36, 42, 42, 42, 42, 42, 42, 76, 42, 2, 65, 2, ++ 76, 42, 76, 76, 77, 77, 77, 77, 57, 2, 2, 2, 2, 2, 2, 2, ++ 42, 42, 42, 42, 42, 42, 42, 78, 2, 36, 36, 36, 36, 36, 36, 36, ++ 42, 42, 42, 42, 76, 42, 42, 42, 76, 42, 78, 42, 42, 42, 42, 42, ++ 42, 42, 42, 63, 42, 42, 42, 42, 36, 36, 36, 36, 36, 77, 77, 77, ++ 42, 76, 78, 78, 36, 36, 36, 36, 36, 36, 36, 36, 75, 36, 36, 36, ++ 36, 63, 76, 96, 2, 2, 2, 2, 42, 81, 36, 36, 36, 36, 36, 36, ++ 36, 36, 77, 42, 42, 42, 42, 77, 76, 56, 2, 2, 2, 2, 2, 2, ++ 7, 7, 7, 7, 7, 42, 42, 42, 27, 27, 83, 60, 60, 60, 52, 20, ++ 150, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 21, ++ 64, 36, 36, 63, 42, 42, 42, 42, 36, 36, 36, 36, 36, 36, 36, 42, ++ 42, 42, 42, 42, 42, 77, 78, 42, 42, 42, 56, 2, 2, 2, 2, 2, ++ 42, 42, 42, 56, 2, 2, 60, 60, 39, 39, 88, 60, 60, 60, 60, 60, ++ 7, 7, 7, 7, 7,168, 27, 27, 27, 86, 36, 36, 36, 36, 36, 36, ++ 39, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 75,146, 2, ++ 27, 27, 27, 30, 2, 2, 2, 2, 11, 11, 11, 11, 11, 32, 16, 16, ++ 81, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, ++ 42, 67, 39, 39, 39, 39, 39, 39, 39, 79, 42, 42, 42, 42, 42, 42, ++ 77, 39, 94, 94, 94, 94, 94, 94, 36, 36, 36, 36, 36, 36, 46, 56, ++ 7, 7, 7, 7, 7, 60, 60, 60, 60, 60,169, 78, 42, 60,169, 77, ++ 77,170, 58, 58, 58, 74, 42, 42, 42, 69, 46, 42, 42, 42, 60, 60, ++ 60, 60, 60, 60, 60, 42, 42, 60, 60, 42, 69, 60, 60, 60, 60, 60, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, +@@ -4966,74 +4711,76 @@ _hb_ucd_u8[13730] = + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, +- 43, 43, 43, 70, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 70, 61, +- 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 70, 21, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 56, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, +- 43, 43, 43, 68, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 71, +- 7, 7, 7, 7, 7, 7, 7,171, 36, 36, 36, 36, 36, 76, 43, 43, +- 172, 7, 7, 7, 7, 7, 7, 85, 16, 16, 43, 43, 43, 68, 40, 40, +- 27, 27, 27, 27, 27, 27,145, 27,173, 27, 27, 27, 27, 27, 27, 27, +- 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61, +- 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, +- 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, +- 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, +- 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, +- 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, +- 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, +- 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, +- 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, +- 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, +- 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 1, 12, +- 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, +- 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, +- 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, +- 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, +- 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, +- 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, 9, 26, 26, 9, 26, 5, +- 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, +- 18, 22, 5, 12, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, +- 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, +- 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, +- 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, +- 21, 14, 7, 15, 9, 12, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, +- 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, +- 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, ++ 42, 42, 42, 69, 60, 46, 42, 42, 42, 42, 42, 42, 42, 42, 69, 60, ++ 60, 60, 46, 60, 60, 60, 60, 60, 60, 60, 69, 21, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 55, 42, 42, 16, 16, 16, 16, 16,123, 16, 16, ++ 42, 42, 42, 67, 39, 39, 39, 39, 7, 7, 7, 7, 7, 7, 7, 70, ++ 36, 36, 36, 36, 36, 36, 42, 42, 7, 7, 7, 7, 7, 7, 7,171, ++ 36, 36, 36, 36, 36, 75, 42, 42,172, 7, 7, 7, 7, 7, 7, 84, ++ 36, 63, 36, 64, 36, 36, 36, 42, 36, 36, 63, 42, 42, 42, 42, 75, ++ 16, 16, 42, 42, 42, 67, 39, 39, 27, 27, 27, 27, 27, 27,145, 27, ++ 173, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,145, ++ 27, 27, 27, 27, 27, 27, 83, 60, 60, 60, 60, 60, 60, 25, 40, 40, ++ 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, ++ 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, ++ 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, ++ 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, ++ 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 6, 6, ++ 24, 24, 6, 24, 12, 12, 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, ++ 9, 6, 5, 21, 17, 17, 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, ++ 12, 21, 7, 21, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, ++ 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, ++ 21, 1, 24, 7, 1, 12, 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, ++ 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, ++ 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, ++ 10, 21, 17, 21, 11, 12, 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, ++ 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, ++ 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, ++ 9, 26, 26, 9, 26, 5, 7, 5, 5, 26, 14, 9, 5, 14, 14, 15, ++ 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 22, 21, 21, 22, ++ 18, 17, 26, 6, 7, 14, 17, 22, 26, 14, 17, 6, 14, 6, 12, 24, ++ 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, ++ 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, ++ 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, 7, 15, 9, 12, 12, 17, ++ 13, 15, 26, 10, 10, 1, 13, 23, 7, 13, 23, 15, 0, 1, 2, 3, ++ 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, ++ 0, 0, 15, 0, 16, 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, 17, ++ 18, 19, 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, 17, 18, 19, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, ++ 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 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, 35, 0, 0, 0, ++ 0, 36, 0, 37, 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, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, +- 31, 32, 33, 34, 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, 35, 0, 0, 0, 0, 36, 0, 37, 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, 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, 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, 44, ++ 45, 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, 0, 0, 0, 0, 0, 0,118, 0,119, + 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, +@@ -5044,405 +4791,411 @@ _hb_ucd_u8[13730] = + 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, 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, 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, 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, 33, 17, 49, +- 17, 17, 84, 97,135,145, 26, 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, ++ 57, 58, 0, 0, 0, 59, 60, 61, 62, 0, 0, 0, 0, 63, 52, 0, ++ 64, 65, 0, 0, 66, 0, 0, 0, 67, 68, 0, 0, 0, 69, 0, 70, ++ 71, 72, 73, 74, 1, 75, 0, 76, 77, 78, 0, 0, 79, 80, 0, 0, ++ 0, 81, 0, 0, 1, 1, 0, 0, 82, 0, 0, 83, 0, 0, 0, 0, ++ 79, 84, 0, 85, 0, 0, 0, 0, 0, 80, 86, 0, 87, 0, 52, 0, ++ 1, 80, 0, 0, 88, 0, 0, 89, 0, 0, 0, 0, 0, 90, 57, 0, ++ 0, 0, 0, 0, 0, 91, 92, 0, 0, 86, 0, 0, 33, 0, 0, 93, ++ 0, 0, 0, 0, 94, 0, 0, 0, 0, 49, 0, 0, 95, 0, 0, 0, ++ 0, 96, 97, 0, 0, 98, 0, 0, 99, 0, 0, 0,100, 0, 0, 0, ++ 101, 0, 0, 0,102, 0, 0, 0, 0,103,104, 95, 0, 0,105, 0, ++ 0, 0, 86, 0, 0,106, 0, 0, 0,107,108, 0, 0,109,110, 0, ++ 0, 0, 0, 0, 0,111, 0, 0,112, 0, 0, 0, 0,113, 33, 0, ++ 114,115,116, 57, 0, 0,117, 35, 0, 0,118, 0, 0, 0,119, 0, ++ 0, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,122, 90, 0, ++ 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,123, 0, 0, 0, 0,124, ++ 0, 0,125, 0, 0, 0, 0,123, 0, 0,126, 0, 0, 0, 0, 0, ++ 81, 0, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,129, 0,130, ++ 0, 0, 0, 0,131,132,133, 0,134, 0,135, 0, 0, 0,136,137, ++ 138, 0, 79, 0, 0, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 0, ++ 140, 0, 0, 0,141, 0, 0, 0,142,143, 0,144, 0, 0,145, 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, 1, 1, 1, 1, 41, 1, 21, 87, 0, 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, 90, 9, 12, 4, 91, 8, ++ 92, 47, 0, 58, 50, 0, 21, 1, 21, 93, 94, 1, 1, 1, 1, 95, ++ 96, 97, 98, 1, 99, 58, 81,100,101, 4, 58, 0, 0, 0, 0, 0, ++ 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,102,103, 0, 0, ++ 104, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, ++ 0, 62, 0, 0,105, 68, 61, 0, 0, 0, 78, 0, 0, 0,106,107, ++ 58, 38, 81, 0, 0, 0, 0, 0, 0,108, 1, 14, 4, 12, 84, 0, ++ 0, 0, 0, 38, 90, 0, 0, 0, 0,109, 0, 0,110, 61, 0,111, ++ 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, ++ 112, 51, 0,112, 14, 52,113, 41, 0, 0, 62, 0, 0, 61, 0, 0, ++ 114, 0, 90, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,114, ++ 0, 0, 0, 0,115, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, ++ 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,116, 0, 0, 0, 55, 0, ++ 0, 0, 0,116, 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, 92, ++ 0, 0, 1, 90, 0, 0,117, 0, 0, 0, 0, 0, 0,118, 0,119, ++ 120,121,122, 0,105, 4,123, 49, 23, 0, 0, 0, 38, 50, 38, 58, ++ 0, 0, 1, 90, 1, 1, 1, 1, 39, 1, 48,106, 90, 0, 0, 0, ++ 0, 1, 0, 0, 0,124, 0, 0, 0,113, 19, 59, 0, 38, 0, 81, ++ 0, 0, 4,123, 0, 0, 0, 1,125, 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,234, 0, 0, 9, 9, 0, 0, ++ 7, 0,230,230,230, 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, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 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,177, 0, 1, 2, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, +- 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, +- 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, +- 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, +- 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, +- 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, +- 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, +- 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, +- 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, +- 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, +- 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, +- 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, +- 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, +- 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, +- 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, +- 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, +- 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, +- 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, +- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, +- 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, +- 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, +- 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, +- 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, +- 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, +- 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, +- 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, +- 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, +- 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, +- 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, +- 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, +- 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, +- 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, +- 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, +- 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, +- 3, 15, 3, 16, 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, 18, 0, 0, 1, 2, 3, +- 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, +- 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, +- 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, +- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, +- 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +- 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, +- 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, +- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, +- 31, 31, 31, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 57, +- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58, 31, 31, 31, +- 59, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, +- 63, 64, 65, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, +- 31, 31, 31, 66, 67, 68, 31, 31, 31, 31, 69, 31, 31, 31, 31, 31, +- 31, 31, 17, 70, 71, 72, 17, 17, 73, 74, 31, 75, 76, 77, 78, 79, +- 80, 31, 81, 82, 17, 83, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, +- 23, 23, 23, 84, 31, 31, 31, 31, 23, 84, 31, 31, 23, 23, 31, 31, +- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, +- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 85, 0, 0, 1, +- 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 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, 25, 26, 19, 27, +- 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, +- 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, +- 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, +- 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, +- 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, +- 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, +- 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, +- 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, +- 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, +- 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +- 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, +- 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, +- 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, +- 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, +- 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, +- 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, +- 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, +- 151,152,153,154,155,155,155,155,155,155, 4, 4,156,157,158,159, +- 160,161,162,163,164,165,166,167,168,169,170,170,171,171,172,172, +- 173,174,174,174, 19, 19,175,176,177,178,179,180,181,181,182,183, +- 184,185,186,187,188,188,189,190,191,192,193,193,194,194,195,195, +- 128,128,196,196,197,198,199,200,201,201,128,128,202,202,203,203, +- 204,204,205,205,206,207,208,209, 28, 28,210,210,211,212,213,213, +- 214,215,216,216,128,128,217,217,218,218,219, 34,220,220,220,220, +- 220,220,220,220,220,220,220,220,220,220,128,128,128,128,128,128, +- 128,128,221,221,222,222,222,222,222,222,222,222,223,223,223,223, +- 223,223,223,223,223,223,128,128,128,128,128,128,128,128,128,128, +- 224,224,128,128,110,110,110,110,110,110,110,110,110,225,226,227, +- 228,228,228,228,128,128,128,128,229,229,128,128,230,230,230,230, +- 231,231,231,232,233,233,233,233,233,233,233,233,233,233,233,233, +- 234,234,234,234,234,234,234,234,233,233,128,128,128,128,128,128, +- 128,128,104,104,235,236,236,236,237,238,239,239,239,239,239,239, +- 128,128,128,128,240,240,241, 0,128,128,128,128, 0, 0, 0, 0, +- 7,242, 0, 0, 0, 0, 0, 0, 0,243,244, 0, 77, 77, 0, 0, +- 0, 0,128,128,245,245,245,245,245,245,245,245,245,245,245,245, +- 128,128,128,128,128,128,128,128, 4, 4,128,128,246, 11, 11, 11, +- 247,247,128,128,128,128,248,249,128,128,128,128,128,128,250,250, +- 128,128,251,251,128,128,128,128,128,128, 48, 48,252,252,252,252, +- 253,253,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, +- 128,128,128,128,254, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, +- 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0, +- 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, +- 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, +- 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 14, 13, 13, 13, +- 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, +- 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, +- 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, +- 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 31, 21, 32, 32, 32, 32, +- 32, 33, 34, 32, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, +- 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, +- 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44, +- 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49, +- 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 53, 53, 53, 53, +- 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, +- 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64, +- 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 67, 67, 67, 67, +- 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, +- 71, 71, 71, 71, 71, 71, 71, 8, 72, 72, 72, 72, 73, 73, 73, 73, +- 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, +- 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84, +- 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, +- 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, +- 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, +- 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 13, 13, 94, 94, 94, 94, +- 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102, +- 102,102,102,103,104,104,104,105, 52, 0,104,104, 0, 0, 0,102, +- 52, 52, 0, 0, 0, 0, 52,106, 0,102,102,107,102,102,102,102, +- 102,108, 0, 0,109,109,109,109,109,110,110,110,111,111,111,111, +- 13, 13,112,112,112,112,112,112, 0, 0,113, 4,114, 4, 4, 4, +- 115,115,115, 0,116,116,116,116,117,117,117,117,117,117, 32, 32, +- 118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, 49, 49, +- 123,123,123,123,123,123, 49, 49,124,124,124,124,124,124,125,125, +- 53, 53, 53, 4, 4,126,127, 54,125,125,125,125,128,128,128,128, +- 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21,130, 8, 0,131, 0, +- 0, 0, 0, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101, +- 102,134, 52, 52,135,135,135,135, 11, 0, 11, 11, 11, 0, 0,136, +- 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142, +- 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146, +- 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151, +- 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, +- 155,155,156,156,157,157,157,157,157,157,158,158,159,159,160,160, +- 160,160,160,160,161,161,162,162,162,162,162,162,163,163,163,163, +- 163,163,164,164,165,165,165,165,166,166,166,166,167,167,167,167, +- 168,168,169,169,170,170,170,170,171,171,171,171,172,172,172,172, +- 173,173,173,173,174,174,174,174,175,175,175,175,176, 21, 21, 21, +- 177,177,177,178,178,178,178,179,179,179,179,180,180,180,181,181, +- 182,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, +- 185,186,186,186,187,187,187,187,187,187,188, 43,189,189,189,189, +- 190,190,190,191,191,191,191,191,192,192,192,193,192,192,192,192, +- 194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197, +- 198,198,198,198,198,198, 66, 66,199,199,199,199,199, 49, 49, 49, +- 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, +- 204,204,204,204,205,205,205,205,205,206,206,206,206,206,206, 55, +- 207,207,207,207,208,208,208,208,209,209,209,209,209,209,209,210, +- 210,210,210,210,211,211,211,211,211,211,212,212,212,212,212,212, +- 213,213,213,213,214,214,214,214,110,110,110,110,215,215,215,215, +- 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, +- 220,220,220,221,221,221,221,221,221,222,222,222,223,223,223,223, +- 224,224,224,224,225,225,225,225,226,226,226,226,226,226,227, 94, +- 228,228,228,228,229,229,229,229,230, 99, 99, 99, 99, 99, 99, 99, +- 99, 99,102,231, 99,232,102,233,233,233,233,233,234,234,234,234, +- 234,234, 0, 0, 8, 0, 0, 0, 0, 0,235,236,237, 0,238, 0, +- 239,239,239,239, 91, 91, 91, 13,240,240,240,240,241,241,241,241, +- 242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245, +- 246,246,246,246,247, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, +- 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, +- 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, +- 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, +- 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, +- 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, +- 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, +- 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, +- 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, +- 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, +- 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, +- 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, +- 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, +- 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, +- 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, +- 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, +- 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, +- 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, +- 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, +- 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, +- 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, +- 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, +- 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, +- 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99, +- 100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0, +- 105,106,106,106,106,106,106,106,106,106,107,105,108,109,109,109, +- 109,109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, +- 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114, +- 115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, +- 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120, +- 121,121,121,121,121,121,121,122,123,123,123,123,124,124,124,124, +- 124,124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, +- 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, +- 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109, +- 109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139, +- 140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142, +- 143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146, +- 147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150, +- 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, +- 155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158, +- 159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162, +- 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, +- 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, +- 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, +- 175,175,175,175,176,176,176,176,177, 20, 20, 20,178,178,178,178, +- 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182, +- 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, +- 187,187,187,187,188,188,188,188,189, 45, 45, 45,190,190,190,190, +- 191,191,191,191,192,192,192,192,193,193,193,193,193,193,194,193, +- 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, +- 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, +- 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, +- 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, +- 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214, +- 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, +- 219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222, +- 223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226, +- 227,227,227,227,228,229,229,229,230,230,230,230,229,229,229,229, +- 231,106,106,106,232,106,106,106,106,233,109,109,234,234,234,234, +- 235,235,235,235, 0,236, 86, 0, 0, 0,236, 7, 82,138, 7, 0, +- 0, 0,237, 86,238,238,238,238,239,239,239,239,240,240,240,240, +- 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244, +- 245,245,245,245,246, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, +- 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, +- 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, +- 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, +- 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, +- 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, +- 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, +- 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, +- 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, +- 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, +- 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, +- 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, +- 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, +- 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, +- 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, +- 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, +- 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, +- 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, +- 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, +- 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, +- 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, +- 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, +- 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, +- 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, +- 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, +- 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, +- 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, +- 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, +- 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, +- 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, +- 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, +- 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, +- 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, +- 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, +- 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, +- 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, +- 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, +- 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, +- 106,106,106,106,104,104,104,104,161,161,161,161,170,170,170,170, +- 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120, +- 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, +- 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88, +- 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, +- 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130, +- 144,144,144,144,165,165,165,165,156,156,156,156,156,156, 3, 3, +- 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, +- 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, +- 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, +- 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, +- 107,107,107, 1,171,171,171,171,137,137,137,137,124,124,124,124, +- 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, +- 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, +- 141,141,141,141,140,140,140,140,121,121,121,121,169,169,169,169, +- 133,133,133,133,134,134,134,134,138,138,138,138,143,143,143,143, +- 145,145,145,145,163,163,163,163, 63, 63, 63, 63,157,157,157,157, +- 80, 80, 80, 80,127,127,127,127,166,166,166,166,115,115,115,115, +- 159,159,159,159,103,103,103,103,119,119,119,119,167,167,167,167, +- 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, +- 136,136,136,136, 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, +- 139,139,139,139,105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1, +- 131,131,131,131,151,151,151,151,160,160,160,160,152,152,152,152, +- 164,164,164,164,168,168,168,168,113,113,113,113,132,132,132,132, +- 15, 0, 0, 0, 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, ++ 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, ++ 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, ++ 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, ++ 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, ++ 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, ++ 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, ++ 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, ++ 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, ++ 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, ++ 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, ++ 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, ++ 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, ++ 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, ++ 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, ++ 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, ++ 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, ++ 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, ++ 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, ++ 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, ++ 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, ++ 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, ++ 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, ++ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, ++ 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, ++ 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, ++ 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, ++ 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, ++ 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, ++ 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, ++ 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, ++ 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, ++ 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, ++ 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, ++ 0, 0, 16, 50, 84,118,136,152,186,187,187,187,187,187,187,187, ++ 187,187,187,187,187,187,187,187,187,187,187,187,187,187, 12, 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, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 21, 22, ++ 23, 24, 25, 26, 27, 28, 29, 30, 31, 19, 32, 33, 33, 33, 33, 33, ++ 34, 19, 19, 19, 19, 19, 19, 35, 19, 36, 37, 38, 38, 38, 38, 38, ++ 38, 39, 40, 19, 19, 19, 19, 19, 19, 19, 41, 42, 19, 19, 43, 19, ++ 19, 19, 44, 45, 9, 46, 47, 48, 49, 50, 51, 52, 9, 9, 19, 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, 53, 19, 19, 53, 19, 13, ++ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 54, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 55, ++ 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, ++ 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ++ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, ++ 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, 35, 36, 37, 38, 39, ++ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 2, 2, 51, 51, 52, ++ 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, ++ 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61, 56, 62, 62, 63, 64, ++ 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, ++ 62, 62, 71, 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, ++ 73, 74, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, ++ 32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, ++ 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89, 91, 92, 93, 94, 95, ++ 95, 96, 97, 87, 98, 99,100,101,102,103,104,105,105,105, 2,106, ++ 107,108,109,110,111,112,113,114,115,116,117, 89,118,119,120,121, ++ 122,123,124,125,126,127,128,129,130, 87,131,132,133,134, 87,135, ++ 136,137,138,139,140,141,142,143,144,145,146, 87,147,148,149,150, ++ 150,150,150,150,150,150,150,150,150,150, 87, 87, 87, 87, 87, 87, ++ 87, 87, 87, 87, 87, 87,151,152,152,152,152,152,152,152,152,153, ++ 153,153,153,153, 87, 87, 87, 87, 87,154, 87, 87, 87, 87, 87,155, ++ 155,155,155,156,157,158,158, 87, 87,159, 87,160,161,162,163,164, ++ 164,164,164,164,164,164,164,164,164,164,164,164,164,165,165,165, ++ 165,164,164, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,166,167, ++ 168,169,170,170,170, 87, 87,171,172, 87, 87, 87, 87, 87, 87, 56, ++ 56, 56, 56, 56, 56,173, 56, 56, 56,174,175, 51, 56, 56, 87,176, ++ 176,176,176,176,176, 87, 87, 87, 87, 87, 87, 87, 87, 2, 87,177, ++ 6,178, 87, 87,179, 87, 87, 87,180, 87,181, 87,182, 87, 33,183, ++ 183,184, 87, 87, 87, 87, 87, 56, 56, 56, 87, 89, 89, 87, 87, 56, ++ 56, 56, 56,185, 87, 56, 56, 62, 62, 62, 62, 62, 87, 87, 87, 62, ++ 87, 87, 87, 87, 87, 87, 87, 56, 87,186,186, 0, 1, 2, 2, 0, ++ 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, ++ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, ++ 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, 11, 11, 12, 11, 13, ++ 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, ++ 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 19, ++ 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, 26, ++ 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, ++ 29, 29, 29, 30, 30, 26, 21, 21, 21, 21, 21, 21, 21, 31, 21, 32, ++ 32, 32, 32, 32, 33, 34, 32, 35, 35, 35, 35, 35, 35, 35, 35, 36, ++ 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, ++ 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, ++ 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, ++ 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, ++ 44, 44, 45, 44, 44, 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 47, ++ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 49, ++ 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, ++ 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, ++ 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 56, ++ 56, 57, 57, 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, ++ 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 66, ++ 66, 66, 55, 55, 55, 55, 55, 67, 67, 67, 67, 67, 68, 68, 68, 69, ++ 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, 71, 71, 71, 71, 71, ++ 71, 71, 8, 8, 8, 8, 8, 72, 72, 72, 72, 72, 72, 72, 72, 73, ++ 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, ++ 50, 50, 50, 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, ++ 4, 4, 84, 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 85, ++ 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, 0, 8, 8, 8, 0, ++ 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 90, 90, 90, 90, 90, 91, ++ 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, 92, 92, 92, 92, 50, ++ 50, 50, 93, 93, 93, 93, 93, 53, 53, 53, 53, 53, 53, 13, 13, 94, ++ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, ++ 0, 96, 97, 98, 99, 99, 99, 99,100,101,102,102,102,102,103,104, ++ 104,104,105, 52, 52, 52, 52, 52, 0,104,104, 0, 0, 0,102, 52, ++ 52, 0, 0, 0, 0, 52,106, 0, 0, 0, 0, 0,102,102,107,102, ++ 102,102,102,102,108, 0, 0, 94, 94, 94, 94, 0, 0, 0, 0,109, ++ 109,109,109,109,109,109,109,109,109,109,109,109,110,110,110,111, ++ 111,111,111,111,111,111,111,111,111,111,111, 13, 13, 13, 13, 13, ++ 13,112,112,112,112,112,112, 0, 0,113, 4, 4, 4, 4, 4,114, ++ 4, 4, 4, 4, 4, 4, 4,115,115,115, 0,116,116,116,116,117, ++ 117,117,117,117,117, 32, 32,118,118,119,120,120,120, 52, 52,121, ++ 121,121,121,122,121, 49, 49,123,123,123,123,123,123, 49, 49,124, ++ 124,124,124,124,124,125,125, 53, 53, 53, 4, 4,126,127, 54, 54, ++ 54, 54, 54,125,125,125,125,128,128,128,128,128,128,128,128, 4, ++ 129, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, ++ 21, 21,130, 21, 21, 21, 21, 8, 0,131, 0, 0, 0, 0, 21, 21, ++ 21, 21, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101,102, ++ 134, 52, 52, 52, 52, 0, 0,135,135,135,135,135,135,135,135, 0, ++ 0, 0, 0, 11, 11, 11, 11, 11, 0, 11, 11, 11, 0, 0,136,137, ++ 137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142,143, ++ 143,144,144,144,144,144,144,145,145,145,145,145,146,146,146,147, ++ 147,147,148,148,148,148,148,149,149,149,150,150,150,150,151,151, ++ 151,151,151,152,152,152,152,153,153,153,153,153,153,153,153,154, ++ 154,154,154,155,155,156,156,157,157,157,157,157,157,158,158,159, ++ 159,160,160,161,161,161,161,162,162,163,163,163,163,163,163,164, ++ 164,164,164,164,164,165,165,166,166,166,166,167,167,167,167,168, ++ 168,168,168,169,169,170,170,171,171,171,171,171,171,171,171,172, ++ 172,172,172,172,172,172,172,173,173,173,173,173,173,173,173,174, ++ 174,174,174,175,175,175,175,175,175,175,175,175,175,175,175,176, ++ 176,176,176,177, 21, 21, 21,178,178,178,179,179,179,179,180,180, ++ 180,180,181,181,181,182,182,183,183,183,183,183,183,183,183,184, ++ 184,184,184,184,185,185,185,186,186,186,186,186,187,187,187,188, ++ 188,188,188,188,188,189, 43,190,190,190,190,190,190,190,190,191, ++ 191,191,192,192,192,192,192,193,193,193,194,193,193,193,193,195, ++ 195,195,195,195,195,195,195,196,196,196,196,196,196,196,196,197, ++ 197,197,197,197,197,197,197,198,198,198,198,198,198,198,198,199, ++ 199,199,199,199,199, 66, 66,200,200,200,200,200, 49, 49, 49,201, ++ 201,201,201,201,201,201,201,202,202,202,202,202,202,202,202,203, ++ 203,203,203,203,203,203,203,204,204,204,204,204,204,204,204,205, ++ 205,205,205,205,205,205,205,206,206,206,206,206,207,207,207,207, ++ 207,207, 55,208,208,208,208, 32, 32, 32, 32, 32, 32,188,188,209, ++ 209,209,209,209,209,209,209,210,210,210,210,210,210,210,211,211, ++ 211,211,211,211,211,211,211,212,212,212,212,212,212,213,213,213, ++ 213,213,214,214,214,214,214,215,215,215,215,215,215,215,215,216, ++ 216,216,216,216,216,216,216,110,110,110,110, 39, 39, 39, 39,217, ++ 217,217,217,217,217,217,217,218,218,218,218,218,218,218,218,219, ++ 219,219,219,219,219,219,219,220,220,220,220,220,220,220,220,221, ++ 221,221,221,221,221,221,221,112,112,112,112,112,112,112,112,112, ++ 112,112,112,222,222,222,223,223,223,223,223,223,224,224,224,225, ++ 225,225,225,225,225,225,225,226,226,226,226,226,226,226,226,227, ++ 227,227,227,227,227,227,227,227,227,228,228,228,228,228,228,229, ++ 229,229,229,229,229,229,229,229,229,229,229,229,229,230, 94,231, ++ 231,231,231,231,231,231,231,232,232,232,232,232,232,232,232,102, ++ 102,102,102,102,102,102,102,233, 99, 99, 99, 99, 99, 99, 99, 99, ++ 99, 99, 99, 99, 99, 99, 99, 99, 99,102,234, 99,235,102,236,236, ++ 236,236,236,236,236,236,236,237,237,237,237,237,237,237,237,237, ++ 237, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,238,239,240, 0,241, 0, 0, 0, 0, 0,242, ++ 242,242,242,242,242,242,242, 91, 91, 91, 13, 13, 13, 13, 13,243, ++ 243,243,243,243,243,243,243,244,244,244,244,245,245,245,245,246, ++ 246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,248, ++ 248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250, ++ 250,250,250,250,250,250,250,251, 0, 0, 0, 0, 0, 0, 0, 8, ++ 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, 2, 2, 2, ++ 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, ++ 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, ++ 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, 14, ++ 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, 19, ++ 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, 22, ++ 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, 27, ++ 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, ++ 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, 33, ++ 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, ++ 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, ++ 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 48, ++ 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, 53, ++ 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, 57, ++ 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, ++ 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, 66, ++ 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, 71, ++ 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, ++ 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, ++ 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, 83, ++ 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, 90, ++ 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, 1, ++ 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, 97, ++ 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99,100, ++ 100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0,105, ++ 106,106,106,106,106,106,106,106,106,107,105,108,109,109,109,109, ++ 109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, 55, ++ 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114,115, ++ 115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, 2, ++ 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120,121, ++ 121,121,121,121,121,121,122,123,123,123,123,124,124,124,124,124, ++ 124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, 2, ++ 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, 20, ++ 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109,109, ++ 109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139,140, ++ 140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142,143, ++ 143,143,143,144,144,144,144,145,145,145,145,146,146,146,146,147, ++ 147,147,147,148,148,148,148,149,149,149,149,150,150,150,150,151, ++ 151,151,151,152,152,152,152,153,153,153,153,154,154,154,154,155, ++ 155,155,155,156,156,156,156,157,157,157,157,158,158,158,158,159, ++ 159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,163, ++ 163,163,163,164,164,164,164,165,165,165,165,166,166,166,166,167, ++ 167,167,167,168,168,168,168,169,169,169,169,170,170,170,170,171, ++ 171,171,171,172,172,172,172,173,173,173,173,174,174,174,174,175, ++ 175,175,175,176,176,176,176,177,177,177,177,178, 20, 20, 20,179, ++ 179,179,179,180,180,180,180,181,181,181,181,182,182,182,182,183, ++ 183,183,183,184,184,184,184,185,185,185,185,186,186,186,186,187, ++ 187,187,187,188,188,188,188,189,189,189,189,190, 45, 45, 45,191, ++ 191,191,191,192,192,192,192,193,193,193,193,194,194,194,194,194, ++ 194,195,194,196,196,196,196,197,197,197,197,198,198,198,198,199, ++ 199,199,199,200,200,200,200,201,201,201,201,202,202,202,202,203, ++ 203,203,203,204,204,204,204,205,205,205,205,206,206,206,206,207, ++ 207,207,207,208,208,208,208,209,209,209,209,210,210,210,210,211, ++ 211,211,211,212,212,212,212,213,213,213,213,214,214,214,214,215, ++ 215,215,215,216,216,216,216,217,217,217,217,218,218,218,218,219, ++ 219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223, ++ 223,223,223,224,224,224,224,225,225,225,225,226,226,226,226,227, ++ 227,227,227,228,228,228,228,229,229,229,229,230,230,230,230,231, ++ 232,232,232,233,233,233,233,232,232,232,232,234,106,106,106,235, ++ 106,106,106,106,236,109,109,237,237,237,237,238,238,238,238, 0, ++ 239, 86, 0, 0, 0,239, 7, 82,138, 7, 0, 0, 0,240, 86,241, ++ 241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,245, ++ 245,245,245,246,246,246,246,247,247,247,247,248,248,248,248,249, ++ 249,249,249,250, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, ++ 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 9, ++ 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, 6, ++ 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, ++ 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, 0, ++ 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, ++ 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, 90, ++ 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, 7, ++ 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 11, ++ 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, 23, ++ 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, 24, ++ 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, 25, ++ 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, 8, ++ 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, 28, ++ 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, 0, ++ 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, 43, ++ 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, 32, ++ 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, 58, ++ 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, 76, ++ 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, 1, ++ 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, ++ 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, ++ 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 0, ++ 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 56, ++ 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, 0, ++ 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, 15, ++ 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, ++ 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, 39, ++ 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 60, ++ 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, 69, ++ 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, 68, ++ 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, 19, ++ 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, 1, ++ 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, 0, ++ 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, 41, ++ 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, 40, ++ 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135,106, ++ 106,106,106,104,104,104,104,161,161,161,161,170,170,170,170,110, ++ 110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120,116, ++ 116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72,173, ++ 173,173,173, 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, ++ 88, 88, 88,117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, ++ 83, 83, 83, 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130, ++ 130,130,130,144,144,144,144,165,165,165,165,156,156,156,156,156, ++ 156, 3, 3,147,147,147,147,148,148,148,148,158,158,158,158,153, ++ 153,153,153,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101, ++ 101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, ++ 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109,107, ++ 107,107,107,107,107,107, 1,171,171,171,171,137,137,137,137,124, ++ 124,124,124,123,123,123,123,114,114,114,114,102,102,102,102,126, ++ 126,126,126,142,142,142,142,125,125,125,125,154,154,154,154,150, ++ 150,150,150,141,141,141,141,140,140,140,140,121,121,121,121,169, ++ 169,169,169,133,133,133,133,134,134,134,134,138,138,138,138,143, ++ 143,143,143,175,175,175,175,145,145,145,145,163,163,163,163, 63, ++ 63, 63, 63,157,157,157,157, 80, 80, 80, 80,127,127,127,127,166, ++ 166,166,166,115,115,115,115,159,159,159,159,103,103,103,103,119, ++ 119,119,119,167,167,167,167,146,146,146,146,172,172,172,172, 99, ++ 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136, 17, ++ 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17,139,139,139,139,105, ++ 105,105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151, ++ 151,151,151,160,160,160,160,152,152,152,152,164,164,164,164,168, ++ 168,168,168,174,174,174,174,113,113,113,113,132,132,132,132, 15, ++ 0, 0, 0, 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, +- 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, 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, 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, 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, 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, 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, +@@ -5451,66 +5204,66 @@ _hb_ucd_u8[13730] = + 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, 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, ++ 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, 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, 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, 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, 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, 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, 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, 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, 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,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, 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,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, 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,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, 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,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,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 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, 0,174, 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, 0, 0, 0, 0, 0,175, 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, 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, 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[5080] = ++static const uint16_t _hb_ucd_u16[5104]= + { + 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, +@@ -5563,276 +5316,276 @@ _hb_ucd_u16[5080] = + 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, + 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, +- 47, 47, 47, 324, 31, 325, 47, 47, 47, 47, 47, 326, 146, 47, 47, 47, +- 47, 47, 47, 47, 327, 146, 146, 328, 32, 329, 32, 330, 331, 332, 333, 47, +- 47, 47, 47, 47, 47, 47, 47, 334, 335, 2, 3, 4, 5, 336, 337, 338, +- 47, 339, 47, 47, 47, 47, 340, 341, 342, 145, 145, 343, 220, 220, 220, 344, +- 345, 146, 146, 146, 146, 146, 146, 346, 347, 347, 347, 347, 347, 347, 347, 347, +- 47, 47, 47, 47, 47, 47, 348, 145, 47, 47, 349, 47, 350, 47, 47, 60, +- 47, 351, 47, 47, 47, 352, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, +- 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 351, 9, +- 9, 353, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, +- 47, 47, 47, 47, 47, 354, 47, 355, 47, 47, 356, 145, 145, 145, 47, 357, +- 47, 358, 47, 351, 66, 66, 66, 66, 47, 47, 47, 359, 145, 145, 145, 145, +- 360, 47, 47, 361, 145, 66, 47, 362, 47, 363, 145, 145, 364, 47, 365, 66, +- 47, 47, 47, 366, 47, 367, 47, 367, 47, 366, 144, 145, 145, 145, 145, 145, +- 9, 9, 9, 9, 11, 11, 11, 368, 47, 47, 369, 160, 370, 9, 371, 11, +- 372, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, +- 47, 47, 373, 47, 47, 47, 47, 374, 47, 363, 375, 47, 60, 376, 66, 47, +- 377, 66, 66, 47, 378, 145, 47, 47, 379, 47, 47, 361, 380, 381, 382, 383, +- 180, 47, 47, 384, 385, 47, 47, 160, 97, 47, 386, 387, 388, 47, 47, 389, +- 180, 47, 47, 390, 391, 392, 393, 145, 47, 47, 394, 395, 360, 32, 32, 32, +- 47, 47, 366, 47, 47, 396, 172, 160, 92, 47, 47, 113, 397, 398, 399, 32, +- 47, 47, 47, 400, 401, 402, 403, 32, 47, 47, 47, 404, 405, 406, 47, 47, +- 47, 47, 47, 407, 408, 160, 160, 160, 47, 47, 409, 410, 411, 412, 32, 32, +- 47, 47, 47, 413, 414, 160, 66, 66, 47, 47, 415, 416, 160, 160, 160, 160, +- 47, 417, 418, 419, 47, 47, 47, 47, 47, 47, 394, 420, 66, 66, 66, 66, +- 9, 9, 9, 9, 11, 11, 128, 421, 47, 47, 47, 422, 423, 160, 160, 160, +- 47, 47, 47, 47, 47, 424, 425, 426, 427, 47, 47, 428, 429, 430, 47, 47, +- 431, 432, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, +- 47, 47, 47, 47, 47, 47, 433, 160, 47, 47, 409, 434, 433, 128, 145, 435, +- 47, 156, 436, 437, 32, 32, 32, 32, 47, 47, 47, 360, 438, 160, 47, 47, +- 439, 440, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 441, +- 442, 47, 47, 443, 444, 445, 32, 32, 47, 47, 47, 47, 145, 446, 447, 448, +- 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 433, +- 47, 47, 47, 209, 449, 32, 47, 47, 47, 450, 451, 160, 160, 160, 160, 160, +- 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 452, +- 47, 47, 47, 453, 454, 455, 456, 47, 27, 27, 27, 27, 457, 47, 458, 160, +- 9, 9, 9, 9, 9, 9, 11, 11, 145, 459, 66, 66, 66, 66, 66, 66, +- 47, 47, 47, 47, 396, 460, 426, 426, 461, 462, 27, 27, 27, 27, 463, 426, +- 47, 464, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 160, +- 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 465, 466, +- 467, 146, 468, 146, 146, 146, 146, 146, 146, 146, 146, 146, 469, 146, 146, 146, +- 9, 470, 11, 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, +- 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 471, 472, 11, +- 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 197, 9, 476, 477, 478, 479, +- 11, 480, 9, 481, 482, 483, 484, 11, 485, 9, 486, 11, 487, 160, 160, 160, +- 32, 32, 32, 488, 32, 32, 489, 490, 491, 492, 32, 32, 32, 32, 32, 32, +- 493, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, +- 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 494, 495, 146, 146, 146, +- 47, 47, 450, 32, 47, 47, 374, 496, 47, 47, 47, 47, 47, 47, 497, 160, +- 47, 47, 47, 47, 47, 47, 450, 498, 47, 47, 47, 47, 356, 32, 32, 32, +- 9, 9, 473, 11, 499, 306, 66, 66, 145, 145, 500, 501, 145, 145, 145, 145, +- 145, 145, 502, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, +- 503, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 504, +- 209, 209, 209, 209, 209, 209, 209, 209, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, +- 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, +- 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, +- 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, +- 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, +- 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, +- 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, +- 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, +- 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, +- 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, +- 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, +- 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, +- 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, +- 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, +- 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, +- 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, +- 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, +- 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, +- 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, +- 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, +- 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, +- 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, +- 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, +- 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, +- 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, +- 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, +- 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, +- 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, +- 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, +- 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, +- 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, +- 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, +- 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, +- 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, +- 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, +- 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, +- 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, +- 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, +- 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, +- 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, +- 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, +- 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, +- 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, +- 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, +- 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, +- 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, +- 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, +- 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, +- 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, +- 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, +- 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, +- 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, +- 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, +- 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, +- 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, +- 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, +- 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, +- 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, +- 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, +- 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, +- 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, +- 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, +- 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, +- 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, +- 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, +- 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, +- 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, +- 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, +- 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, +- 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, +- 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, +- 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, +- 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, +- 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, +- 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, +- 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, +- 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, +- 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, +- 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, +- 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, +- 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, +- 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, +- 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, +- 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, +- 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, +- 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, +- 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, +- 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, +- 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, +- 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, +- 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, +- 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, +- 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, +- 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, +- 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, +- 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, +- 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, +- 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, +- 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, +- 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, +- 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, +- 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, +- 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, +- 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, +- 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, +- 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, +- 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, +- 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, +- 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, +- 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0,1936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1938, 0,1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1943,1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, +- 0, 0, 0, 0, 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949, +- 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1953,1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0,1955,1956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1957, 0, 0, 0, 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964, +- 1963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 1967,1966,1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, ++ 47, 47, 47, 324, 325, 326, 47, 47, 47, 47, 47, 327, 146, 47, 47, 47, ++ 47, 328, 47, 47, 329, 146, 146, 330, 32, 331, 32, 332, 333, 334, 335, 47, ++ 47, 47, 47, 47, 47, 47, 47, 336, 337, 2, 3, 4, 5, 338, 339, 340, ++ 47, 341, 47, 47, 47, 47, 342, 343, 344, 145, 145, 345, 220, 220, 220, 346, ++ 347, 146, 146, 146, 146, 146, 146, 348, 349, 349, 349, 349, 349, 349, 349, 349, ++ 47, 47, 47, 47, 47, 47, 350, 145, 47, 47, 351, 47, 352, 47, 47, 60, ++ 47, 353, 47, 47, 47, 354, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, ++ 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 353, 9, ++ 9, 355, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, ++ 47, 47, 47, 47, 47, 356, 47, 357, 47, 47, 358, 145, 145, 145, 47, 359, ++ 47, 360, 47, 353, 47, 47, 47, 47, 47, 47, 47, 361, 145, 145, 145, 145, ++ 362, 47, 47, 363, 145, 66, 47, 364, 47, 365, 145, 145, 366, 47, 367, 66, ++ 47, 47, 47, 368, 47, 369, 47, 369, 47, 368, 144, 145, 145, 145, 145, 145, ++ 9, 9, 9, 9, 11, 11, 11, 370, 47, 47, 371, 160, 372, 9, 373, 11, ++ 374, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, ++ 47, 47, 375, 47, 275, 376, 146, 377, 47, 365, 378, 47, 60, 379, 66, 47, ++ 380, 66, 66, 47, 381, 145, 47, 47, 382, 47, 47, 363, 383, 384, 385, 386, ++ 180, 47, 47, 387, 388, 47, 47, 160, 97, 47, 389, 390, 391, 47, 47, 392, ++ 180, 47, 47, 393, 394, 395, 396, 145, 47, 47, 397, 398, 362, 32, 32, 32, ++ 47, 47, 368, 47, 47, 399, 172, 160, 92, 47, 47, 113, 400, 401, 402, 32, ++ 47, 47, 47, 403, 404, 405, 406, 32, 47, 47, 47, 407, 408, 409, 47, 47, ++ 47, 47, 47, 410, 411, 160, 160, 160, 47, 47, 412, 413, 414, 415, 32, 32, ++ 47, 47, 47, 416, 417, 160, 66, 66, 47, 47, 418, 419, 160, 160, 160, 160, ++ 47, 420, 421, 422, 47, 47, 47, 47, 47, 47, 397, 423, 66, 66, 66, 66, ++ 9, 9, 9, 9, 11, 11, 128, 424, 47, 47, 47, 425, 426, 160, 160, 160, ++ 47, 47, 47, 47, 47, 427, 428, 429, 430, 47, 47, 431, 432, 433, 47, 47, ++ 434, 435, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 436, 429, ++ 47, 47, 47, 47, 47, 47, 437, 160, 47, 47, 412, 438, 437, 128, 145, 439, ++ 47, 156, 440, 441, 32, 32, 32, 32, 47, 47, 47, 362, 442, 160, 47, 47, ++ 443, 444, 160, 47, 47, 445, 160, 160, 47, 47, 47, 47, 47, 47, 47, 446, ++ 447, 47, 47, 448, 449, 450, 32, 32, 47, 47, 47, 47, 145, 451, 452, 453, ++ 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 437, ++ 47, 47, 47, 209, 454, 32, 47, 47, 47, 455, 456, 160, 160, 160, 160, 160, ++ 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 457, ++ 47, 47, 47, 458, 459, 460, 461, 47, 27, 27, 27, 27, 462, 47, 463, 160, ++ 9, 9, 9, 9, 9, 9, 11, 11, 145, 464, 9, 465, 11, 11, 11, 11, ++ 47, 47, 47, 47, 399, 466, 429, 429, 467, 468, 27, 27, 27, 27, 469, 470, ++ 47, 471, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 472, ++ 146, 146, 146, 146, 146, 146, 146, 227, 32, 32, 32, 32, 32, 146, 146, 146, ++ 146, 146, 146, 146, 146, 146, 473, 474, 475, 146, 476, 146, 146, 146, 146, 146, ++ 146, 146, 146, 146, 477, 146, 146, 146, 9, 478, 11, 479, 480, 11, 197, 9, ++ 481, 482, 9, 483, 11, 9, 478, 11, 479, 480, 11, 197, 9, 481, 482, 9, ++ 483, 11, 9, 478, 11, 479, 480, 11, 197, 9, 481, 482, 9, 483, 11, 9, ++ 478, 11, 197, 9, 484, 485, 486, 487, 11, 488, 9, 489, 490, 491, 492, 11, ++ 493, 9, 494, 11, 495, 160, 160, 160, 32, 32, 32, 496, 32, 32, 497, 498, ++ 499, 500, 32, 32, 32, 32, 32, 32, 501, 11, 11, 11, 11, 11, 11, 11, ++ 32, 32, 32, 27, 27, 27, 27, 27, 32, 32, 32, 32, 32, 32, 32, 32, ++ 47, 47, 47, 502, 503, 146, 146, 146, 47, 47, 455, 32, 47, 47, 504, 505, ++ 47, 47, 47, 47, 47, 47, 506, 160, 47, 47, 47, 47, 47, 47, 455, 507, ++ 47, 47, 47, 47, 47, 47, 508, 509, 47, 47, 47, 47, 358, 32, 32, 32, ++ 9, 9, 481, 11, 510, 306, 66, 66, 145, 145, 511, 512, 145, 145, 145, 145, ++ 145, 145, 513, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, ++ 514, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 515, ++ 146, 146, 146, 146, 146, 227, 227, 227, 209, 209, 209, 209, 209, 209, 209, 209, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0,1976,1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, +- 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, +- 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, +- 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, +- 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, +- 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, +- 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, +- 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, +- 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, +- 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, +- 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, +- 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, +- 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, +- 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, +- 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, +- 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, +- 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, +- 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, +- 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, +- 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, +- 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, +- 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, +- 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, +- 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, +- 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, +- 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, +- 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, +- 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, +- 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, +- 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, +- 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, +- 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, +- 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, +- 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, +- 817, 818, 819, 820, 821, 935, 0, 0, ++ 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, ++ 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, ++ 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, ++ 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, ++ 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, ++ 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, ++ 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, ++ 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, ++ 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, ++ 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, ++ 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, ++ 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, ++ 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, ++ 1280, 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, 949,1134,1010, ++ 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, ++ 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, ++ 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, ++ 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, ++ 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, ++ 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, ++ 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, ++ 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, ++ 1514, 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,1446,1458,1468,1476,1480,1486, ++ 1517, 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,1489,1503,1494,1500,1508, 0, ++ 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, ++ 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, ++ 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, ++ 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, ++ 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, ++ 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, ++ 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, ++ 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, ++ 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, ++ 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, ++ 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, ++ 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, ++ 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, ++ 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, ++ 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, ++ 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, ++ 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, ++ 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, ++ 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, ++ 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, ++ 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, ++ 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, ++ 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, ++ 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, ++ 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, ++ 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, ++ 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, ++ 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, ++ 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, ++ 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, ++ 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, ++ 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, ++ 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, ++ 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, ++ 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, ++ 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, ++ 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, ++ 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, ++ 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, ++ 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, ++ 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, ++ 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, ++ 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, ++ 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, ++ 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, ++ 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, ++ 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, ++ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, ++ 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, ++ 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, ++ 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, ++ 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, ++ 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, ++ 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, ++ 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, ++ 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, ++ 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, ++ 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, ++ 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, ++ 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, ++ 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, ++ 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, ++ 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, ++ 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, ++ 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, ++ 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, ++ 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, ++ 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, ++ 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, ++ 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, ++ 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, ++ 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, ++ 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, ++ 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, ++ 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, ++ 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, ++ 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, ++ 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, ++ 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, ++ 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, ++ 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, ++ 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, ++ 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, ++ 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, ++ 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, ++ 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, ++ 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, ++ 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, ++ 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, ++ 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, ++ 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, ++ 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, ++ 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, ++ 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, ++ 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, ++ 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, ++ 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970, ++ 1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979, ++ 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, ++ 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, ++ 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, ++ 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, ++ 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, ++ 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, ++ 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, ++ 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, ++ 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, ++ 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, ++ 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, ++ 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, ++ 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, ++ 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, ++ 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, ++ 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, ++ 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, ++ 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, ++ 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, ++ 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, ++ 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, ++ 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, ++ 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, ++ 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, ++ 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, ++ 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, ++ 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, ++ 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, ++ 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, ++ 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, ++ 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, ++ 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, ++ 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, ++ 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, + }; +-static const int16_t +-_hb_ucd_i16[92] = ++static const int16_t _hb_ucd_i16[92]= + { + 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, + 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, +@@ -5842,39 +5595,33 @@ _hb_ucd_i16[92] = + 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, + }; + +-static inline uint_fast8_t +-_hb_ucd_gc (unsigned u) ++static inline uint8_t _hb_ucd_gc (unsigned u) + { +- return u<1114112u?_hb_ucd_u8[5208+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; ++ return u<1114112 ? _hb_ucd_u8[5296u+((_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 uint_fast8_t +-_hb_ucd_ccc (unsigned u) ++static inline uint8_t _hb_ucd_ccc (unsigned u) + { +- return u<125259u?_hb_ucd_u8[7206+(((_hb_ucd_u8[6638+(((_hb_ucd_u8[6162+(((_hb_ucd_u8[5802+(((_hb_ucd_u8[5556+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; ++ return u<125259 ? _hb_ucd_u8[7322u+((_hb_ucd_u8[6738u+((_hb_ucd_u8[6258u+((_hb_ucd_u8[5890u+((_hb_ucd_u8[5644u+((((((((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 unsigned +-_hb_ucd_b4 (const uint8_t* a, unsigned i) ++static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) + { +- return (a[i>>1]>>((i&1u)<<2))&15u; ++ return (a[i>>1]>>((i&1)<<2))&15; + } +-static inline int_fast16_t +-_hb_ucd_bmg (unsigned u) ++static inline int16_t _hb_ucd_bmg (unsigned u) + { +- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[8098+(((_hb_ucd_u8[7866+(((_hb_ucd_u8[7770+(((_hb_ucd_b4(7706+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; ++ return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8218u+((_hb_ucd_u8[7986u+((_hb_ucd_u8[7890u+((_hb_ucd_b4(_hb_ucd_u8+7826u,((((((((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 uint_fast8_t +-_hb_ucd_sc (unsigned u) ++static inline uint8_t _hb_ucd_sc (unsigned u) + { +- return u<918016u?_hb_ucd_u8[11464+(((_hb_ucd_u8[10472+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[8764+(((_hb_ucd_u8[8460+(((_hb_ucd_u8[8346+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; ++ return u<918016 ? _hb_ucd_u8[11655u+((_hb_ucd_u8[10647u+((_hb_ucd_u8[9151u+((_hb_ucd_u8[8703u+((_hb_ucd_u8[8495u+((_hb_ucd_b4(_hb_ucd_u8+8466u,((((((((((u)>>2))>>2))>>3))>>3))>>4)))<<4)+((((((((((u)>>2))>>2))>>3))>>3))&15)])<<3)+((((((((u)>>2))>>2))>>3))&7)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)] : 2; + } +-static inline uint_fast16_t +-_hb_ucd_dm (unsigned u) ++static inline uint16_t _hb_ucd_dm (unsigned u) + { +- return u<195102u?_hb_ucd_u16[1656+(((_hb_ucd_u8[12834+(((_hb_ucd_u8[12452+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; ++ return u<195102 ? _hb_ucd_u16[1680u+((_hb_ucd_u8[13041u+((_hb_ucd_u8[12659u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)] : 0; + } + +-#endif + ++#endif + + #endif /* HB_UCD_TABLE_HH */ + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh +index 4bc8d64c28f..711dd9b6571 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh +@@ -7,13 +7,13 @@ + * on file with this header: + * + * # emoji-data.txt +- * # Date: 2024-05-01, 21:25:24 GMT +- * # © 2024 Unicode®, Inc. ++ * # Date: 2025-07-25, 17:54:31 GMT ++ * # © 2025 Unicode®, Inc. + * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. + * # For terms of use and license, see https://www.unicode.org/terms_of_use.html + * # + * # Emoji Data for UTS #51 +- * # Used with Emoji Version 16.0 and subsequent minor revisions (if any) ++ * # Version: 17.0 + * # + * # For documentation and usage, see https://www.unicode.org/reports/tr51 + */ +@@ -23,54 +23,62 @@ + + #include "hb-unicode.hh" + +-static const uint8_t +-_hb_emoji_u8[464] = ++#include ++ ++static const uint8_t _hb_emoji_u8[624]= + { + 16, 17, 17, 17, 50, 20, 21, 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,118,152, +- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 2, 0, 3, 4, 0, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, 12, +- 0, 0, 13, 0, 0, 0, 14, 0, 15, 0, 0, 0, 0, 16, 0, 0, +- 17, 17, 18, 19, 20, 17, 17, 21, 17, 17, 22, 17, 23, 17, 24, 25, +- 26, 27, 28, 17, 17, 17, 0, 0, 17, 17, 17, 17, 17, 17, 17, 29, +- 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 4, 0, 0, +- 5, 6, 0, 0, 7, 8, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0, +- 0, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 18, 19, 20, 21, +- 22, 23, 0, 0, 0, 24, 0, 0, 25, 0, 26, 0, 0, 27, 0, 0, +- 28, 0, 0, 0, 16, 16, 16, 16, 29, 9, 0, 30, 31, 32, 16, 33, +- 34, 35, 36, 16, 16, 16, 16, 37, 16, 38, 39, 16, 16, 16, 40, 0, +- 0, 0, 0, 41, 0, 0, 42, 16, 43, 0, 44, 0, 45, 46, 16, 16, +- 47, 48, 49, 16, 16, 16, 16, 38, 0, 0, 0, 0, 0, 66, 0, 0, +- 0, 0, 0, 16, 0, 2, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, +- 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, +- 0,254, 15, 7, 4, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, +- 0, 0, 0,120,191,255,247,255,255,255,255,255, 63, 0,255,255, +- 63,255, 87, 32, 2, 1, 24, 0,144, 80,184, 0,248, 0, 0, 0, +- 0, 0,224, 0, 2, 0, 1,128, 0, 0, 48, 0,224, 0, 0, 24, +- 0, 0, 33, 0, 0, 0, 1, 32, 0, 0,128, 2, 0,224, 0, 0, +- 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, 63, 0, 0, 0, +- 254,255, 0, 4, 0,128,252,247, 0,254,255,255,255,255,255, 7, +- 255,255,255, 63,192,255,255,255,255,255, 0, 0, 0, 0,240,255, +- 0, 0,224,255, 0,240, 0, 0, 0,255, 0,252, 0,255, 0, 0, +- 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255, ++ 0, 0, 1, 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, ++ 2, 3, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, ++ 0, 0, 0, 8, 0, 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, ++ 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 0, ++ 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, ++ 23, 0, 24, 25, 0, 26, 27, 28, 29, 30, 31, 31, 32, 31, 33, 34, ++ 31, 31, 31, 35, 36, 37, 38, 39, 31, 40, 31, 41, 0, 0, 0, 42, ++ 43, 44, 45, 46, 47, 48, 31, 31, 0, 49, 31, 31, 0, 0, 0, 0, ++ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 36, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, 0, 6, 0, 0, ++ 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, 0,254, 15, 7, ++ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 64, 0, ++ 1, 0, 0, 0, 0, 0, 0,120, 31, 64, 50, 33, 77,196, 0, 7, ++ 5,255, 15,128,105, 1, 0,200, 0, 0,252, 26,131, 12, 3, 96, ++ 48,193, 26, 0, 0, 6,191, 39, 36,191, 84, 32, 2, 1, 24, 0, ++ 144, 80,184, 0, 24, 0, 0, 0, 0, 0,224, 0, 2, 0, 1,128, ++ 0, 0, 0, 0, 0, 0, 48, 0,224, 0, 0, 24, 0, 0, 0, 0, ++ 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, ++ 0, 0,128, 2, 0, 0, 0, 0, 16, 0, 0, 0, 0,240, 0, 0, ++ 0, 0,240,255, 0,128, 1, 0, 1,128, 1, 0, 0, 0,192,255, ++ 0, 0, 0, 0, 0, 0, 3,192, 0, 64,254, 7, 0,192,255,255, ++ 255,255,255,255, 63, 0, 0, 0,254,255, 0, 4, 0,128,252,247, ++ 0,254,255,255,192,255,255,255,255,255,255,255,255,255,255,255, ++ 255,255,255,255,243,255,255,255,255,255,207,206,255,255,255,255, ++ 255,255,255,255,255,255,185, 7,255,255,255,255,255,255,255,191, ++ 255,255,255,255,255,255,255, 63, 0,126,255,255,255,128,249, 7, ++ 128, 60, 97, 0, 48, 1, 6, 16, 28, 0, 14,112, 10,129, 8,252, ++ 255,255, 0, 0, 0, 0, 0, 0, 63,248,231,255, 63,250,249,255, ++ 0, 0, 0,252,255,255,255,255, 0,240, 0, 0, 0, 0, 0, 0, ++ 0,255, 0,252, 0, 0, 0, 0, 0,255, 0, 0, 0,192, 0,240, ++ 252,255, 0,254,255,255,255,255, 0,240,255,255,255,255,255,247, ++ 191,255,255,255,255,255,255,255, 0, 0, 0,255, 0,192,255,255, + }; + +-static inline unsigned +-_hb_emoji_b4 (const uint8_t* a, unsigned i) ++static inline uint8_t _hb_emoji_b4 (const uint8_t* a, unsigned i) + { +- return (a[i>>1]>>((i&1u)<<2))&15u; ++ return (a[i>>1]>>((i&1)<<2))&15; + } +-static inline unsigned +-_hb_emoji_b1 (const uint8_t* a, unsigned i) ++static inline uint8_t _hb_emoji_b1 (const uint8_t* a, unsigned i) + { +- return (a[i>>3]>>((i&7u)<<0))&1u; ++ return (a[i>>3]>>((i&7)<<0))&1; + } +-static inline uint_fast8_t +-_hb_emoji_is_Extended_Pictographic (unsigned u) ++static inline uint8_t _hb_emoji_is_Extended_Pictographic (unsigned u) + { +- return u<131070u?_hb_emoji_b1(264+_hb_emoji_u8,((_hb_emoji_u8[144+(((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7u))])<<2)+((u>>5)&3u))])<<5)+((u)&31u)):0; ++ return u<131070 ? _hb_emoji_b1(_hb_emoji_u8+224u,((_hb_emoji_u8[64u+((_hb_emoji_b4(_hb_emoji_u8,((((u)>>6))>>4)))<<4)+((((u)>>6))&15)])<<6)+((u)&63)) : 0; + } + + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh +index 924105001d7..9e6f89365fe 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode.hh +@@ -241,6 +241,57 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE + } + } + ++ static hb_codepoint_t ++ vertical_char_for (hb_codepoint_t u) ++ { ++ switch (u >> 8) ++ { ++ case 0x20: switch (u) { ++ case 0x2013u: return 0xfe32u; // EN DASH ++ case 0x2014u: return 0xfe31u; // EM DASH ++ case 0x2025u: return 0xfe30u; // TWO DOT LEADER ++ case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS ++ } break; ++ case 0x30: switch (u) { ++ case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA ++ case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP ++ case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET ++ case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET ++ case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET ++ case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET ++ case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET ++ case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET ++ case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET ++ case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET ++ case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET ++ case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET ++ case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET ++ case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET ++ case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET ++ case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET ++ } break; ++ case 0xfe: switch (u) { ++ case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE ++ } break; ++ case 0xff: switch (u) { ++ case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK ++ case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS ++ case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS ++ case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA ++ case 0xff1au: return 0xfe13u; // FULLWIDTH COLON ++ case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON ++ case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK ++ case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET ++ case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET ++ case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE ++ case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET ++ case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET ++ } break; ++ } ++ ++ return u; ++ } ++ + struct { + #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; + HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh +index 7fd3bf8828b..3891fb331af 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh +@@ -37,7 +37,7 @@ struct hb_utf8_t + typedef uint8_t codepoint_t; + static constexpr unsigned max_len = 4; + +- static const codepoint_t * ++ static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end, + hb_codepoint_t *unicode, +@@ -106,7 +106,7 @@ struct hb_utf8_t + return text; + } + +- static const codepoint_t * ++ static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start, + hb_codepoint_t *unicode, +@@ -185,7 +185,7 @@ struct hb_utf16_xe_t + typedef TCodepoint codepoint_t; + static constexpr unsigned max_len = 2; + +- static const codepoint_t * ++ static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end, + hb_codepoint_t *unicode, +@@ -217,7 +217,7 @@ struct hb_utf16_xe_t + return text; + } + +- static const codepoint_t * ++ static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start, + hb_codepoint_t *unicode, +@@ -294,7 +294,7 @@ struct hb_utf32_xe_t + typedef TCodepoint codepoint_t; + static constexpr unsigned max_len = 1; + +- static const TCodepoint * ++ static inline const TCodepoint * + next (const TCodepoint *text, + const TCodepoint *end HB_UNUSED, + hb_codepoint_t *unicode, +@@ -306,7 +306,7 @@ struct hb_utf32_xe_t + return text; + } + +- static const TCodepoint * ++ static inline const TCodepoint * + prev (const TCodepoint *text, + const TCodepoint *start HB_UNUSED, + hb_codepoint_t *unicode, +@@ -353,7 +353,7 @@ struct hb_latin1_t + typedef uint8_t codepoint_t; + static constexpr unsigned max_len = 1; + +- static const codepoint_t * ++ static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end HB_UNUSED, + hb_codepoint_t *unicode, +@@ -363,7 +363,7 @@ struct hb_latin1_t + return text; + } + +- static const codepoint_t * ++ static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start HB_UNUSED, + hb_codepoint_t *unicode, +@@ -405,7 +405,7 @@ struct hb_ascii_t + typedef uint8_t codepoint_t; + static constexpr unsigned max_len = 1; + +- static const codepoint_t * ++ static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end HB_UNUSED, + hb_codepoint_t *unicode, +@@ -417,7 +417,7 @@ struct hb_ascii_t + return text; + } + +- static const codepoint_t * ++ static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start HB_UNUSED, + hb_codepoint_t *unicode, +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh +index cd27da96648..b650ca9f066 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh +@@ -32,6 +32,12 @@ + #include "hb-meta.hh" + #include "hb-null.hh" + ++// Change to 1 to force inline vector allocs, to see callsite in malloc-stats tool. ++#if 0 ++#define HB_ALWAYS_INLINE_VECTOR_ALLOCS HB_ALWAYS_INLINE ++#else ++#define HB_ALWAYS_INLINE_VECTOR_ALLOCS ++#endif + + template +@@ -45,6 +51,7 @@ struct hb_vector_t + using c_array_t = typename std::conditional, hb_array_t>::type; + + hb_vector_t () = default; ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t (std::initializer_list lst) : hb_vector_t () + { + alloc (lst.size (), true); +@@ -57,18 +64,21 @@ struct hb_vector_t + { + extend (o); + } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t (const hb_vector_t &o) : hb_vector_t () + { + alloc_exact (o.length); + if (unlikely (in_error ())) return; + copy_array (o.as_array ()); + } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t (array_t o) : hb_vector_t () + { + alloc_exact (o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t (c_array_t o) : hb_vector_t () + { + alloc_exact (o.length); +@@ -84,8 +94,29 @@ struct hb_vector_t + } + ~hb_vector_t () { fini (); } + ++ template ++ void ++ set_storage (Type (&array)[n]) ++ { set_storage (array, n); } ++ void ++ set_storage (hb_array_t array) ++ { set_storage (array.arrayZ, array.length); } ++ template ++ void ++ set_storage (Type *array, unsigned n) ++ { ++ assert (allocated == 0); ++ assert (length == 0); ++ ++ arrayZ = array; ++ length = n; ++ } ++ + template ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + void extend (const Iterable &o) + { + auto iter = hb_iter (o); +@@ -106,12 +137,14 @@ struct hb_vector_t + push_has_room (*iter++); + } + } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + void extend (array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + void extend (c_array_t o) + { + alloc (length + o.length); +@@ -136,10 +169,7 @@ struct hb_vector_t + + void fini () + { +- /* 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) ++ if (is_owned ()) + { + shrink_vector (0); + hb_free (arrayZ); +@@ -147,11 +177,13 @@ struct hb_vector_t + init (); + } + +- void reset () ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ hb_vector_t &reset () + { + if (unlikely (in_error ())) + reset_error (); + resize (0); ++ return *this; + } + + friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept +@@ -237,13 +269,16 @@ struct hb_vector_t + Type * operator + (unsigned int i) { return arrayZ + i; } + const Type * operator + (unsigned int i) const { return arrayZ + i; } + ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push () + { + if (unlikely (!resize (length + 1))) + return std::addressof (Crap (Type)); + return std::addressof (arrayZ[length - 1]); + } +- template Type *push (Args&&... args) ++ template ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ Type *push (Args&&... args) + { + if (unlikely ((int) length >= allocated && !alloc (length + 1))) + // If push failed to allocate then don't copy v, since this may cause +@@ -253,13 +288,20 @@ struct hb_vector_t + + return push_has_room (std::forward (args)...); + } +- template Type *push_has_room (Args&&... args) ++ template ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ Type *push_has_room (Args&&... args) + { + /* Emplace. */ + Type *p = std::addressof (arrayZ[length++]); + return new (p) Type (std::forward (args)...); + } + ++ bool is_owned () const ++ { ++ return allocated != 0 && allocated != -1; ++ } ++ + bool in_error () const { return allocated < 0; } + void set_error () + { +@@ -271,27 +313,40 @@ struct hb_vector_t + assert (allocated < 0); + allocated = -(allocated + 1); + } ++ void ensure_error () ++ { ++ if (!in_error ()) ++ set_error (); ++ } + +- template + 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 + 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,22 +358,33 @@ struct hb_vector_t + new_array[i] = std::move (arrayZ[i]); + arrayZ[i].~Type (); + } +- hb_free (arrayZ); ++ if (is_owned ()) ++ hb_free (arrayZ); + } + return new_array; + } ++ ++ template ++ Type * ++ realloc_vector (unsigned new_allocated, hb_priority<0>) ++ { ++ return _realloc (new_allocated); ++ } ++ template ++ Type * ++ realloc_vector (unsigned new_allocated, hb_priority<0>) ++ { ++ return _malloc_move (new_allocated); ++ } + /* Specialization for types that can be moved using realloc(). */ + template + 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 other) + { +- assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; + } +@@ -362,7 +427,6 @@ struct hb_vector_t + void + copy_array (hb_array_t other) + { +- assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; + } +@@ -372,7 +436,6 @@ struct hb_vector_t + void + copy_array (hb_array_t other) + { +- assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) + new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); + length += other.length; +@@ -385,7 +448,6 @@ struct hb_vector_t + void + copy_array (hb_array_t other) + { +- assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) + { + new (std::addressof (arrayZ[length + i])) Type (); +@@ -398,12 +460,12 @@ struct hb_vector_t + shrink_vector (unsigned size) + { + assert (size <= length); +- if (!std::is_trivially_destructible::value) ++ if (!hb_is_trivially_destructible(Type)) + { + unsigned count = length - size; +- Type *p = arrayZ + length - 1; ++ Type *p = arrayZ + length; + while (count--) +- p--->~Type (); ++ (--p)->~Type (); + } + length = size; + } +@@ -416,6 +478,7 @@ struct hb_vector_t + } + + /* Allocate for size but don't adjust length. */ ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool alloc (unsigned int size, bool exact=false) + { + if (unlikely (in_error ())) +@@ -471,17 +534,64 @@ struct hb_vector_t + + return true; + } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool alloc_exact (unsigned int size) + { + return alloc (size, true); + } + ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS + void clear () + { + resize (0); + } + +- bool resize (int size_, bool initialize = true, bool exact = false) ++ template ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ bool allocate_from_pool (allocator_t *allocator, unsigned size, unsigned int initialize = true) ++ { ++ if (allocator) ++ { ++ assert (!length && !allocated); ++ arrayZ = (Type *) allocator->alloc (size * sizeof (Type), alignof (Type)); ++ if (unlikely (!arrayZ)) ++ { ++ set_error (); ++ return false; ++ } ++ if (initialize) ++ grow_vector (size, hb_prioritize); ++ else ++ length = size; ++ return true; ++ } ++ return resize_full ((int) size, initialize, true); ++ } ++ ++ template ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ bool duplicate_vector_from_pool (allocator_t *allocator, const hb_vector_t &other) ++ { ++ if (unlikely (!allocate_from_pool (allocator, other.length, false))) ++ return false; ++ length = 0; ++ copy_array (other.as_array ()); ++ return true; ++ } ++ ++ template ++ void shrink_back_to_pool (allocator_t *allocator, int size) ++ { ++ unsigned orig_length = length; ++ ++ shrink (size, false); ++ ++ if (allocator && !is_owned ()) ++ allocator->discard (arrayZ + length, (orig_length - length) * sizeof (Type)); ++ } ++ ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ bool resize_full (int size_, bool initialize, bool exact) + { + unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; + if (!alloc (size, exact)) +@@ -501,9 +611,20 @@ struct hb_vector_t + length = size; + return true; + } +- bool resize_exact (int size_, bool initialize = true) ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ bool resize (int size_) ++ { ++ return resize_full (size_, true, false); ++ } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ bool resize_dirty (int size_) ++ { ++ return resize_full (size_, false, false); ++ } ++ HB_ALWAYS_INLINE_VECTOR_ALLOCS ++ bool resize_exact (int size_) + { +- return resize (size_, initialize, true); ++ return resize_full (size_, true, true); + } + + Type pop () +@@ -544,7 +665,7 @@ struct hb_vector_t + + shrink_vector (size); + +- if (shrink_memory) ++ if (is_owned () && shrink_memory) + alloc_exact (size); /* To force shrinking memory if needed. */ + } + +diff --git a/src/java.desktop/share/native/libharfbuzz/hb-version.h b/src/java.desktop/share/native/libharfbuzz/hb-version.h +index e41286d2d8c..c673d1e3612 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb-version.h ++++ b/src/java.desktop/share/native/libharfbuzz/hb-version.h +@@ -41,26 +41,26 @@ HB_BEGIN_DECLS + * + * The major component of the library version available at compile-time. + */ +-#define HB_VERSION_MAJOR 11 ++#define HB_VERSION_MAJOR 12 + /** + * HB_VERSION_MINOR: + * + * The minor component of the library version available at compile-time. + */ +-#define HB_VERSION_MINOR 2 ++#define HB_VERSION_MINOR 3 + /** + * HB_VERSION_MICRO: + * + * The micro component of the library version available at compile-time. + */ +-#define HB_VERSION_MICRO 0 ++#define HB_VERSION_MICRO 2 + + /** + * HB_VERSION_STRING: + * + * A string literal containing the library version available at compile-time. + */ +-#define HB_VERSION_STRING "11.2.0" ++#define HB_VERSION_STRING "12.3.2" + + /** + * HB_VERSION_ATLEAST: +diff --git a/src/java.desktop/share/native/libharfbuzz/hb.hh b/src/java.desktop/share/native/libharfbuzz/hb.hh +index 8c430e5770d..7582abaa933 100644 +--- a/src/java.desktop/share/native/libharfbuzz/hb.hh ++++ b/src/java.desktop/share/native/libharfbuzz/hb.hh +@@ -89,7 +89,6 @@ + #pragma GCC diagnostic error "-Wstring-conversion" + #pragma GCC diagnostic error "-Wswitch-enum" + #pragma GCC diagnostic error "-Wtautological-overlap-compare" +-#pragma GCC diagnostic error "-Wuninitialized" + #pragma GCC diagnostic error "-Wunneeded-internal-declaration" + #pragma GCC diagnostic error "-Wunused" + #pragma GCC diagnostic error "-Wunused-local-typedefs" +@@ -110,11 +109,21 @@ + #pragma GCC diagnostic warning "-Wformat-signedness" + #pragma GCC diagnostic warning "-Wignored-pragma-optimize" + #pragma GCC diagnostic warning "-Wlogical-op" +-#pragma GCC diagnostic warning "-Wmaybe-uninitialized" + #pragma GCC diagnostic warning "-Wmissing-format-attribute" ++#pragma GCC diagnostic warning "-Wpessimizing-move" + #pragma GCC diagnostic warning "-Wundef" + #pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" + #pragma GCC diagnostic warning "-Wunused-but-set-variable" ++#ifdef __clang__ ++// The following are too buggy on gcc ++// https://github.com/harfbuzz/harfbuzz/issues/5589 ++// https://github.com/harfbuzz/harfbuzz/pull/5367 ++#pragma GCC diagnostic warning "-Wmaybe-uninitialized" ++#pragma GCC diagnostic warning "-Wuninitialized" ++#else ++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" ++#pragma GCC diagnostic ignored "-Wuninitialized" ++#endif + #endif + + /* Ignored currently, but should be fixed at some point. */ +@@ -136,6 +145,7 @@ + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + #pragma GCC diagnostic ignored "-Wformat-zero-length" + #pragma GCC diagnostic ignored "-Wmissing-field-initializers" ++#pragma GCC diagnostic ignored "-Wold-style-cast" + #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang + #pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834 + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +@@ -239,6 +249,8 @@ + // clang defines it so no need. + #ifdef __has_builtin + #define hb_has_builtin __has_builtin ++#elif defined(_MSC_VER) ++#define hb_has_builtin(x) 0 + #else + #define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5)) + #endif +@@ -314,6 +326,10 @@ + #endif + #endif + ++#ifndef HB_HOT ++#define HB_HOT __attribute__((hot)) ++#endif ++ + /* + * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 + * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch +@@ -553,4 +569,13 @@ extern "C" void hb_free_impl(void *ptr); + #include "hb-vector.hh" // Requires: hb-array hb-null + #include "hb-object.hh" // Requires: hb-atomic hb-mutex hb-vector + ++ ++/* Our src/test-*.cc use hb_assert(), such that it's not compiled out under NDEBUG. ++ * https://github.com/harfbuzz/harfbuzz/issues/5418 */ ++#define hb_always_assert(x) \ ++ HB_STMT_START { \ ++ if (!(x)) { fprintf(stderr, "Assertion failed: %s, at %s:%d\n", #x, __FILE__, __LINE__); abort(); } \ ++ } HB_STMT_END ++ ++ + #endif /* HB_HH */ diff --git a/jdk8375063-libpng-1.6.54.patch b/jdk8375063-libpng-1.6.54.patch new file mode 100644 index 0000000..9a9e201 --- /dev/null +++ b/jdk8375063-libpng-1.6.54.patch @@ -0,0 +1,4384 @@ +commit c1fe897ce1ce39df9dfc52b1b56a42e6bcfe89ae +Author: Sergey Bylokhov +AuthorDate: Sat Jan 31 07:45:14 2026 +0000 +Commit: Sergey Bylokhov +CommitDate: Sat Jan 31 07:45:14 2026 +0000 + + 8375063: Update Libpng to 1.6.54 + + Backport-of: a2e749572e03dd394d123b701e163e3837472dd0 + +diff --git a/src/java.desktop/share/legal/libpng.md b/src/java.desktop/share/legal/libpng.md +index 8899491c6c0..80d12248ec4 100644 +--- a/src/java.desktop/share/legal/libpng.md ++++ b/src/java.desktop/share/legal/libpng.md +@@ -1,4 +1,4 @@ +-## libpng v1.6.51 ++## libpng v1.6.54 + + ### libpng License +
+@@ -9,8 +9,8 @@ ### libpng License
+ PNG Reference Library License version 2
+ ---------------------------------------
+ 
+-Copyright (C) 1995-2025 The PNG Reference Library Authors.
+-Copyright (C) 2018-2025 Cosmin Truta
++Copyright (C) 1995-2026 The PNG Reference Library Authors.
++Copyright (C) 2018-2026 Cosmin Truta
+ Copyright (C) 1998-2018 Glenn Randers-Pehrson
+ Copyright (C) 1996-1997 Andreas Dilger
+ Copyright (C) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -158,6 +158,7 @@ ### AUTHORS File Information
+ Authors, for copyright and licensing purposes.
+ 
+  * Adam Richter
++ * Alexander Smorkalov
+  * Andreas Dilger
+  * Chris Blume
+  * Cosmin Truta
+@@ -179,6 +180,7 @@ ### AUTHORS File Information
+  * Mike Klein
+  * Pascal Massimino
+  * Paul Schmidt
++ * Petr Simecek
+  * Philippe Antoine
+  * Qiang Zhou
+  * Sam Bushell
+@@ -209,6 +211,8 @@ ### AUTHORS File Information
+     - ZhangLixia (张利霞)
+  * Samsung Group
+     - Filip Wasil
++ * SpacemiT Hangzhou Technology, Co.
++    - Liang Junzhao (梁俊钊)
+ 
+ The build projects, the build scripts, the test scripts, and other
+ files in the "projects", "scripts" and "tests" directories, have
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+index 2478fd0fc08..3bb1baecd23 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+@@ -6304,6 +6304,33 @@ Version 1.6.51 [November 21, 2025]
+   Added GitHub Actions workflows for automated testing.
+   Performed various refactorings and cleanups.
+ 
++Version 1.6.52 [December 3, 2025]
++  Fixed CVE-2025-66293 (high severity):
++    Out-of-bounds read in `png_image_read_composite`.
++    (Reported by flyfish101 .)
++  Fixed the Paeth filter handling in the RISC-V RVV implementation.
++    (Reported by Filip Wasil; fixed by Liang Junzhao.)
++  Improved the performance of the RISC-V RVV implementation.
++    (Contributed by Liang Junzhao.)
++  Added allocation failure fuzzing to oss-fuzz.
++    (Contributed by Philippe Antoine.)
++
++Version 1.6.53 [December 5, 2025]
++  Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic.
++    (Contributed by Alexander Smorkalov.)
++  Fixed a build failure with CMake 4.1 or newer, on Windows, when using
++    Visual C++ without MASM installed.
++
++Version 1.6.54 [January 12, 2026]
++  Fixed CVE-2026-22695 (medium severity):
++    Heap buffer over-read in `png_image_read_direct_scaled.
++    (Reported and fixed by Petr Simecek.)
++  Fixed CVE-2026-22801 (medium severity):
++    Integer truncation causing heap buffer over-read in `png_image_write_*`.
++  Implemented various improvements in oss-fuzz.
++    (Contributed by Philippe Antoine.)
++
++
+ Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
+ Subscription is required; visit
+ https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
+index ea6df986cb6..1b765ae9f96 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
+@@ -4,8 +4,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
+ PNG Reference Library License version 2
+ ---------------------------------------
+ 
+- * Copyright (c) 1995-2025 The PNG Reference Library Authors.
+- * Copyright (c) 2018-2025 Cosmin Truta.
++ * Copyright (c) 1995-2026 The PNG Reference Library Authors.
++ * Copyright (c) 2018-2026 Cosmin Truta.
+  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
+  * Copyright (c) 1996-1997 Andreas Dilger.
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/README b/src/java.desktop/share/native/libsplashscreen/libpng/README
+index 5ea329ee3da..63d1376edf7 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/README
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/README
+@@ -1,4 +1,4 @@
+-README for libpng version 1.6.51
++README for libpng version 1.6.54
+ ================================
+ 
+ See the note about version numbers near the top of `png.h`.
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.c b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+index 7d85e7c8d5f..5636b4a754e 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+@@ -29,7 +29,7 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * Copyright (c) 2018-2025 Cosmin Truta
++ * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+  * Copyright (c) 1996-1997 Andreas Dilger
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -42,7 +42,7 @@
+ #include "pngpriv.h"
+ 
+ /* Generate a compiler error if there is an old png.h in the search path. */
+-typedef png_libpng_version_1_6_51 Your_png_h_is_not_version_1_6_51;
++typedef png_libpng_version_1_6_54 Your_png_h_is_not_version_1_6_54;
+ 
+ /* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
+  * corresponding macro definitions.  This causes a compile time failure if
+@@ -130,7 +130,8 @@ png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
+ #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+ /* Function to allocate memory for zlib */
+ PNG_FUNCTION(voidpf /* PRIVATE */,
+-png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
++png_zalloc,(voidpf png_ptr, uInt items, uInt size),
++    PNG_ALLOCATED)
+ {
+    png_alloc_size_t num_bytes = size;
+ 
+@@ -286,7 +287,8 @@ png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
+ PNG_FUNCTION(png_structp /* PRIVATE */,
+ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+     png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+-    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
++    png_malloc_ptr malloc_fn, png_free_ptr free_fn),
++    PNG_ALLOCATED)
+ {
+    png_struct create_struct;
+ #  ifdef PNG_SETJMP_SUPPORTED
+@@ -390,7 +392,8 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ 
+ /* Allocate the memory for an info_struct for the application. */
+ PNG_FUNCTION(png_infop,PNGAPI
+-png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
++png_create_info_struct,(png_const_structrp png_ptr),
++    PNG_ALLOCATED)
+ {
+    png_inforp info_ptr;
+ 
+@@ -846,8 +849,8 @@ png_get_copyright(png_const_structrp png_ptr)
+    return PNG_STRING_COPYRIGHT
+ #else
+    return PNG_STRING_NEWLINE \
+-      "libpng version 1.6.51" PNG_STRING_NEWLINE \
+-      "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \
++      "libpng version 1.6.54" PNG_STRING_NEWLINE \
++      "Copyright (c) 2018-2026 Cosmin Truta" PNG_STRING_NEWLINE \
+       "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
+       PNG_STRING_NEWLINE \
+       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+@@ -2286,8 +2289,8 @@ png_check_fp_number(png_const_charp string, size_t size, int *statep,
+ int
+ png_check_fp_string(png_const_charp string, size_t size)
+ {
+-   int        state=0;
+-   size_t char_index=0;
++   int state = 0;
++   size_t char_index = 0;
+ 
+    if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
+       (char_index == size || string[char_index] == 0))
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.h b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+index d39ff73552c..ab8876a9626 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+@@ -29,9 +29,9 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * libpng version 1.6.51
++ * libpng version 1.6.54
+  *
+- * Copyright (c) 2018-2025 Cosmin Truta
++ * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+  * Copyright (c) 1996-1997 Andreas Dilger
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -43,7 +43,7 @@
+  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
+  *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
+  *     Glenn Randers-Pehrson
+- *   libpng versions 1.6.36, December 2018, through 1.6.51, November 2025:
++ *   libpng versions 1.6.36, December 2018, through 1.6.54, January 2026:
+  *     Cosmin Truta
+  *   See also "Contributing Authors", below.
+  */
+@@ -55,8 +55,8 @@
+  * PNG Reference Library License version 2
+  * ---------------------------------------
+  *
+- *  * Copyright (c) 1995-2025 The PNG Reference Library Authors.
+- *  * Copyright (c) 2018-2025 Cosmin Truta.
++ *  * Copyright (c) 1995-2026 The PNG Reference Library Authors.
++ *  * Copyright (c) 2018-2026 Cosmin Truta.
+  *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
+  *  * Copyright (c) 1996-1997 Andreas Dilger.
+  *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -267,7 +267,7 @@
+  *    ...
+  *    1.5.30                  15    10530  15.so.15.30[.0]
+  *    ...
+- *    1.6.51                  16    10651  16.so.16.51[.0]
++ *    1.6.54                  16    10654  16.so.16.54[.0]
+  *
+  *    Henceforth the source version will match the shared-library major and
+  *    minor numbers; the shared-library major version number will be used for
+@@ -303,7 +303,7 @@
+  */
+ 
+ /* Version information for png.h - this should match the version in png.c */
+-#define PNG_LIBPNG_VER_STRING "1.6.51"
++#define PNG_LIBPNG_VER_STRING "1.6.54"
+ #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
+ 
+ /* The versions of shared library builds should stay in sync, going forward */
+@@ -314,7 +314,7 @@
+ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+ #define PNG_LIBPNG_VER_MAJOR   1
+ #define PNG_LIBPNG_VER_MINOR   6
+-#define PNG_LIBPNG_VER_RELEASE 51
++#define PNG_LIBPNG_VER_RELEASE 54
+ 
+ /* This should be zero for a public release, or non-zero for a
+  * development version.
+@@ -345,7 +345,7 @@
+  * From version 1.0.1 it is:
+  * XXYYZZ, where XX=major, YY=minor, ZZ=release
+  */
+-#define PNG_LIBPNG_VER 10651 /* 1.6.51 */
++#define PNG_LIBPNG_VER 10654 /* 1.6.54 */
+ 
+ /* Library configuration: these options cannot be changed after
+  * the library has been built.
+@@ -455,7 +455,7 @@ extern "C" {
+ /* This triggers a compiler error in png.c, if png.c and png.h
+  * do not agree upon the version number.
+  */
+-typedef char* png_libpng_version_1_6_51;
++typedef char *png_libpng_version_1_6_54;
+ 
+ /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
+  *
+@@ -814,17 +814,22 @@ typedef png_row_info * * png_row_infopp;
+  * modify the buffer it is passed. The 'read' function, on the other hand, is
+  * expected to return the read data in the buffer.
+  */
+-typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
+-typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t));
+-typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
+-typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
+-    int));
+-typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
+-    int));
++typedef PNG_CALLBACK(void, *png_error_ptr,
++   (png_structp, png_const_charp));
++typedef PNG_CALLBACK(void, *png_rw_ptr,
++   (png_structp, png_bytep, size_t));
++typedef PNG_CALLBACK(void, *png_flush_ptr,
++   (png_structp));
++typedef PNG_CALLBACK(void, *png_read_status_ptr,
++   (png_structp, png_uint_32, int));
++typedef PNG_CALLBACK(void, *png_write_status_ptr,
++   (png_structp, png_uint_32, int));
+ 
+ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+-typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
+-typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
++typedef PNG_CALLBACK(void, *png_progressive_info_ptr,
++   (png_structp, png_infop));
++typedef PNG_CALLBACK(void, *png_progressive_end_ptr,
++   (png_structp, png_infop));
+ 
+ /* The following callback receives png_uint_32 row_number, int pass for the
+  * png_bytep data of the row.  When transforming an interlaced image the
+@@ -836,19 +841,19 @@ typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
+  * find the output pixel (x,y) given an interlaced sub-image pixel
+  * (row,col,pass).  (See below for these macros.)
+  */
+-typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
+-    png_uint_32, int));
++typedef PNG_CALLBACK(void, *png_progressive_row_ptr,
++   (png_structp, png_bytep, png_uint_32, int));
+ #endif
+ 
+ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+-typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
+-    png_bytep));
++typedef PNG_CALLBACK(void, *png_user_transform_ptr,
++   (png_structp, png_row_infop, png_bytep));
+ #endif
+ 
+ #ifdef PNG_USER_CHUNKS_SUPPORTED
+-typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
+-    png_unknown_chunkp));
++typedef PNG_CALLBACK(int, *png_user_chunk_ptr,
++   (png_structp, png_unknown_chunkp));
+ #endif
+ #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+ /* not used anywhere */
+@@ -906,9 +911,10 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef);
+  * ignores the first argument) should be completely compatible with the
+  * following.
+  */
+-typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
+-    png_alloc_size_t));
+-typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
++typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr,
++   (png_structp, png_alloc_size_t));
++typedef PNG_CALLBACK(void, *png_free_ptr,
++   (png_structp, png_voidp));
+ 
+ /* Section 4: exported functions
+  * Here are the function definitions most commonly used.  This is not
+@@ -940,20 +946,22 @@ typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
+  */
+ 
+ /* Returns the version number of the library */
+-PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
++PNG_EXPORT(1, png_uint_32, png_access_version_number,
++   (void));
+ 
+ /* Tell lib we have already handled the first  magic bytes.
+  * Handling more than 8 bytes from the beginning of the file is an error.
+  */
+-PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
++PNG_EXPORT(2, void, png_set_sig_bytes,
++   (png_structrp png_ptr, int num_bytes));
+ 
+ /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+  * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
+  * signature, and non-zero otherwise.  Having num_to_check == 0 or
+  * start > 7 will always fail (i.e. return non-zero).
+  */
+-PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
+-    size_t num_to_check));
++PNG_EXPORT(3, int, png_sig_cmp,
++   (png_const_bytep sig, size_t start, size_t num_to_check));
+ 
+ /* Simple signature checking function.  This is the same as calling
+  * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0).
+@@ -962,21 +970,21 @@ PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
+ 
+ /* Allocate and initialize png_ptr struct for reading, and any other memory. */
+ PNG_EXPORTA(4, png_structp, png_create_read_struct,
+-    (png_const_charp user_png_ver, png_voidp error_ptr,
+-    png_error_ptr error_fn, png_error_ptr warn_fn),
+-    PNG_ALLOCATED);
++   (png_const_charp user_png_ver,
++    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn),
++   PNG_ALLOCATED);
+ 
+ /* Allocate and initialize png_ptr struct for writing, and any other memory */
+ PNG_EXPORTA(5, png_structp, png_create_write_struct,
+-    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+-    png_error_ptr warn_fn),
+-    PNG_ALLOCATED);
++   (png_const_charp user_png_ver,
++    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn),
++   PNG_ALLOCATED);
+ 
+ PNG_EXPORT(6, size_t, png_get_compression_buffer_size,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ 
+-PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
+-    size_t size));
++PNG_EXPORT(7, void, png_set_compression_buffer_size,
++   (png_structrp png_ptr, size_t size));
+ 
+ /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
+  * match up.
+@@ -989,8 +997,8 @@ PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
+  * allocated by the library - the call will return NULL on a mismatch
+  * indicating an ABI mismatch.
+  */
+-PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
+-    png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
++PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn,
++   (png_structrp png_ptr, png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
+ #  define png_jmpbuf(png_ptr) \
+       (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))
+ #else
+@@ -1002,67 +1010,77 @@ PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
+  * will use it; otherwise it will call PNG_ABORT().  This function was
+  * added in libpng-1.5.0.
+  */
+-PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
+-    PNG_NORETURN);
++PNG_EXPORTA(9, void, png_longjmp,
++   (png_const_structrp png_ptr, int val),
++   PNG_NORETURN);
+ 
+ #ifdef PNG_READ_SUPPORTED
+ /* Reset the compression stream */
+-PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
++PNG_EXPORTA(10, int, png_reset_zstream,
++   (png_structrp png_ptr),
++   PNG_DEPRECATED);
+ #endif
+ 
+ /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+ #ifdef PNG_USER_MEM_SUPPORTED
+ PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
+-    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+-    png_error_ptr warn_fn,
++   (png_const_charp user_png_ver,
++    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn,
+     png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+-    PNG_ALLOCATED);
++   PNG_ALLOCATED);
+ PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
+-    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+-    png_error_ptr warn_fn,
++   (png_const_charp user_png_ver,
++    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn,
+     png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+-    PNG_ALLOCATED);
++   PNG_ALLOCATED);
+ #endif
+ 
+ /* Write the PNG file signature. */
+-PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
++PNG_EXPORT(13, void, png_write_sig,
++   (png_structrp png_ptr));
+ 
+ /* Write a PNG chunk - size, type, (optional) data, CRC. */
+-PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
+-    chunk_name, png_const_bytep data, size_t length));
++PNG_EXPORT(14, void, png_write_chunk,
++   (png_structrp png_ptr,
++    png_const_bytep chunk_name, png_const_bytep data, size_t length));
+ 
+ /* Write the start of a PNG chunk - length and chunk name. */
+-PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
++PNG_EXPORT(15, void, png_write_chunk_start,
++   (png_structrp png_ptr,
+     png_const_bytep chunk_name, png_uint_32 length));
+ 
+ /* Write the data of a PNG chunk started with png_write_chunk_start(). */
+-PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
++PNG_EXPORT(16, void, png_write_chunk_data,
++   (png_structrp png_ptr,
+     png_const_bytep data, size_t length));
+ 
+ /* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+-PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
++PNG_EXPORT(17, void, png_write_chunk_end,
++   (png_structrp png_ptr));
+ 
+ /* Allocate and initialize the info structure */
+-PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
+-    PNG_ALLOCATED);
++PNG_EXPORTA(18, png_infop, png_create_info_struct,
++   (png_const_structrp png_ptr),
++   PNG_ALLOCATED);
+ 
+ /* DEPRECATED: this function allowed init structures to be created using the
+  * default allocation method (typically malloc).  Use is deprecated in 1.6.0 and
+  * the API will be removed in the future.
+  */
+-PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
+-    size_t png_info_struct_size), PNG_DEPRECATED);
++PNG_EXPORTA(19, void, png_info_init_3,
++   (png_infopp info_ptr, size_t png_info_struct_size),
++   PNG_DEPRECATED);
+ 
+ /* Writes all the PNG information before the image. */
+ PNG_EXPORT(20, void, png_write_info_before_PLTE,
+-    (png_structrp png_ptr, png_const_inforp info_ptr));
++   (png_structrp png_ptr, png_const_inforp info_ptr));
+ PNG_EXPORT(21, void, png_write_info,
+-    (png_structrp png_ptr, png_const_inforp info_ptr));
++   (png_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ /* Read the information before the actual image data. */
+ PNG_EXPORT(22, void, png_read_info,
+-    (png_structrp png_ptr, png_inforp info_ptr));
++   (png_structrp png_ptr, png_inforp info_ptr));
+ #endif
+ 
+ #ifdef PNG_TIME_RFC1123_SUPPORTED
+@@ -1072,45 +1090,54 @@ PNG_EXPORT(22, void, png_read_info,
+     */
+ #if PNG_LIBPNG_VER < 10700
+ /* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */
+-PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,
+-    png_const_timep ptime),PNG_DEPRECATED);
++PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123,
++   (png_structrp png_ptr, png_const_timep ptime),
++   PNG_DEPRECATED);
+ #endif
+-PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],
+-    png_const_timep ptime));
++PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer,
++   (char out[29], png_const_timep ptime));
+ #endif
+ 
+ #ifdef PNG_CONVERT_tIME_SUPPORTED
+ /* Convert from a struct tm to png_time */
+-PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
+-    const struct tm * ttime));
++PNG_EXPORT(24, void, png_convert_from_struct_tm,
++   (png_timep ptime, const struct tm * ttime));
+ 
+ /* Convert from time_t to png_time.  Uses gmtime() */
+-PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));
++PNG_EXPORT(25, void, png_convert_from_time_t,
++   (png_timep ptime, time_t ttime));
+ #endif /* CONVERT_tIME */
+ 
+ #ifdef PNG_READ_EXPAND_SUPPORTED
+ /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+-PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));
+-PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));
+-PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));
+-PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));
++PNG_EXPORT(26, void, png_set_expand,
++   (png_structrp png_ptr));
++PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8,
++   (png_structrp png_ptr));
++PNG_EXPORT(28, void, png_set_palette_to_rgb,
++   (png_structrp png_ptr));
++PNG_EXPORT(29, void, png_set_tRNS_to_alpha,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_EXPAND_16_SUPPORTED
+ /* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
+  * of a tRNS chunk if present.
+  */
+-PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));
++PNG_EXPORT(221, void, png_set_expand_16,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+ /* Use blue, green, red order for pixels. */
+-PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));
++PNG_EXPORT(30, void, png_set_bgr,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* Expand the grayscale to 24-bit RGB if necessary. */
+-PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
++PNG_EXPORT(31, void, png_set_gray_to_rgb,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+@@ -1120,18 +1147,20 @@ PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
+ #define PNG_ERROR_ACTION_ERROR 3
+ #define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
+ 
+-PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,
++PNG_FP_EXPORT(32, void, png_set_rgb_to_gray,
++   (png_structrp png_ptr,
+     int error_action, double red, double green))
+-PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,
++PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed,
++   (png_structrp png_ptr,
+     int error_action, png_fixed_point red, png_fixed_point green))
+ 
+-PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp
+-    png_ptr));
++PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status,
++   (png_const_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+-PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
+-    png_colorp palette));
++PNG_EXPORT(35, void, png_build_grayscale_palette,
++   (int bit_depth, png_colorp palette));
+ #endif
+ 
+ #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+@@ -1176,10 +1205,10 @@ PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
+ #define PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */
+ #define PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */
+ 
+-PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,
+-    double output_gamma))
+-PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
+-    int mode, png_fixed_point output_gamma))
++PNG_FP_EXPORT(227, void, png_set_alpha_mode,
++   (png_structrp png_ptr, int mode, double output_gamma))
++PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed,
++   (png_structrp png_ptr, int mode, png_fixed_point output_gamma))
+ #endif
+ 
+ #if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+@@ -1269,51 +1298,57 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
+  */
+ 
+ #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+-PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));
++PNG_EXPORT(36, void, png_set_strip_alpha,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+-PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));
++PNG_EXPORT(37, void, png_set_swap_alpha,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+-PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));
++PNG_EXPORT(38, void, png_set_invert_alpha,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+ /* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
+-PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
+-    int flags));
++PNG_EXPORT(39, void, png_set_filler,
++   (png_structrp png_ptr, png_uint_32 filler, int flags));
+ /* The values of the PNG_FILLER_ defines should NOT be changed */
+ #  define PNG_FILLER_BEFORE 0
+ #  define PNG_FILLER_AFTER 1
+ /* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
+-PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
+-    png_uint_32 filler, int flags));
++PNG_EXPORT(40, void, png_set_add_alpha,
++   (png_structrp png_ptr, png_uint_32 filler, int flags));
+ #endif /* READ_FILLER || WRITE_FILLER */
+ 
+ #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+ /* Swap bytes in 16-bit depth files. */
+-PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));
++PNG_EXPORT(41, void, png_set_swap,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+ /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+-PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));
++PNG_EXPORT(42, void, png_set_packing,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+     defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+ /* Swap packing order of pixels in bytes. */
+-PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));
++PNG_EXPORT(43, void, png_set_packswap,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ /* Converts files to legal bit depths. */
+-PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
+-    true_bits));
++PNG_EXPORT(44, void, png_set_shift,
++   (png_structrp png_ptr, png_const_color_8p true_bits));
+ #endif
+ 
+ #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+@@ -1324,12 +1359,14 @@ PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
+  * necessary to call png_read_row or png_read_rows png_get_image_height
+  * times for each pass.
+ */
+-PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));
++PNG_EXPORT(45, int, png_set_interlace_handling,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+ /* Invert monochrome files */
+-PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
++PNG_EXPORT(46, void, png_set_invert_mono,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_BACKGROUND_SUPPORTED
+@@ -1338,10 +1375,12 @@ PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
+  * read.  Doing so will result in unexpected behavior and possible warnings or
+  * errors if the PNG file contains a bKGD chunk.
+  */
+-PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,
++PNG_FP_EXPORT(47, void, png_set_background,
++   (png_structrp png_ptr,
+     png_const_color_16p background_color, int background_gamma_code,
+     int need_expand, double background_gamma))
+-PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
++PNG_FIXED_EXPORT(215, void, png_set_background_fixed,
++   (png_structrp png_ptr,
+     png_const_color_16p background_color, int background_gamma_code,
+     int need_expand, png_fixed_point background_gamma))
+ #endif
+@@ -1354,20 +1393,23 @@ PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
+ 
+ #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ /* Scale a 16-bit depth file down to 8-bit, accurately. */
+-PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
++PNG_EXPORT(229, void, png_set_scale_16,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ #define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
+ /* Strip the second byte of information from a 16-bit depth file. */
+-PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
++PNG_EXPORT(48, void, png_set_strip_16,
++   (png_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_QUANTIZE_SUPPORTED
+ /* Turn on quantizing, and reduce the palette to the number of colors
+  * available.
+  */
+-PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
++PNG_EXPORT(49, void, png_set_quantize,
++   (png_structrp png_ptr,
+     png_colorp palette, int num_palette, int maximum_colors,
+     png_const_uint_16p histogram, int full_quantize));
+ #endif
+@@ -1389,82 +1431,92 @@ PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
+  * API (floating point or fixed.)  Notice, however, that the 'file_gamma' value
+  * is the inverse of a 'screen gamma' value.
+  */
+-PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,
++PNG_FP_EXPORT(50, void, png_set_gamma,
++   (png_structrp png_ptr,
+     double screen_gamma, double override_file_gamma))
+-PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,
++PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed,
++   (png_structrp png_ptr,
+     png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
+ #endif
+ 
+ #ifdef PNG_WRITE_FLUSH_SUPPORTED
+ /* Set how many lines between output flushes - 0 for no flushing */
+-PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));
++PNG_EXPORT(51, void, png_set_flush,
++   (png_structrp png_ptr, int nrows));
+ /* Flush the current PNG output buffer */
+-PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));
++PNG_EXPORT(52, void, png_write_flush,
++   (png_structrp png_ptr));
+ #endif
+ 
+ /* Optional update palette with requested transformations */
+-PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));
++PNG_EXPORT(53, void, png_start_read_image,
++   (png_structrp png_ptr));
+ 
+ /* Optional call to update the users info structure */
+-PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,
+-    png_inforp info_ptr));
++PNG_EXPORT(54, void, png_read_update_info,
++   (png_structrp png_ptr, png_inforp info_ptr));
+ 
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ /* Read one or more rows of image data. */
+-PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,
++PNG_EXPORT(55, void, png_read_rows,
++   (png_structrp png_ptr, png_bytepp row,
+     png_bytepp display_row, png_uint_32 num_rows));
+ #endif
+ 
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ /* Read a row of data. */
+-PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,
+-    png_bytep display_row));
++PNG_EXPORT(56, void, png_read_row,
++   (png_structrp png_ptr, png_bytep row, png_bytep display_row));
+ #endif
+ 
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ /* Read the whole image into memory at once. */
+-PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));
++PNG_EXPORT(57, void, png_read_image,
++   (png_structrp png_ptr, png_bytepp image));
+ #endif
+ 
+ /* Write a row of image data */
+-PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,
+-    png_const_bytep row));
++PNG_EXPORT(58, void, png_write_row,
++   (png_structrp png_ptr, png_const_bytep row));
+ 
+ /* Write a few rows of image data: (*row) is not written; however, the type
+  * is declared as writeable to maintain compatibility with previous versions
+  * of libpng and to allow the 'display_row' array from read_rows to be passed
+  * unchanged to write_rows.
+  */
+-PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,
+-    png_uint_32 num_rows));
++PNG_EXPORT(59, void, png_write_rows,
++   (png_structrp png_ptr, png_bytepp row, png_uint_32 num_rows));
+ 
+ /* Write the image data */
+-PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));
++PNG_EXPORT(60, void, png_write_image,
++   (png_structrp png_ptr, png_bytepp image));
+ 
+ /* Write the end of the PNG file. */
+-PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,
+-    png_inforp info_ptr));
++PNG_EXPORT(61, void, png_write_end,
++   (png_structrp png_ptr, png_inforp info_ptr));
+ 
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ /* Read the end of the PNG file. */
+-PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));
++PNG_EXPORT(62, void, png_read_end,
++   (png_structrp png_ptr, png_inforp info_ptr));
+ #endif
+ 
+ /* Free any memory associated with the png_info_struct */
+-PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,
+-    png_infopp info_ptr_ptr));
++PNG_EXPORT(63, void, png_destroy_info_struct,
++   (png_const_structrp png_ptr, png_infopp info_ptr_ptr));
+ 
+ /* Free any memory associated with the png_struct and the png_info_structs */
+-PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
++PNG_EXPORT(64, void, png_destroy_read_struct,
++   (png_structpp png_ptr_ptr,
+     png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+ 
+ /* Free any memory associated with the png_struct and the png_info_structs */
+-PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
+-    png_infopp info_ptr_ptr));
++PNG_EXPORT(65, void, png_destroy_write_struct,
++   (png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+ 
+ /* Set the libpng method of handling chunk CRC errors */
+-PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
+-    int ancil_action));
++PNG_EXPORT(66, void, png_set_crc_action,
++   (png_structrp png_ptr, int crit_action, int ancil_action));
+ 
+ /* Values for png_set_crc_action() say how to handle CRC errors in
+  * ancillary and critical chunks, and whether to use the data contained
+@@ -1494,8 +1546,8 @@ PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
+ /* Set the filtering method(s) used by libpng.  Currently, the only valid
+  * value for "method" is 0.
+  */
+-PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
+-    int filters));
++PNG_EXPORT(67, void, png_set_filter,
++   (png_structrp png_ptr, int method, int filters));
+ #endif /* WRITE */
+ 
+ /* Flags for png_set_filter() to say which filters to use.  The flags
+@@ -1524,11 +1576,14 @@ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
+ 
+ #ifdef PNG_WRITE_SUPPORTED
+ #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
+-PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
+-    int heuristic_method, int num_weights, png_const_doublep filter_weights,
++PNG_FP_EXPORT(68, void, png_set_filter_heuristics,
++   (png_structrp png_ptr,
++    int heuristic_method, int num_weights,
++    png_const_doublep filter_weights,
+     png_const_doublep filter_costs))
+ PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
+-    (png_structrp png_ptr, int heuristic_method, int num_weights,
++   (png_structrp png_ptr,
++    int heuristic_method, int num_weights,
+     png_const_fixed_point_p filter_weights,
+     png_const_fixed_point_p filter_costs))
+ #endif /* WRITE_WEIGHTED_FILTER */
+@@ -1547,44 +1602,44 @@ PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
+  * these values may not correspond directly to the zlib compression levels.
+  */
+ #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+-PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
+-    int level));
++PNG_EXPORT(69, void, png_set_compression_level,
++   (png_structrp png_ptr, int level));
+ 
+-PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,
+-    int mem_level));
++PNG_EXPORT(70, void, png_set_compression_mem_level,
++   (png_structrp png_ptr, int mem_level));
+ 
+-PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,
+-    int strategy));
++PNG_EXPORT(71, void, png_set_compression_strategy,
++   (png_structrp png_ptr, int strategy));
+ 
+ /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+  * smaller value of window_bits if it can do so safely.
+  */
+-PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
+-    int window_bits));
++PNG_EXPORT(72, void, png_set_compression_window_bits,
++   (png_structrp png_ptr, int window_bits));
+ 
+-PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
+-    int method));
++PNG_EXPORT(73, void, png_set_compression_method,
++   (png_structrp png_ptr, int method));
+ #endif /* WRITE_CUSTOMIZE_COMPRESSION */
+ 
+ #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+ /* Also set zlib parameters for compressing non-IDAT chunks */
+-PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,
+-    int level));
++PNG_EXPORT(222, void, png_set_text_compression_level,
++   (png_structrp png_ptr, int level));
+ 
+-PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,
+-    int mem_level));
++PNG_EXPORT(223, void, png_set_text_compression_mem_level,
++   (png_structrp png_ptr, int mem_level));
+ 
+-PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,
+-    int strategy));
++PNG_EXPORT(224, void, png_set_text_compression_strategy,
++   (png_structrp png_ptr, int strategy));
+ 
+ /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+  * smaller value of window_bits if it can do so safely.
+  */
+ PNG_EXPORT(225, void, png_set_text_compression_window_bits,
+-    (png_structrp png_ptr, int window_bits));
++   (png_structrp png_ptr, int window_bits));
+ 
+-PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
+-    int method));
++PNG_EXPORT(226, void, png_set_text_compression_method,
++   (png_structrp png_ptr, int method));
+ #endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+ #endif /* WRITE */
+ 
+@@ -1599,7 +1654,8 @@ PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
+ 
+ #ifdef PNG_STDIO_SUPPORTED
+ /* Initialize the input/output for the PNG file to the default functions. */
+-PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, FILE *fp));
++PNG_EXPORT(74, void, png_init_io,
++   (png_structrp png_ptr, FILE *fp));
+ #endif
+ 
+ /* Replace the (error and abort), and warning functions with user
+@@ -1610,11 +1666,13 @@ PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, FILE *fp));
+  * default function will be used.
+  */
+ 
+-PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,
++PNG_EXPORT(75, void, png_set_error_fn,
++   (png_structrp png_ptr,
+     png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+ 
+ /* Return the user pointer associated with the error functions */
+-PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
++PNG_EXPORT(76, png_voidp, png_get_error_ptr,
++   (png_const_structrp png_ptr));
+ 
+ /* Replace the default data output functions with a user supplied one(s).
+  * If buffered output is not used, then output_flush_fn can be set to NULL.
+@@ -1626,47 +1684,54 @@ PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
+  * default flush function, which uses the standard *FILE structure, will
+  * be used.
+  */
+-PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,
++PNG_EXPORT(77, void, png_set_write_fn,
++   (png_structrp png_ptr,
++    png_voidp io_ptr,
+     png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+ 
+ /* Replace the default data input function with a user supplied one. */
+-PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,
+-    png_rw_ptr read_data_fn));
++PNG_EXPORT(78, void, png_set_read_fn,
++   (png_structrp png_ptr,
++    png_voidp io_ptr, png_rw_ptr read_data_fn));
+ 
+ /* Return the user pointer associated with the I/O functions */
+-PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));
++PNG_EXPORT(79, png_voidp, png_get_io_ptr,
++   (png_const_structrp png_ptr));
+ 
+-PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,
+-    png_read_status_ptr read_row_fn));
++PNG_EXPORT(80, void, png_set_read_status_fn,
++   (png_structrp png_ptr, png_read_status_ptr read_row_fn));
+ 
+-PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,
+-    png_write_status_ptr write_row_fn));
++PNG_EXPORT(81, void, png_set_write_status_fn,
++   (png_structrp png_ptr, png_write_status_ptr write_row_fn));
+ 
+ #ifdef PNG_USER_MEM_SUPPORTED
+ /* Replace the default memory allocation functions with user supplied one(s). */
+-PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,
+-    png_malloc_ptr malloc_fn, png_free_ptr free_fn));
++PNG_EXPORT(82, void, png_set_mem_fn,
++   (png_structrp png_ptr,
++    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+ /* Return the user pointer associated with the memory functions */
+-PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));
++PNG_EXPORT(83, png_voidp, png_get_mem_ptr,
++   (png_const_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+-PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,
+-    png_user_transform_ptr read_user_transform_fn));
++PNG_EXPORT(84, void, png_set_read_user_transform_fn,
++   (png_structrp png_ptr, png_user_transform_ptr read_user_transform_fn));
+ #endif
+ 
+ #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+-PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,
+-    png_user_transform_ptr write_user_transform_fn));
++PNG_EXPORT(85, void, png_set_write_user_transform_fn,
++   (png_structrp png_ptr, png_user_transform_ptr write_user_transform_fn));
+ #endif
+ 
+ #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+-PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,
+-    png_voidp user_transform_ptr, int user_transform_depth,
+-    int user_transform_channels));
++PNG_EXPORT(86, void, png_set_user_transform_info,
++   (png_structrp png_ptr,
++    png_voidp user_transform_ptr,
++    int user_transform_depth, int user_transform_channels));
+ /* Return the user pointer associated with the user transform functions */
+ PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+@@ -1681,8 +1746,10 @@ PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
+  * find the output pixel (x,y) given an interlaced sub-image pixel
+  * (row,col,pass).  (See below for these macros.)
+  */
+-PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));
+-PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
++PNG_EXPORT(217, png_uint_32, png_get_current_row_number,
++   (png_const_structrp));
++PNG_EXPORT(218, png_byte, png_get_current_pass_number,
++   (png_const_structrp));
+ #endif
+ 
+ #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+@@ -1705,28 +1772,32 @@ PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
+  * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about
+  * how this behavior will change in libpng 1.7
+  */
+-PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
++PNG_EXPORT(88, void, png_set_read_user_chunk_fn,
++   (png_structrp png_ptr,
+     png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+ #endif
+ 
+ #ifdef PNG_USER_CHUNKS_SUPPORTED
+-PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));
++PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr,
++   (png_const_structrp png_ptr));
+ #endif
+ 
+ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ /* Sets the function callbacks for the push reader, and a pointer to a
+  * user-defined structure available to the callback functions.
+  */
+-PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,
++PNG_EXPORT(90, void, png_set_progressive_read_fn,
++   (png_structrp png_ptr,
+     png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
+     png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
+ 
+ /* Returns the user pointer associated with the push read functions */
+ PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ 
+ /* Function to be called when data becomes available */
+-PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
++PNG_EXPORT(92, void, png_process_data,
++   (png_structrp png_ptr,
+     png_inforp info_ptr, png_bytep buffer, size_t buffer_size));
+ 
+ /* A function which may be called *only* within png_process_data to stop the
+@@ -1736,7 +1807,8 @@ PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
+  * 'save' is set to true the routine will first save all the pending data and
+  * will always return 0.
+  */
+-PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save));
++PNG_EXPORT(219, size_t, png_process_data_pause,
++   (png_structrp, int save));
+ 
+ /* A function which may be called *only* outside (after) a call to
+  * png_process_data.  It returns the number of bytes of data to skip in the
+@@ -1744,45 +1816,53 @@ PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save));
+  * application must skip than number of bytes of input data and pass the
+  * following data to the next call to png_process_data.
+  */
+-PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));
++PNG_EXPORT(220, png_uint_32, png_process_data_skip,
++   (png_structrp));
+ 
+ /* Function that combines rows.  'new_row' is a flag that should come from
+  * the callback and be non-NULL if anything needs to be done; the library
+  * stores its own version of the new data internally and ignores the passed
+  * in value.
+  */
+-PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,
++PNG_EXPORT(93, void, png_progressive_combine_row,
++   (png_const_structrp png_ptr,
+     png_bytep old_row, png_const_bytep new_row));
+ #endif /* PROGRESSIVE_READ */
+ 
+-PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,
+-    png_alloc_size_t size), PNG_ALLOCATED);
++PNG_EXPORTA(94, png_voidp, png_malloc,
++   (png_const_structrp png_ptr, png_alloc_size_t size),
++   PNG_ALLOCATED);
+ /* Added at libpng version 1.4.0 */
+-PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,
+-    png_alloc_size_t size), PNG_ALLOCATED);
++PNG_EXPORTA(95, png_voidp, png_calloc,
++   (png_const_structrp png_ptr, png_alloc_size_t size),
++   PNG_ALLOCATED);
+ 
+ /* Added at libpng version 1.2.4 */
+-PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,
+-    png_alloc_size_t size), PNG_ALLOCATED);
++PNG_EXPORTA(96, png_voidp, png_malloc_warn,
++   (png_const_structrp png_ptr, png_alloc_size_t size),
++   PNG_ALLOCATED);
+ 
+ /* Frees a pointer allocated by png_malloc() */
+-PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
++PNG_EXPORT(97, void, png_free,
++   (png_const_structrp png_ptr, png_voidp ptr));
+ 
+ /* Free data that was allocated internally */
+-PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_uint_32 free_me, int num));
++PNG_EXPORT(98, void, png_free_data,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_uint_32 free_me, int num));
+ 
+ /* Reassign the responsibility for freeing existing data, whether allocated
+  * by libpng or by the application; this works on the png_info structure passed
+  * in, without changing the state for other png_info structures.
+  */
+-PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, int freer, png_uint_32 mask));
++PNG_EXPORT(99, void, png_data_freer,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    int freer, png_uint_32 mask));
+ 
+ /* Assignments for png_data_freer */
+ #define PNG_DESTROY_WILL_FREE_DATA 1
+-#define PNG_SET_WILL_FREE_DATA 1
+-#define PNG_USER_WILL_FREE_DATA 2
++#define PNG_SET_WILL_FREE_DATA     1
++#define PNG_USER_WILL_FREE_DATA    2
+ /* Flags for png_ptr->free_me and info_ptr->free_me */
+ #define PNG_FREE_HIST 0x0008U
+ #define PNG_FREE_ICCP 0x0010U
+@@ -1802,36 +1882,42 @@ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
+ #define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+ 
+ #ifdef PNG_USER_MEM_SUPPORTED
+-PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
+-    png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);
+-PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,
+-    png_voidp ptr), PNG_DEPRECATED);
++PNG_EXPORTA(100, png_voidp, png_malloc_default,
++   (png_const_structrp png_ptr, png_alloc_size_t size),
++   PNG_ALLOCATED PNG_DEPRECATED);
++PNG_EXPORTA(101, void, png_free_default,
++   (png_const_structrp png_ptr, png_voidp ptr),
++   PNG_DEPRECATED);
+ #endif
+ 
+ #ifdef PNG_ERROR_TEXT_SUPPORTED
+ /* Fatal error in PNG image of libpng - can't continue */
+-PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,
+-    png_const_charp error_message), PNG_NORETURN);
++PNG_EXPORTA(102, void, png_error,
++   (png_const_structrp png_ptr, png_const_charp error_message),
++   PNG_NORETURN);
+ 
+ /* The same, but the chunk name is prepended to the error string. */
+-PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
+-    png_const_charp error_message), PNG_NORETURN);
++PNG_EXPORTA(103, void, png_chunk_error,
++   (png_const_structrp png_ptr, png_const_charp error_message),
++   PNG_NORETURN);
+ 
+ #else
+ /* Fatal error in PNG image of libpng - can't continue */
+-PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
++PNG_EXPORTA(104, void, png_err,
++   (png_const_structrp png_ptr),
++   PNG_NORETURN);
+ #  define png_error(s1,s2) png_err(s1)
+ #  define png_chunk_error(s1,s2) png_err(s1)
+ #endif
+ 
+ #ifdef PNG_WARNINGS_SUPPORTED
+ /* Non-fatal error in libpng.  Can continue, but may have a problem. */
+-PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
+-    png_const_charp warning_message));
++PNG_EXPORT(105, void, png_warning,
++   (png_const_structrp png_ptr, png_const_charp warning_message));
+ 
+ /* Non-fatal error in libpng, chunk name is prepended to message. */
+-PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
+-    png_const_charp warning_message));
++PNG_EXPORT(106, void, png_chunk_warning,
++   (png_const_structrp png_ptr, png_const_charp warning_message));
+ #else
+ #  define png_warning(s1,s2) ((void)(s1))
+ #  define png_chunk_warning(s1,s2) ((void)(s1))
+@@ -1840,17 +1926,17 @@ PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
+ #ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ /* Benign error in libpng.  Can continue, but may have a problem.
+  * User can choose whether to handle as a fatal error or as a warning. */
+-PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
+-    png_const_charp warning_message));
++PNG_EXPORT(107, void, png_benign_error,
++   (png_const_structrp png_ptr, png_const_charp warning_message));
+ 
+ #ifdef PNG_READ_SUPPORTED
+ /* Same, chunk name is prepended to message (only during read) */
+-PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,
+-    png_const_charp warning_message));
++PNG_EXPORT(108, void, png_chunk_benign_error,
++   (png_const_structrp png_ptr, png_const_charp warning_message));
+ #endif
+ 
+ PNG_EXPORT(109, void, png_set_benign_errors,
+-    (png_structrp png_ptr, int allowed));
++   (png_structrp png_ptr, int allowed));
+ #else
+ #  ifdef PNG_ALLOW_BENIGN_ERRORS
+ #    define png_benign_error png_warning
+@@ -1874,169 +1960,181 @@ PNG_EXPORT(109, void, png_set_benign_errors,
+  * png_info_struct.
+  */
+ /* Returns "flag" if chunk data is valid in info_ptr. */
+-PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, png_uint_32 flag));
++PNG_EXPORT(110, png_uint_32, png_get_valid,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag));
+ 
+ /* Returns number of bytes needed to hold a transformed row. */
+-PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(111, size_t, png_get_rowbytes,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ #ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Returns row_pointers, which is an array of pointers to scanlines that was
+  * returned from png_read_png().
+  */
+-PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(112, png_bytepp, png_get_rows,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Set row_pointers, which is an array of pointers to scanlines for use
+  * by png_write_png().
+  */
+-PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_bytepp row_pointers));
++PNG_EXPORT(113, void, png_set_rows,
++   (png_const_structrp png_ptr, png_inforp info_ptr, png_bytepp row_pointers));
+ #endif
+ 
+ /* Returns number of color channels in image. */
+-PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(114, png_byte, png_get_channels,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ #ifdef PNG_EASY_ACCESS_SUPPORTED
+ /* Returns image width in pixels. */
+-PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(115, png_uint_32, png_get_image_width,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image height in pixels. */
+-PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(116, png_uint_32, png_get_image_height,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image bit_depth. */
+-PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(117, png_byte, png_get_bit_depth,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image color_type. */
+-PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(118, png_byte, png_get_color_type,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image filter_type. */
+-PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(119, png_byte, png_get_filter_type,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image interlace_type. */
+-PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(120, png_byte, png_get_interlace_type,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image compression_type. */
+-PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(121, png_byte, png_get_compression_type,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns image resolution in pixels per meter, from pHYs chunk data. */
+ PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ /* Returns pixel aspect ratio, computed from pHYs chunk data.  */
+ PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr))
++   (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr))
++   (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ 
+ /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+ PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ #endif /* EASY_ACCESS */
+ 
+ #ifdef PNG_READ_SUPPORTED
+ /* Returns pointer to signature string read from PNG header */
+-PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr));
++PNG_EXPORT(130, png_const_bytep, png_get_signature,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ #endif
+ 
+ #ifdef PNG_bKGD_SUPPORTED
+-PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_color_16p *background));
++PNG_EXPORT(131, png_uint_32, png_get_bKGD,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_color_16p *background));
+ #endif
+ 
+ #ifdef PNG_bKGD_SUPPORTED
+-PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_color_16p background));
++PNG_EXPORT(132, void, png_set_bKGD,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_color_16p background));
+ #endif
+ 
+ #ifdef PNG_cHRM_SUPPORTED
+-PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,
+-    double *red_y, double *green_x, double *green_y, double *blue_x,
+-    double *blue_y))
+-PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,
+-    double *green_X, double *green_Y, double *green_Z, double *blue_X,
+-    double *blue_Y, double *blue_Z))
++PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    double *white_x, double *white_y,
++    double *red_x, double *red_y,
++    double *green_x, double *green_y,
++    double *blue_x, double *blue_y))
++PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    double *red_X, double *red_Y, double *red_Z,
++    double *green_X, double *green_Y, double *green_Z,
++    double *blue_X, double *blue_Y, double *blue_Z))
+ PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
+     png_fixed_point *int_white_x, png_fixed_point *int_white_y,
+     png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+     png_fixed_point *int_green_x, png_fixed_point *int_green_y,
+     png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))
+ PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
+     png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+-    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+-    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
++    png_fixed_point *int_red_Z,
++    png_fixed_point *int_green_X, png_fixed_point *int_green_Y,
++    png_fixed_point *int_green_Z,
+     png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+     png_fixed_point *int_blue_Z))
+ #endif
+ 
+ #ifdef PNG_cHRM_SUPPORTED
+-PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,
+-    png_inforp info_ptr,
+-    double white_x, double white_y, double red_x, double red_y, double green_x,
+-    double green_y, double blue_x, double blue_y))
+-PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, double red_X, double red_Y, double red_Z,
+-    double green_X, double green_Y, double green_Z, double blue_X,
+-    double blue_Y, double blue_Z))
+-PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_fixed_point int_white_x,
+-    png_fixed_point int_white_y, png_fixed_point int_red_x,
+-    png_fixed_point int_red_y, png_fixed_point int_green_x,
+-    png_fixed_point int_green_y, png_fixed_point int_blue_x,
+-    png_fixed_point int_blue_y))
+-PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
+-    png_fixed_point int_red_Z, png_fixed_point int_green_X,
+-    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
++PNG_FP_EXPORT(135, void, png_set_cHRM,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    double white_x, double white_y,
++    double red_x, double red_y,
++    double green_x, double green_y,
++    double blue_x, double blue_y))
++PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    double red_X, double red_Y, double red_Z,
++    double green_X, double green_Y, double green_Z,
++    double blue_X, double blue_Y, double blue_Z))
++PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_fixed_point int_white_x, png_fixed_point int_white_y,
++    png_fixed_point int_red_x, png_fixed_point int_red_y,
++    png_fixed_point int_green_x, png_fixed_point int_green_y,
++    png_fixed_point int_blue_x, png_fixed_point int_blue_y))
++PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_fixed_point int_red_X, png_fixed_point int_red_Y,
++    png_fixed_point int_red_Z,
++    png_fixed_point int_green_X, png_fixed_point int_green_Y,
++    png_fixed_point int_green_Z,
+     png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+     png_fixed_point int_blue_Z))
+ #endif
+ 
+ #ifdef PNG_cICP_SUPPORTED
+-PNG_EXPORT(250, png_uint_32, png_get_cICP, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, png_bytep colour_primaries,
+-    png_bytep transfer_function, png_bytep matrix_coefficients,
+-    png_bytep video_full_range_flag));
++PNG_EXPORT(250, png_uint_32, png_get_cICP,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    png_bytep colour_primaries, png_bytep transfer_function,
++    png_bytep matrix_coefficients, png_bytep video_full_range_flag));
+ #endif
+ 
+ #ifdef PNG_cICP_SUPPORTED
+-PNG_EXPORT(251, void, png_set_cICP, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_byte colour_primaries,
+-    png_byte transfer_function, png_byte matrix_coefficients,
+-    png_byte video_full_range_flag));
++PNG_EXPORT(251, void, png_set_cICP,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_byte colour_primaries, png_byte transfer_function,
++    png_byte matrix_coefficients, png_byte video_full_range_flag));
+ #endif
+ 
+ #ifdef PNG_cLLI_SUPPORTED
+-PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI, (png_const_structrp png_ptr,
+-         png_const_inforp info_ptr, double *maximum_content_light_level,
+-         double *maximum_frame_average_light_level))
++PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    double *maximum_content_light_level,
++    double *maximum_frame_average_light_level))
+ PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
+     /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
+      * 100,000 as in the case of png_fixed_point.
+      */
+@@ -2045,11 +2143,12 @@ PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed,
+ #endif
+ 
+ #ifdef PNG_cLLI_SUPPORTED
+-PNG_FP_EXPORT(254, void, png_set_cLLI, (png_const_structrp png_ptr,
+-         png_inforp info_ptr, double maximum_content_light_level,
+-         double maximum_frame_average_light_level))
+-PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed, (png_const_structrp png_ptr,
+-    png_inforp info_ptr,
++PNG_FP_EXPORT(254, void, png_set_cLLI,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    double maximum_content_light_level,
++    double maximum_frame_average_light_level))
++PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
+     /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
+      * 100,000 as in the case of png_fixed_point.
+      */
+@@ -2058,64 +2157,73 @@ PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed, (png_const_structrp png_ptr,
+ #endif
+ 
+ #ifdef PNG_eXIf_SUPPORTED
+-PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_bytep *exif));
+-PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_bytep exif));
++PNG_EXPORT(246, png_uint_32, png_get_eXIf,
++   (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *exif));
++PNG_EXPORT(247, void, png_set_eXIf,
++   (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep exif));
+ 
+-PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif));
+-PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif));
++PNG_EXPORT(248, png_uint_32, png_get_eXIf_1,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    png_uint_32 *num_exif, png_bytep *exif));
++PNG_EXPORT(249, void, png_set_eXIf_1,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_uint_32 num_exif, png_bytep exif));
+ #endif
+ 
+ #ifdef PNG_gAMA_SUPPORTED
+-PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, double *file_gamma))
++PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    double *file_gamma))
+ PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
+     png_fixed_point *int_file_gamma))
+ #endif
+ 
+ #ifdef PNG_gAMA_SUPPORTED
+-PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, double file_gamma))
+-PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_fixed_point int_file_gamma))
++PNG_FP_EXPORT(139, void, png_set_gAMA,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    double file_gamma))
++PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_fixed_point int_file_gamma))
+ #endif
+ 
+ #ifdef PNG_hIST_SUPPORTED
+-PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_uint_16p *hist));
+-PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_uint_16p hist));
++PNG_EXPORT(141, png_uint_32, png_get_hIST,
++   (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_16p *hist));
++PNG_EXPORT(142, void, png_set_hIST,
++   (png_const_structrp png_ptr, png_inforp info_ptr, png_const_uint_16p hist));
+ #endif
+ 
+-PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
+-    int *bit_depth, int *color_type, int *interlace_method,
+-    int *compression_method, int *filter_method));
++PNG_EXPORT(143, png_uint_32, png_get_IHDR,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    png_uint_32 *width, png_uint_32 *height,
++    int *bit_depth, int *color_type,
++    int *interlace_method, int *compression_method, int *filter_method));
+ 
+-PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+-    int color_type, int interlace_method, int compression_method,
+-    int filter_method));
++PNG_EXPORT(144, void, png_set_IHDR,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_uint_32 width, png_uint_32 height,
++    int bit_depth, int color_type,
++    int interlace_method, int compression_method, int filter_method));
+ 
+ #ifdef PNG_mDCV_SUPPORTED
+-PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr,
++PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
+     /* The chromaticities of the mastering display.  As cHRM, but independent of
+      * the encoding endpoints in cHRM, or cICP, or iCCP.  These values will
+      * always be in the range 0 to 1.3107.
+      */
+-    double *white_x, double *white_y, double *red_x, double *red_y,
+-    double *green_x, double *green_y, double *blue_x, double *blue_y,
++    double *white_x, double *white_y,
++    double *red_x, double *red_y,
++    double *green_x, double *green_y,
++    double *blue_x, double *blue_y,
+     /* Mastering display luminance in cd/m2 (nits). */
+     double *mastering_display_maximum_luminance,
+     double *mastering_display_minimum_luminance))
+ 
+ PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
+     png_fixed_point *int_white_x, png_fixed_point *int_white_y,
+     png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+     png_fixed_point *int_green_x, png_fixed_point *int_green_y,
+@@ -2128,19 +2236,21 @@ PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed,
+ #endif
+ 
+ #ifdef PNG_mDCV_SUPPORTED
+-PNG_FP_EXPORT(258, void, png_set_mDCV, (png_const_structrp png_ptr,
+-    png_inforp info_ptr,
++PNG_FP_EXPORT(258, void, png_set_mDCV,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
+     /* The chromaticities of the mastering display.  As cHRM, but independent of
+      * the encoding endpoints in cHRM, or cICP, or iCCP.
+      */
+-    double white_x, double white_y, double red_x, double red_y, double green_x,
+-    double green_y, double blue_x, double blue_y,
++    double white_x, double white_y,
++    double red_x, double red_y,
++    double green_x, double green_y,
++    double blue_x, double blue_y,
+     /* Mastering display luminance in cd/m2 (nits). */
+     double mastering_display_maximum_luminance,
+     double mastering_display_minimum_luminance))
+ 
+-PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, (png_const_structrp png_ptr,
+-    png_inforp info_ptr,
++PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
+     /* The admissible range of these values is not the full range of a PNG
+      * fixed point value.  Negative values cannot be encoded and the maximum
+      * value is about 1.3 */
+@@ -2156,95 +2266,107 @@ PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, (png_const_structrp png_ptr,
+ #endif
+ 
+ #ifdef PNG_oFFs_SUPPORTED
+-PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
+-   png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+-   int *unit_type));
++PNG_EXPORT(145, png_uint_32, png_get_oFFs,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type));
+ #endif
+ 
+ #ifdef PNG_oFFs_SUPPORTED
+-PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+-    int unit_type));
++PNG_EXPORT(146, void, png_set_oFFs,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_int_32 offset_x, png_int_32 offset_y, int unit_type));
+ #endif
+ 
+ #ifdef PNG_pCAL_SUPPORTED
+-PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,
+-    png_int_32 *X1, int *type, int *nparams, png_charp *units,
+-    png_charpp *params));
++PNG_EXPORT(147, png_uint_32, png_get_pCAL,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
++    int *type, int *nparams, png_charp *units, png_charpp *params));
+ #endif
+ 
+ #ifdef PNG_pCAL_SUPPORTED
+-PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,
++PNG_EXPORT(148, void, png_set_pCAL,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_charp purpose, png_int_32 X0, png_int_32 X1,
+     int type, int nparams, png_const_charp units, png_charpp params));
+ #endif
+ 
+ #ifdef PNG_pHYs_SUPPORTED
+-PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+-    int *unit_type));
++PNG_EXPORT(149, png_uint_32, png_get_pHYs,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+ #endif
+ 
+ #ifdef PNG_pHYs_SUPPORTED
+-PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
++PNG_EXPORT(150, void, png_set_pHYs,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+ #endif
+ 
+-PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,
+-   png_inforp info_ptr, png_colorp *palette, int *num_palette));
++PNG_EXPORT(151, png_uint_32, png_get_PLTE,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_colorp *palette, int *num_palette));
+ 
+-PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,
+-    png_inforp info_ptr, png_const_colorp palette, int num_palette));
++PNG_EXPORT(152, void, png_set_PLTE,
++   (png_structrp png_ptr, png_inforp info_ptr,
++    png_const_colorp palette, int num_palette));
+ 
+ #ifdef PNG_sBIT_SUPPORTED
+-PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_color_8p *sig_bit));
++PNG_EXPORT(153, png_uint_32, png_get_sBIT,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_color_8p *sig_bit));
+ #endif
+ 
+ #ifdef PNG_sBIT_SUPPORTED
+-PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_color_8p sig_bit));
++PNG_EXPORT(154, void, png_set_sBIT,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_color_8p sig_bit));
+ #endif
+ 
+ #ifdef PNG_sRGB_SUPPORTED
+-PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, int *file_srgb_intent));
++PNG_EXPORT(155, png_uint_32, png_get_sRGB,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    int *file_srgb_intent));
+ #endif
+ 
+ #ifdef PNG_sRGB_SUPPORTED
+-PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, int srgb_intent));
+-PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, int srgb_intent));
++PNG_EXPORT(156, void, png_set_sRGB,
++   (png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent));
++PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM,
++   (png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent));
+ #endif
+ 
+ #ifdef PNG_iCCP_SUPPORTED
+-PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_charpp name, int *compression_type,
++PNG_EXPORT(158, png_uint_32, png_get_iCCP,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_charpp name, int *compression_type,
+     png_bytepp profile, png_uint_32 *proflen));
+ #endif
+ 
+ #ifdef PNG_iCCP_SUPPORTED
+-PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_charp name, int compression_type,
++PNG_EXPORT(159, void, png_set_iCCP,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_charp name, int compression_type,
+     png_const_bytep profile, png_uint_32 proflen));
+ #endif
+ 
+ #ifdef PNG_sPLT_SUPPORTED
+-PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_sPLT_tpp entries));
++PNG_EXPORT(160, int, png_get_sPLT,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_sPLT_tpp entries));
+ #endif
+ 
+ #ifdef PNG_sPLT_SUPPORTED
+-PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));
++PNG_EXPORT(161, void, png_set_sPLT,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_sPLT_tp entries, int nentries));
+ #endif
+ 
+ #ifdef PNG_TEXT_SUPPORTED
+ /* png_get_text also returns the number of text chunks in *num_text */
+-PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_textp *text_ptr, int *num_text));
++PNG_EXPORT(162, int, png_get_text,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_textp *text_ptr, int *num_text));
+ #endif
+ 
+ /* Note while png_set_text() will accept a structure whose text,
+@@ -2255,35 +2377,41 @@ PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
+  */
+ 
+ #ifdef PNG_TEXT_SUPPORTED
+-PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_textp text_ptr, int num_text));
++PNG_EXPORT(163, void, png_set_text,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_textp text_ptr, int num_text));
+ #endif
+ 
+ #ifdef PNG_tIME_SUPPORTED
+-PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_timep *mod_time));
++PNG_EXPORT(164, png_uint_32, png_get_tIME,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_timep *mod_time));
+ #endif
+ 
+ #ifdef PNG_tIME_SUPPORTED
+-PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_timep mod_time));
++PNG_EXPORT(165, void, png_set_tIME,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_timep mod_time));
+ #endif
+ 
+ #ifdef PNG_tRNS_SUPPORTED
+-PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,
++PNG_EXPORT(166, png_uint_32, png_get_tRNS,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_bytep *trans_alpha, int *num_trans,
+     png_color_16p *trans_color));
+ #endif
+ 
+ #ifdef PNG_tRNS_SUPPORTED
+-PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,
+-    png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,
++PNG_EXPORT(167, void, png_set_tRNS,
++   (png_structrp png_ptr, png_inforp info_ptr,
++    png_const_bytep trans_alpha, int num_trans,
+     png_const_color_16p trans_color));
+ #endif
+ 
+ #ifdef PNG_sCAL_SUPPORTED
+-PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, int *unit, double *width, double *height))
++PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    int *unit, double *width, double *height))
+ #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+    defined(PNG_FLOATING_POINT_SUPPORTED)
+ /* NOTE: this API is currently implemented using floating point arithmetic,
+@@ -2292,21 +2420,22 @@ PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
+  * is highly recommended that png_get_sCAL_s be used instead.
+  */
+ PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+-    png_fixed_point *width, png_fixed_point *height))
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    int *unit, png_fixed_point *width, png_fixed_point *height))
+ #endif
+ PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+-    png_charpp swidth, png_charpp sheight));
+-
+-PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, int unit, double width, double height))
+-PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,
+-   png_inforp info_ptr, int unit, png_fixed_point width,
+-   png_fixed_point height))
+-PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, int unit,
+-    png_const_charp swidth, png_const_charp sheight));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    int *unit, png_charpp swidth, png_charpp sheight));
++
++PNG_FP_EXPORT(170, void, png_set_sCAL,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    int unit, double width, double height))
++PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    int unit, png_fixed_point width, png_fixed_point height))
++PNG_EXPORT(171, void, png_set_sCAL_s,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    int unit, png_const_charp swidth, png_const_charp sheight));
+ #endif /* sCAL */
+ 
+ #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+@@ -2409,7 +2538,8 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
+  *    be processed by libpng.
+  */
+ #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+-PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
++PNG_EXPORT(172, void, png_set_keep_unknown_chunks,
++   (png_structrp png_ptr,
+     int keep, png_const_bytep chunk_list, int num_chunks));
+ #endif /* HANDLE_AS_UNKNOWN */
+ 
+@@ -2417,14 +2547,14 @@ PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
+  * the result is therefore true (non-zero) if special handling is required,
+  * false for the default handling.
+  */
+-PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
+-    png_const_bytep chunk_name));
++PNG_EXPORT(173, int, png_handle_as_unknown,
++   (png_const_structrp png_ptr, png_const_bytep chunk_name));
+ #endif /* SET_UNKNOWN_CHUNKS */
+ 
+ #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+-PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_unknown_chunkp unknowns,
+-    int num_unknowns));
++PNG_EXPORT(174, void, png_set_unknown_chunks,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_const_unknown_chunkp unknowns, int num_unknowns));
+    /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added
+     * unknowns to the location currently stored in the png_struct.  This is
+     * invariably the wrong value on write.  To fix this call the following API
+@@ -2435,43 +2565,47 @@ PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
+     */
+ 
+ PNG_EXPORT(175, void, png_set_unknown_chunk_location,
+-    (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    int chunk, int location));
+ 
+-PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_unknown_chunkpp entries));
++PNG_EXPORT(176, int, png_get_unknown_chunks,
++   (png_const_structrp png_ptr, png_inforp info_ptr,
++    png_unknown_chunkpp entries));
+ #endif
+ 
+ /* Png_free_data() will turn off the "valid" flag for anything it frees.
+  * If you need to turn it off for a chunk that your application has freed,
+  * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
+  */
+-PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
+-    png_inforp info_ptr, int mask));
++PNG_EXPORT(177, void, png_set_invalid,
++   (png_const_structrp png_ptr, png_inforp info_ptr, int mask));
+ 
+ #ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* The "params" pointer is currently not used and is for future expansion. */
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+-PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
++PNG_EXPORT(178, void, png_read_png,
++   (png_structrp png_ptr, png_inforp info_ptr,
+     int transforms, png_voidp params));
+ #endif
+ #ifdef PNG_WRITE_SUPPORTED
+-PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
++PNG_EXPORT(179, void, png_write_png,
++   (png_structrp png_ptr, png_inforp info_ptr,
+     int transforms, png_voidp params));
+ #endif
+ #endif
+ 
+ PNG_EXPORT(180, png_const_charp, png_get_copyright,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ PNG_EXPORT(181, png_const_charp, png_get_header_ver,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ PNG_EXPORT(182, png_const_charp, png_get_header_version,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ 
+ #ifdef PNG_MNG_FEATURES_SUPPORTED
+-PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
+-    png_uint_32 mng_features_permitted));
++PNG_EXPORT(184, png_uint_32, png_permit_mng_features,
++   (png_structrp png_ptr, png_uint_32 mng_features_permitted));
+ #endif
+ 
+ /* For use in png_set_keep_unknown, added to version 1.2.6 */
+@@ -2485,71 +2619,74 @@ PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
+  * messages before passing them to the error or warning handler.
+  */
+ #ifdef PNG_ERROR_NUMBERS_SUPPORTED
+-PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,
+-    png_uint_32 strip_mode));
++PNG_EXPORT(185, void, png_set_strip_error_numbers,
++   (png_structrp png_ptr, png_uint_32 strip_mode));
+ #endif
+ 
+ /* Added in libpng-1.2.6 */
+ #ifdef PNG_SET_USER_LIMITS_SUPPORTED
+-PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,
++PNG_EXPORT(186, void, png_set_user_limits,
++   (png_structrp png_ptr,
+     png_uint_32 user_width_max, png_uint_32 user_height_max));
+ PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ /* Added in libpng-1.4.0 */
+-PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,
+-    png_uint_32 user_chunk_cache_max));
++PNG_EXPORT(189, void, png_set_chunk_cache_max,
++   (png_structrp png_ptr, png_uint_32 user_chunk_cache_max));
+ PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ /* Added in libpng-1.4.1 */
+-PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,
+-    png_alloc_size_t user_chunk_cache_max));
++PNG_EXPORT(191, void, png_set_chunk_malloc_max,
++   (png_structrp png_ptr, png_alloc_size_t user_chunk_cache_max));
+ PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ #endif
+ 
+ #if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+ PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr));
++   (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ 
+ PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr))
++   (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ #ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+ PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr))
++   (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ #endif
+ 
+-PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr))
++PNG_FP_EXPORT(197, float, png_get_y_offset_inches,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ #ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+ PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
+-    (png_const_structrp png_ptr, png_const_inforp info_ptr))
++   (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ #endif
+ 
+ #  ifdef PNG_pHYs_SUPPORTED
+-PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,
+-    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+-    int *unit_type));
++PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi,
++   (png_const_structrp png_ptr, png_const_inforp info_ptr,
++    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+ #  endif /* pHYs */
+ #endif  /* INCH_CONVERSIONS */
+ 
+ /* Added in libpng-1.4.0 */
+ #ifdef PNG_IO_STATE_SUPPORTED
+-PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));
++PNG_EXPORT(199, png_uint_32, png_get_io_state,
++   (png_const_structrp png_ptr));
+ 
+ /* Removed from libpng 1.6; use png_get_io_chunk_type. */
+-PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),
+-    PNG_DEPRECATED)
++PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name,
++   (png_structrp png_ptr),
++   PNG_DEPRECATED)
+ 
+ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
+-    (png_const_structrp png_ptr));
++   (png_const_structrp png_ptr));
+ 
+ /* The flags returned by png_get_io_state() are the following: */
+ #  define PNG_IO_NONE        0x0000   /* no I/O at this moment */
+@@ -2674,21 +2811,26 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
+ #endif /* READ_COMPOSITE_NODIV */
+ 
+ #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+-PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
+-PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
+-PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
++PNG_EXPORT(201, png_uint_32, png_get_uint_32,
++   (png_const_bytep buf));
++PNG_EXPORT(202, png_uint_16, png_get_uint_16,
++   (png_const_bytep buf));
++PNG_EXPORT(203, png_int_32, png_get_int_32,
++   (png_const_bytep buf));
+ #endif
+ 
+-PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,
+-    png_const_bytep buf));
++PNG_EXPORT(204, png_uint_32, png_get_uint_31,
++   (png_const_structrp png_ptr, png_const_bytep buf));
+ /* No png_get_int_16 -- may be added if there's a real need for it. */
+ 
+ /* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
+ #ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+-PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
++PNG_EXPORT(205, void, png_save_uint_32,
++   (png_bytep buf, png_uint_32 i));
+ #endif
+ #ifdef PNG_SAVE_INT_32_SUPPORTED
+-PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
++PNG_EXPORT(206, void, png_save_int_32,
++   (png_bytep buf, png_int_32 i));
+ #endif
+ 
+ /* Place a 16-bit number into a buffer in PNG byte order.
+@@ -2696,7 +2838,8 @@ PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
+  * just to avoid potential problems on pre-ANSI C compilers.
+  */
+ #ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+-PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
++PNG_EXPORT(207, void, png_save_uint_16,
++   (png_bytep buf, unsigned int i));
+ /* No png_save_int_16 -- may be added if there's a real need for it. */
+ #endif
+ 
+@@ -2743,10 +2886,10 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
+ 
+ #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ PNG_EXPORT(242, void, png_set_check_for_invalid_index,
+-    (png_structrp png_ptr, int allowed));
++   (png_structrp png_ptr, int allowed));
+ #  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+-PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
+-    png_const_infop info_ptr));
++PNG_EXPORT(243, int, png_get_palette_max,
++   (png_const_structp png_ptr, png_const_infop info_ptr));
+ #  endif
+ #endif /* CHECK_FOR_INVALID_INDEX */
+ 
+@@ -3110,24 +3253,25 @@ typedef struct
+  * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)
+  */
+ #ifdef PNG_STDIO_SUPPORTED
+-PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,
+-   const char *file_name));
++PNG_EXPORT(234, int, png_image_begin_read_from_file,
++   (png_imagep image, const char *file_name));
+    /* The named file is opened for read and the image header is filled in
+     * from the PNG header in the file.
+     */
+ 
+-PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
+-   FILE *file));
++PNG_EXPORT(235, int, png_image_begin_read_from_stdio,
++   (png_imagep image, FILE *file));
+    /* The PNG header is read from the stdio FILE object. */
+ #endif /* STDIO */
+ 
+-PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
+-   png_const_voidp memory, size_t size));
++PNG_EXPORT(236, int, png_image_begin_read_from_memory,
++   (png_imagep image, png_const_voidp memory, size_t size));
+    /* The PNG header is read from the given memory buffer. */
+ 
+-PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
+-   png_const_colorp background, void *buffer, png_int_32 row_stride,
+-   void *colormap));
++PNG_EXPORT(237, int, png_image_finish_read,
++   (png_imagep image,
++    png_const_colorp background, void *buffer, png_int_32 row_stride,
++    void *colormap));
+    /* Finish reading the image into the supplied buffer and clean up the
+     * png_image structure.
+     *
+@@ -3160,7 +3304,8 @@ PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
+     * written to the colormap; this may be less than the original value.
+     */
+ 
+-PNG_EXPORT(238, void, png_image_free, (png_imagep image));
++PNG_EXPORT(238, void, png_image_free,
++   (png_imagep image));
+    /* Free any data allocated by libpng in image->opaque, setting the pointer to
+     * NULL.  May be called at any time after the structure is initialized.
+     */
+@@ -3184,14 +3329,16 @@ PNG_EXPORT(238, void, png_image_free, (png_imagep image));
+  * colormap_entries: set to the number of entries in the color-map (0 to 256)
+  */
+ #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+-PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
+-   const char *file, int convert_to_8bit, const void *buffer,
+-   png_int_32 row_stride, const void *colormap));
++PNG_EXPORT(239, int, png_image_write_to_file,
++   (png_imagep image,
++    const char *file, int convert_to_8bit, const void *buffer,
++    png_int_32 row_stride, const void *colormap));
+    /* Write the image to the named file. */
+ 
+-PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
+-   int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
+-   const void *colormap));
++PNG_EXPORT(240, int, png_image_write_to_stdio,
++   (png_imagep image,
++    FILE *file, int convert_to_8_bit, const void *buffer,
++    png_int_32 row_stride, const void *colormap));
+    /* Write the image to the given FILE object. */
+ #endif /* SIMPLIFIED_WRITE_STDIO */
+ 
+@@ -3216,9 +3363,11 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
+  * notices) you need to use one of the other APIs.
+  */
+ 
+-PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
+-   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
+-   const void *buffer, png_int_32 row_stride, const void *colormap));
++PNG_EXPORT(245, int, png_image_write_to_memory,
++   (png_imagep image,
++    void *memory, png_alloc_size_t * PNG_RESTRICT memory_bytes,
++    int convert_to_8_bit,
++    const void *buffer, png_int_32 row_stride, const void *colormap));
+    /* Write the image to the given memory buffer.  The function both writes the
+     * whole PNG data stream to *memory and updates *memory_bytes with the count
+     * of bytes written.
+@@ -3394,7 +3543,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
+  * one to use is one more than this.)
+  */
+ #ifdef PNG_EXPORT_LAST_ORDINAL
+-  PNG_EXPORT_LAST_ORDINAL(259);
++   PNG_EXPORT_LAST_ORDINAL(259);
+ #endif
+ 
+ #ifdef __cplusplus
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+index 4bc5f7bb468..959c604edbc 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+@@ -29,9 +29,9 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * libpng version 1.6.51
++ * libpng version 1.6.54
+  *
+- * Copyright (c) 2018-2025 Cosmin Truta
++ * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
+  * Copyright (c) 1996-1997 Andreas Dilger
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
+index 44c86ebfef9..324d1951a52 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
+@@ -78,7 +78,8 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ }
+ #else
+ PNG_FUNCTION(void,PNGAPI
+-png_err,(png_const_structrp png_ptr),PNG_NORETURN)
++png_err,(png_const_structrp png_ptr),
++    PNG_NORETURN)
+ {
+    /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
+     * erroneously as '\0', instead of the empty string "".  This was
+@@ -405,8 +406,8 @@ static const char png_digit[16] = {
+ };
+ 
+ static void /* PRIVATE */
+-png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
+-    error_message)
++png_format_buffer(png_const_structrp png_ptr, png_charp buffer,
++    png_const_charp error_message)
+ {
+    png_uint_32 chunk_name = png_ptr->chunk_name;
+    int iout = 0, ishift = 24;
+@@ -485,8 +486,8 @@ png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+ #ifdef PNG_READ_SUPPORTED
+ #ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ void PNGAPI
+-png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
+-    error_message)
++png_chunk_benign_error(png_const_structrp png_ptr,
++    png_const_charp error_message)
+ {
+    if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+       png_chunk_warning(png_ptr, error_message);
+@@ -543,7 +544,8 @@ png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
+ #ifdef PNG_ERROR_TEXT_SUPPORTED
+ #ifdef PNG_FLOATING_POINT_SUPPORTED
+ PNG_FUNCTION(void,
+-png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
++png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),
++    PNG_NORETURN)
+ {
+ #  define fixed_message "fixed point overflow in "
+ #  define fixed_message_ln ((sizeof fixed_message)-1)
+@@ -696,7 +698,8 @@ png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ }
+ 
+ PNG_FUNCTION(void,PNGAPI
+-png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
++png_longjmp,(png_const_structrp png_ptr, int val),
++    PNG_NORETURN)
+ {
+ #ifdef PNG_SETJMP_SUPPORTED
+    if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
+index ed2e7f886f5..a5bdcd1b524 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
+@@ -151,8 +151,8 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+ }
+ 
+ png_uint_32 PNGAPI
+-png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+-   info_ptr)
++png_get_x_pixels_per_meter(png_const_structrp png_ptr,
++    png_const_inforp info_ptr)
+ {
+ #ifdef PNG_pHYs_SUPPORTED
+    png_debug(1, "in png_get_x_pixels_per_meter");
+@@ -172,8 +172,8 @@ png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ }
+ 
+ png_uint_32 PNGAPI
+-png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+-    info_ptr)
++png_get_y_pixels_per_meter(png_const_structrp png_ptr,
++    png_const_inforp info_ptr)
+ {
+ #ifdef PNG_pHYs_SUPPORTED
+    png_debug(1, "in png_get_y_pixels_per_meter");
+@@ -215,8 +215,8 @@ png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
+ 
+ #ifdef PNG_FLOATING_POINT_SUPPORTED
+ float PNGAPI
+-png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
+-   info_ptr)
++png_get_pixel_aspect_ratio(png_const_structrp png_ptr,
++    png_const_inforp info_ptr)
+ {
+ #ifdef PNG_READ_pHYs_SUPPORTED
+    png_debug(1, "in png_get_pixel_aspect_ratio");
+@@ -766,7 +766,6 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+    }
+ 
+    return 0;
+-
+ }
+ #endif
+ 
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+index 4cfae474751..b413b510acf 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+@@ -31,9 +31,9 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  */
+-/* libpng version 1.6.51 */
++/* libpng version 1.6.54 */
+ 
+-/* Copyright (c) 2018-2025 Cosmin Truta */
++/* Copyright (c) 2018-2026 Cosmin Truta */
+ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
+ 
+ /* This code is released under the libpng license. */
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
+index 12b71bcbc02..8ec703616ec 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
+@@ -75,7 +75,8 @@ png_destroy_png_struct(png_structrp png_ptr)
+  * have the ability to do that.
+  */
+ PNG_FUNCTION(png_voidp,PNGAPI
+-png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
++png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),
++    PNG_ALLOCATED)
+ {
+    png_voidp ret;
+ 
+@@ -147,7 +148,8 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
+ 
+ PNG_FUNCTION(png_voidp /* PRIVATE */,
+ png_malloc_array,(png_const_structrp png_ptr, int nelements,
+-    size_t element_size),PNG_ALLOCATED)
++    size_t element_size),
++    PNG_ALLOCATED)
+ {
+    if (nelements <= 0 || element_size == 0)
+       png_error(png_ptr, "internal error: array alloc");
+@@ -157,7 +159,8 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements,
+ 
+ PNG_FUNCTION(png_voidp /* PRIVATE */,
+ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
+-    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
++    int old_elements, int add_elements, size_t element_size),
++    PNG_ALLOCATED)
+ {
+    /* These are internal errors: */
+    if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
+@@ -196,7 +199,8 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
+  * function png_malloc_default is also provided.
+  */
+ PNG_FUNCTION(png_voidp,PNGAPI
+-png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
++png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),
++    PNG_ALLOCATED)
+ {
+    png_voidp ret;
+ 
+@@ -270,7 +274,8 @@ png_free(png_const_structrp png_ptr, png_voidp ptr)
+ }
+ 
+ PNG_FUNCTION(void,PNGAPI
+-png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
++png_free_default,(png_const_structrp png_ptr, png_voidp ptr),
++    PNG_DEPRECATED)
+ {
+    if (png_ptr == NULL || ptr == NULL)
+       return;
+@@ -284,8 +289,8 @@ png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
+  * of allocating and freeing memory.
+  */
+ void PNGAPI
+-png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+-  malloc_fn, png_free_ptr free_fn)
++png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr,
++    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+ {
+    if (png_ptr != NULL)
+    {
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
+index dcd005efb34..ee91f58d4ba 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
+@@ -1104,15 +1104,17 @@ extern "C" {
+  */
+ /* Zlib support */
+ #define PNG_UNEXPECTED_ZLIB_RETURN (-7)
+-PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
++PNG_INTERNAL_FUNCTION(void, png_zstream_error,
++   (png_structrp png_ptr, int ret),
+    PNG_EMPTY);
+    /* Used by the zlib handling functions to ensure that z_stream::msg is always
+     * set before they return.
+     */
+ 
+ #ifdef PNG_WRITE_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
+-   png_compression_bufferp *list),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_free_buffer_list,
++   (png_structrp png_ptr, png_compression_bufferp *list),
++   PNG_EMPTY);
+    /* Free the buffer list used by the compressed write code. */
+ #endif
+ 
+@@ -1124,22 +1126,25 @@ PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
+    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+    (defined(PNG_sCAL_SUPPORTED) && \
+    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+-PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
+-   double fp, png_const_charp text),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_fixed_point, png_fixed,
++   (png_const_structrp png_ptr, double fp, png_const_charp text),
++   PNG_EMPTY);
+ #endif
+ 
+ #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+    !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+    (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
+-PNG_INTERNAL_FUNCTION(png_uint_32,png_fixed_ITU,(png_const_structrp png_ptr,
+-   double fp, png_const_charp text),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_uint_32, png_fixed_ITU,
++   (png_const_structrp png_ptr, double fp, png_const_charp text),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Check the user version string for compatibility, returns false if the version
+  * numbers aren't compatible.
+  */
+-PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
+-   png_const_charp user_png_ver),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_user_version_check,
++   (png_structrp png_ptr, png_const_charp user_png_ver),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_READ_SUPPORTED /* should only be used on read */
+ /* Security: read limits on the largest allocations while reading a PNG.  This
+@@ -1164,24 +1169,28 @@ PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
+  * does, however, call the application provided allocator and that could call
+  * png_error (although that would be a bug in the application implementation.)
+  */
+-PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,
+-   png_alloc_size_t size),PNG_ALLOCATED);
++PNG_INTERNAL_FUNCTION(png_voidp, png_malloc_base,
++   (png_const_structrp png_ptr, png_alloc_size_t size),
++   PNG_ALLOCATED);
+ 
+ #if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+    defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+ /* Internal array allocator, outputs no error or warning messages on failure,
+  * just returns NULL.
+  */
+-PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
+-   int nelements, size_t element_size),PNG_ALLOCATED);
++PNG_INTERNAL_FUNCTION(png_voidp, png_malloc_array,
++   (png_const_structrp png_ptr, int nelements, size_t element_size),
++   PNG_ALLOCATED);
+ 
+ /* The same but an existing array is extended by add_elements.  This function
+  * also memsets the new elements to 0 and copies the old elements.  The old
+  * array is not freed or altered.
+  */
+-PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
+-   png_const_voidp array, int old_elements, int add_elements,
+-   size_t element_size),PNG_ALLOCATED);
++PNG_INTERNAL_FUNCTION(png_voidp, png_realloc_array,
++   (png_const_structrp png_ptr,
++    png_const_voidp array, int old_elements, int add_elements,
++    size_t element_size),
++   PNG_ALLOCATED);
+ #endif /* text, sPLT or unknown chunks */
+ 
+ /* Magic to create a struct when there is no struct to call the user supplied
+@@ -1190,84 +1199,106 @@ PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
+  * restriction so libpng has to assume that the 'free' handler, at least, might
+  * call png_error.
+  */
+-PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,
+-   (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+-    png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
+-    png_free_ptr free_fn),PNG_ALLOCATED);
++PNG_INTERNAL_FUNCTION(png_structp, png_create_png_struct,
++   (png_const_charp user_png_ver,
++    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn,
++    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
++   PNG_ALLOCATED);
+ 
+ /* Free memory from internal libpng struct */
+-PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(void, png_destroy_png_struct,
++   (png_structrp png_ptr),
+    PNG_EMPTY);
+ 
+ /* Free an allocated jmp_buf (always succeeds) */
+-PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_free_jmpbuf,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ /* Function to allocate memory for zlib.  PNGAPI is disallowed. */
+-PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),
++PNG_INTERNAL_FUNCTION(voidpf, png_zalloc,
++   (voidpf png_ptr, uInt items, uInt size),
+    PNG_ALLOCATED);
+ 
+ /* Function to free memory for zlib.  PNGAPI is disallowed. */
+-PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_zfree,
++   (voidpf png_ptr, voidpf ptr),
++   PNG_EMPTY);
+ 
+ /* Next four functions are used internally as callbacks.  PNGCBAPI is required
+  * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3, changed to
+  * PNGCBAPI at 1.5.0
+  */
+ 
+-PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
+-    png_bytep data, size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_read_data,
++   (png_structp png_ptr, png_bytep data, size_t length),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
+-    png_bytep buffer, size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_push_fill_buffer,
++   (png_structp png_ptr, png_bytep buffer, size_t length),
++   PNG_EMPTY);
+ #endif
+ 
+-PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
+-    png_bytep data, size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_write_data,
++   (png_structp png_ptr, png_bytep data, size_t length),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_WRITE_FLUSH_SUPPORTED
+ #  ifdef PNG_STDIO_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
++PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_flush,
++   (png_structp png_ptr),
+    PNG_EMPTY);
+ #  endif
+ #endif
+ 
+ /* Reset the CRC variable */
+-PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_reset_crc,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ /* Write the "data" buffer to whatever output you are using */
+-PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
+-    png_const_bytep data, size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_data,
++   (png_structrp png_ptr, png_const_bytep data, size_t length),
++   PNG_EMPTY);
+ 
+ /* Read and check the PNG file signature */
+-PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
+-   png_inforp info_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_sig,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
+ 
+ /* Read the chunk header (length + type name) */
+-PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(png_uint_32, png_read_chunk_header,
++   (png_structrp png_ptr),
+    PNG_EMPTY);
+ 
+ /* Read data from whatever input you are using into the "data" buffer */
+-PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
+-    size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_data,
++   (png_structrp png_ptr, png_bytep data, size_t length),
++   PNG_EMPTY);
+ 
+ /* Read bytes into buf, and update png_ptr->crc */
+-PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
+-    png_uint_32 length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_crc_read,
++   (png_structrp png_ptr, png_bytep buf, png_uint_32 length),
++   PNG_EMPTY);
+ 
+ /* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+-PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
+-   png_uint_32 skip),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_crc_finish,
++   (png_structrp png_ptr, png_uint_32 skip),
++   PNG_EMPTY);
+ 
+ /* Calculate the CRC over a section of data.  Note that we are only
+  * passing a maximum of 64K on systems that have this as a memory limit,
+  * since this is the maximum buffer size we can specify.
+  */
+-PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
+-   png_const_bytep ptr, size_t length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_calculate_crc,
++   (png_structrp png_ptr, png_const_bytep ptr, size_t length),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_WRITE_FLUSH_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_flush,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Write various chunks */
+@@ -1275,68 +1306,86 @@ PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
+ /* Write the IHDR chunk, and update the png_struct with the necessary
+  * information.
+  */
+-PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
+-   png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
+-   int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_IHDR,
++   (png_structrp png_ptr,
++    png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
++    int compression_method, int filter_method, int interlace_method),
++   PNG_EMPTY);
+ 
+-PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
+-   png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_PLTE,
++   (png_structrp png_ptr,
++    png_const_colorp palette, png_uint_32 num_pal),
++   PNG_EMPTY);
+ 
+-PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
+-   png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
++PNG_INTERNAL_FUNCTION(void, png_compress_IDAT,
++   (png_structrp png_ptr,
++    png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
+    PNG_EMPTY);
+ 
+-PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_IEND,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_WRITE_gAMA_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,
+-    png_fixed_point file_gamma),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_gAMA_fixed,
++   (png_structrp png_ptr, png_fixed_point file_gamma),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_sBIT_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
+-    png_const_color_8p sbit, int color_type),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_sBIT,
++   (png_structrp png_ptr, png_const_color_8p sbit, int color_type),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_cHRM_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
+-    const png_xy *xy), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_cHRM_fixed,
++   (png_structrp png_ptr, const png_xy *xy),
++   PNG_EMPTY);
+    /* The xy value must have been previously validated */
+ #endif
+ 
+ #ifdef PNG_WRITE_cICP_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_cICP,(png_structrp png_ptr,
++PNG_INTERNAL_FUNCTION(void, png_write_cICP,
++   (png_structrp png_ptr,
+     png_byte colour_primaries, png_byte transfer_function,
+-    png_byte matrix_coefficients, png_byte video_full_range_flag), PNG_EMPTY);
++    png_byte matrix_coefficients, png_byte video_full_range_flag),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_cLLI_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_cLLI_fixed,(png_structrp png_ptr,
+-   png_uint_32 maxCLL, png_uint_32 maxFALL), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_cLLI_fixed,
++   (png_structrp png_ptr, png_uint_32 maxCLL, png_uint_32 maxFALL),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_mDCV_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_mDCV_fixed,(png_structrp png_ptr,
+-   png_uint_16 red_x, png_uint_16 red_y,
+-   png_uint_16 green_x, png_uint_16 green_y,
+-   png_uint_16 blue_x, png_uint_16 blue_y,
+-   png_uint_16 white_x, png_uint_16 white_y,
+-   png_uint_32 maxDL, png_uint_32 minDL), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_mDCV_fixed,
++   (png_structrp png_ptr,
++    png_uint_16 red_x, png_uint_16 red_y,
++    png_uint_16 green_x, png_uint_16 green_y,
++    png_uint_16 blue_x, png_uint_16 blue_y,
++    png_uint_16 white_x, png_uint_16 white_y,
++    png_uint_32 maxDL, png_uint_32 minDL),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_sRGB_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
+-    int intent),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_sRGB,
++   (png_structrp png_ptr, int intent),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_eXIf_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
+-    png_bytep exif, int num_exif),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_eXIf,
++   (png_structrp png_ptr, png_bytep exif, int num_exif),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_iCCP_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
+-   png_const_charp name, png_const_bytep profile, png_uint_32 proflen),
++PNG_INTERNAL_FUNCTION(void, png_write_iCCP,
++   (png_structrp png_ptr,
++    png_const_charp name, png_const_bytep profile, png_uint_32 proflen),
+    PNG_EMPTY);
+    /* Writes a previously 'set' profile.  The profile argument is **not**
+     * compressed.
+@@ -1344,82 +1393,106 @@ PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
+ #endif
+ 
+ #ifdef PNG_WRITE_sPLT_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
+-    png_const_sPLT_tp palette),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_sPLT,
++   (png_structrp png_ptr, png_const_sPLT_tp palette),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_tRNS_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,
++PNG_INTERNAL_FUNCTION(void, png_write_tRNS,
++   (png_structrp png_ptr,
+     png_const_bytep trans, png_const_color_16p values, int number,
+-    int color_type),PNG_EMPTY);
++    int color_type),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_bKGD_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,
+-    png_const_color_16p values, int color_type),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_bKGD,
++   (png_structrp png_ptr, png_const_color_16p values, int color_type),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_hIST_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
+-    png_const_uint_16p hist, int num_hist),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_hIST,
++   (png_structrp png_ptr, png_const_uint_16p hist, int num_hist),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Chunks that have keywords */
+ #ifdef PNG_WRITE_tEXt_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
+-   png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_tEXt,
++   (png_structrp png_ptr,
++    png_const_charp key, png_const_charp text, size_t text_len),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_zTXt_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp
+-    key, png_const_charp text, int compression),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_zTXt,
++   (png_structrp png_ptr,
++    png_const_charp key, png_const_charp text, int compression),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_iTXt_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,
++PNG_INTERNAL_FUNCTION(void, png_write_iTXt,
++   (png_structrp png_ptr,
+     int compression, png_const_charp key, png_const_charp lang,
+-    png_const_charp lang_key, png_const_charp text),PNG_EMPTY);
++    png_const_charp lang_key, png_const_charp text),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */
+-PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,
+-    png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_set_text_2,
++   (png_const_structrp png_ptr,
++    png_inforp info_ptr, png_const_textp text_ptr, int num_text),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_oFFs_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,
+-    png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_oFFs,
++   (png_structrp png_ptr,
++    png_int_32 x_offset, png_int_32 y_offset, int unit_type),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_pCAL_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,
+-    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+-    png_const_charp units, png_charpp params),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_pCAL,
++   (png_structrp png_ptr,
++    png_charp purpose, png_int_32 X0, png_int_32 X1,
++    int type, int nparams, png_const_charp units, png_charpp params),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_pHYs_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,
++PNG_INTERNAL_FUNCTION(void, png_write_pHYs,
++   (png_structrp png_ptr,
+     png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+-    int unit_type),PNG_EMPTY);
++    int unit_type),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_tIME_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,
+-    png_const_timep mod_time),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_tIME,
++   (png_structrp png_ptr, png_const_timep mod_time),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_WRITE_sCAL_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,
+-    int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_sCAL_s,
++   (png_structrp png_ptr,
++    int unit, png_const_charp width, png_const_charp height),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Called when finished processing a row of data */
+-PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
+-    PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_finish_row,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ /* Internal use only.   Called before first row of data */
+-PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
+-    PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_start_row,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ /* Combine a row of data, dealing with alpha, etc. if requested.  'row' is an
+  * array of png_ptr->width pixels.  If the image is not interlaced or this
+@@ -1447,8 +1520,9 @@ PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
+ #ifndef PNG_USE_COMPILE_TIME_MASKS
+ #  define PNG_USE_COMPILE_TIME_MASKS 1
+ #endif
+-PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
+-    png_bytep row, int display),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_combine_row,
++   (png_const_structrp png_ptr, png_bytep row, int display),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Expand an interlaced row: the 'row_info' describes the pass data that has
+@@ -1457,170 +1531,230 @@ PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
+  * the pixels are *replicated* to the intervening space.  This is essential for
+  * the correct operation of png_combine_row, above.
+  */
+-PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,
+-    png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_read_interlace,
++   (png_row_infop row_info,
++    png_bytep row, int pass, png_uint_32 transformations),
++   PNG_EMPTY);
+ #endif
+ 
+ /* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
+ 
+ #ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Grab pixels out of a row for an interlaced pass */
+-PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
+-    png_bytep row, int pass),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_write_interlace,
++   (png_row_infop row_info, png_bytep row, int pass),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Unfilter a row: check the filter value before calling this, there is no point
+  * calling it for PNG_FILTER_VALUE_NONE.
+  */
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row,
++   (png_structrp pp, png_row_infop row_info,
++    png_bytep row, png_const_bytep prev_row, int filter),
++   PNG_EMPTY);
+ 
+ #if PNG_ARM_NEON_OPT > 0
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
+-    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_neon,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_MIPS_MSA_IMPLEMENTATION == 1
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
+-    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_msa,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_MIPS_MMI_IMPLEMENTATION > 0
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info,
+-    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_mmi,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_POWERPC_VSX_OPT > 0
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
+-    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_vsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_INTEL_SSE_IMPLEMENTATION > 0
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_sse2,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_sse2,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_sse2,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_sse2,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_sse2,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_sse2,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_lsx,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_RISCV_RVV_IMPLEMENTATION == 1
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_rvv,(png_row_infop
+-    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_rvv,
++   (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Choose the best filter to use and filter the row data */
+-PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
+-    png_row_infop row_info),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_write_find_filter,
++   (png_structrp png_ptr, png_row_infop row_info),
++   PNG_EMPTY);
+ 
+ #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
+-   png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_IDAT_data,
++   (png_structrp png_ptr, png_bytep output, png_alloc_size_t avail_out),
++   PNG_EMPTY);
+    /* Read 'avail_out' bytes of data from the IDAT stream.  If the output buffer
+     * is NULL the function checks, instead, for the end of the stream.  In this
+     * case a benign error will be issued if the stream end is not found or if
+     * extra data has to be consumed.
+     */
+-PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(void, png_read_finish_IDAT,
++   (png_structrp png_ptr),
+    PNG_EMPTY);
+    /* This cleans up when the IDAT LZ stream does not end when the last image
+     * byte is read; there is still some pending input.
+     */
+ 
+-PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(void, png_read_finish_row,
++   (png_structrp png_ptr),
+    PNG_EMPTY);
+    /* Finish a row while reading, dealing with interlacing passes, etc. */
+ #endif /* SEQUENTIAL_READ */
+ 
+ /* Initialize the row buffers, etc. */
+-PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_start_row,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ #if ZLIB_VERNUM >= 0x1240
+-PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
+-      PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_zlib_inflate,
++   (png_structrp png_ptr, int flush),
++   PNG_EMPTY);
+ #  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
+ #else /* Zlib < 1.2.4 */
+ #  define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
+@@ -1628,38 +1762,44 @@ PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
+ 
+ #ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ /* Optional call to update the users info structure */
+-PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
+-    png_inforp info_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_transform_info,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
+ #endif
+ 
+ /* Shared transform functions, defined in pngtran.c */
+ #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
+-    png_bytep row, int at_start),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_strip_channel,
++   (png_row_infop row_info, png_bytep row, int at_start),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_16BIT_SUPPORTED
+ #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,
+-    png_bytep row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_swap,
++   (png_row_infop row_info, png_bytep row),
++   PNG_EMPTY);
+ #endif
+ #endif
+ 
+ #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+     defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
+-    png_bytep row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_packswap,
++   (png_row_infop row_info, png_bytep row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
+-    png_bytep row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_invert,
++   (png_row_infop row_info, png_bytep row),
++   PNG_EMPTY);
+ #endif
+ 
+ #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
+-    png_bytep row),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_bgr,
++   (png_row_infop row_info, png_bytep row),
++   PNG_EMPTY);
+ #endif
+ 
+ /* The following decodes the appropriate chunks, and does error correction,
+@@ -1680,25 +1820,27 @@ typedef enum
+    handled_ok          /* known, supported and handled without error */
+ } png_handle_result_code;
+ 
+-PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_unknown,
+-    (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),
+-    PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_handle_result_code, png_handle_unknown,
++   (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),
++   PNG_EMPTY);
+    /* This is the function that gets called for unknown chunks.  The 'keep'
+     * argument is either non-zero for a known chunk that has been set to be
+     * handled as unknown or zero for an unknown chunk.  By default the function
+     * just skips the chunk or errors out if it is critical.
+     */
+ 
+-PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_chunk,
+-    (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_handle_result_code, png_handle_chunk,
++   (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),
++   PNG_EMPTY);
+    /* This handles the current chunk png_ptr->chunk_name with unread
+     * data[length] and returns one of the above result codes.
+     */
+ 
+ #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+     defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
+-    (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_chunk_unknown_handling,
++   (png_const_structrp png_ptr, png_uint_32 chunk_name),
++   PNG_EMPTY);
+    /* Exactly as the API png_handle_as_unknown() except that the argument is a
+     * 32-bit chunk name, not a string.
+     */
+@@ -1706,93 +1848,122 @@ PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
+ 
+ /* Handle the transformations for reading and writing */
+ #ifdef PNG_READ_TRANSFORMS_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
+-   png_row_infop row_info),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_read_transformations,
++   (png_structrp png_ptr, png_row_infop row_info),
++   PNG_EMPTY);
+ #endif
+ #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
+-   png_row_infop row_info),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_write_transformations,
++   (png_structrp png_ptr, png_row_infop row_info),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_READ_TRANSFORMS_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
+-    PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_init_read_transformations,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ #endif
+ 
+ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,
+-    png_inforp info_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,
+-    png_inforp info_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
+-    PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
+-    png_bytep buffer, size_t buffer_length),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
+-    png_bytep buffer, size_t buffer_length),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
+-    PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
+-   png_inforp info_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
+-   png_inforp info_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
+-    png_bytep row),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
+-    png_inforp info_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
+-    png_inforp info_ptr),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
+-    PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_read_chunk,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_read_sig,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_check_crc,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_save_buffer,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_restore_buffer,
++   (png_structrp png_ptr, png_bytep buffer, size_t buffer_length),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_read_IDAT,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_process_IDAT_data,
++   (png_structrp png_ptr, png_bytep buffer, size_t buffer_length),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_process_row,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_have_info,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_have_end,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_have_row,
++   (png_structrp png_ptr, png_bytep row),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_push_read_end,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_process_some_data,
++   (png_structrp png_ptr, png_inforp info_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_read_push_finish_row,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
+ #endif /* PROGRESSIVE_READ */
+ 
+ #ifdef PNG_iCCP_SUPPORTED
+ /* Routines for checking parts of an ICC profile. */
+ #ifdef PNG_READ_iCCP_SUPPORTED
+-PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
+-   png_const_charp name, png_uint_32 profile_length), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_icc_check_length,
++   (png_const_structrp png_ptr,
++    png_const_charp name, png_uint_32 profile_length),
++   PNG_EMPTY);
+ #endif /* READ_iCCP */
+-PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
+-   png_const_charp name, png_uint_32 profile_length,
+-   png_const_bytep profile /* first 132 bytes only */, int color_type),
++PNG_INTERNAL_FUNCTION(int, png_icc_check_header,
++   (png_const_structrp png_ptr,
++    png_const_charp name, png_uint_32 profile_length,
++    png_const_bytep profile /* first 132 bytes only */, int color_type),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_icc_check_tag_table,
++   (png_const_structrp png_ptr,
++    png_const_charp name, png_uint_32 profile_length,
++    png_const_bytep profile /* header plus whole tag table */),
+    PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
+-   png_const_charp name, png_uint_32 profile_length,
+-   png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
+ #endif /* iCCP */
+ 
+ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients, (png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(void, png_set_rgb_coefficients,
++   (png_structrp png_ptr),
+    PNG_EMPTY);
+    /* Set the rgb_to_gray coefficients from the cHRM Y values (if unset) */
+ #endif /* READ_RGB_TO_GRAY */
+ 
+ /* Added at libpng version 1.4.0 */
+-PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
+-    png_uint_32 width, png_uint_32 height, int bit_depth,
+-    int color_type, int interlace_type, int compression_type,
+-    int filter_type),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_check_IHDR,
++   (png_const_structrp png_ptr,
++    png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
++    int interlace_type, int compression_type, int filter_type),
++   PNG_EMPTY);
+ 
+ /* Added at libpng version 1.5.10 */
+ #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+     defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
+-   (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_do_check_palette_indexes,
++   (png_structrp png_ptr, png_row_infop row_info),
++   PNG_EMPTY);
+ #endif
+ 
+ #if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
+-   png_const_charp name),PNG_NORETURN);
++PNG_INTERNAL_FUNCTION(void, png_fixed_error,
++   (png_const_structrp png_ptr, png_const_charp name),
++   PNG_NORETURN);
+ #endif
+ 
+ /* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
+  * the end.  Always leaves the buffer nul terminated.  Never errors out (and
+  * there is no error code.)
+  */
+-PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
+-   size_t pos, png_const_charp string),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(size_t, png_safecat,
++   (png_charp buffer, size_t bufsize, size_t pos, png_const_charp string),
++   PNG_EMPTY);
+ 
+ /* Various internal functions to handle formatted warning messages, currently
+  * only implemented for warnings.
+@@ -1803,8 +1974,9 @@ PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
+  * Returns the pointer to the start of the formatted string.  This utility only
+  * does unsigned values.
+  */
+-PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
+-   png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_charp, png_format_number,
++   (png_const_charp start, png_charp end, int format, png_alloc_size_t number),
++   PNG_EMPTY);
+ 
+ /* Convenience macro that takes an array: */
+ #define PNG_FORMAT_NUMBER(buffer,format,number) \
+@@ -1836,23 +2008,26 @@ PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
+ typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
+    PNG_WARNING_PARAMETER_SIZE];
+ 
+-PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,
+-   int number, png_const_charp string),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_warning_parameter,
++   (png_warning_parameters p, int number, png_const_charp string),
++   PNG_EMPTY);
+    /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
+     * including the trailing '\0'.
+     */
+-PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,
++PNG_INTERNAL_FUNCTION(void, png_warning_parameter_unsigned,
+    (png_warning_parameters p, int number, int format, png_alloc_size_t value),
+    PNG_EMPTY);
+    /* Use png_alloc_size_t because it is an unsigned type as big as any we
+     * need to output.  Use the following for a signed value.
+     */
+-PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,
++PNG_INTERNAL_FUNCTION(void, png_warning_parameter_signed,
+    (png_warning_parameters p, int number, int format, png_int_32 value),
+    PNG_EMPTY);
+ 
+-PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
+-   png_warning_parameters p, png_const_charp message),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_formatted_warning,
++   (png_const_structrp png_ptr,
++    png_warning_parameters p, png_const_charp message),
++   PNG_EMPTY);
+    /* 'message' follows the X/Open approach of using @1, @2 to insert
+     * parameters previously supplied using the above functions.  Errors in
+     * specifying the parameters will simply result in garbage substitutions.
+@@ -1874,14 +2049,16 @@ PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
+  * If benign errors aren't supported they end up as the corresponding base call
+  * (png_warning or png_error.)
+  */
+-PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,
+-   png_const_charp message),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_app_warning,
++   (png_const_structrp png_ptr, png_const_charp message),
++   PNG_EMPTY);
+    /* The application provided invalid parameters to an API function or called
+     * an API function at the wrong time, libpng can completely recover.
+     */
+ 
+-PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
+-   png_const_charp message),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_app_error,
++   (png_const_structrp png_ptr, png_const_charp message),
++   PNG_EMPTY);
+    /* As above but libpng will ignore the call, or attempt some other partial
+     * recovery from the error.
+     */
+@@ -1890,8 +2067,9 @@ PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
+ #  define png_app_error(pp,s) png_error(pp,s)
+ #endif
+ 
+-PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
+-   png_const_charp message, int error),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_chunk_report,
++   (png_const_structrp png_ptr, png_const_charp message, int error),
++   PNG_EMPTY);
+    /* Report a recoverable issue in chunk data.  On read this is used to report
+     * a problem found while reading a particular chunk and the
+     * png_chunk_benign_error or png_chunk_warning function is used as
+@@ -1917,14 +2095,17 @@ PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
+ #define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
+ 
+ #ifdef PNG_FLOATING_POINT_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
+-   png_charp ascii, size_t size, double fp, unsigned int precision),
++PNG_INTERNAL_FUNCTION(void, png_ascii_from_fp,
++   (png_const_structrp png_ptr,
++    png_charp ascii, size_t size, double fp, unsigned int precision),
+    PNG_EMPTY);
+ #endif /* FLOATING_POINT */
+ 
+ #ifdef PNG_FIXED_POINT_SUPPORTED
+-PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
+-   png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_ascii_from_fixed,
++   (png_const_structrp png_ptr,
++    png_charp ascii, size_t size, png_fixed_point fp),
++   PNG_EMPTY);
+ #endif /* FIXED_POINT */
+ #endif /* sCAL */
+ 
+@@ -2016,8 +2197,9 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
+  * that omits the last character (i.e. set the size to the index of
+  * the problem character.)  This has not been tested within libpng.
+  */
+-PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
+-   size_t size, int *statep, size_t *whereami),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_check_fp_number,
++   (png_const_charp string, size_t size, int *statep, size_t *whereami),
++   PNG_EMPTY);
+ 
+ /* This is the same but it checks a complete string and returns true
+  * only if it just contains a floating point number.  As of 1.5.4 this
+@@ -2025,8 +2207,9 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
+  * it was valid (otherwise it returns 0.)  This can be used for testing
+  * for negative or zero values using the sticky flag.
+  */
+-PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
+-   size_t size),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_check_fp_string,
++   (png_const_charp string, size_t size),
++   PNG_EMPTY);
+ #endif /* pCAL || sCAL */
+ 
+ #if defined(PNG_READ_GAMMA_SUPPORTED) ||\
+@@ -2039,14 +2222,17 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
+  * for overflow, true (1) if no overflow, in which case *res
+  * holds the result.
+  */
+-PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
+-   png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_muldiv,
++   (png_fixed_point_p res, png_fixed_point a,
++    png_int_32 multiplied_by, png_int_32 divided_by),
++   PNG_EMPTY);
+ 
+ /* Calculate a reciprocal - used for gamma values.  This returns
+  * 0 if the argument is 0 in order to maintain an undefined value;
+  * there are no warnings.
+  */
+-PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
++PNG_INTERNAL_FUNCTION(png_fixed_point, png_reciprocal,
++   (png_fixed_point a),
+    PNG_EMPTY);
+ #endif
+ 
+@@ -2055,11 +2241,13 @@ PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
+  * values.  Accuracy is suitable for gamma calculations but this is
+  * not exact - use png_muldiv for that.  Only required at present on read.
+  */
+-PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
+-   png_fixed_point b),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_fixed_point, png_reciprocal2,
++   (png_fixed_point a, png_fixed_point b),
++   PNG_EMPTY);
+ 
+ /* Return true if the gamma value is significantly different from 1.0 */
+-PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
++PNG_INTERNAL_FUNCTION(int, png_gamma_significant,
++   (png_fixed_point gamma_value),
+    PNG_EMPTY);
+ 
+ /* PNGv3: 'resolve' the file gamma according to the new PNGv3 rules for colour
+@@ -2070,8 +2258,9 @@ PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
+  * transforms.  For this reason a gamma specified by png_set_gamma always takes
+  * precedence.
+  */
+-PNG_INTERNAL_FUNCTION(png_fixed_point,png_resolve_file_gamma,
+-   (png_const_structrp png_ptr),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_fixed_point, png_resolve_file_gamma,
++   (png_const_structrp png_ptr),
++   PNG_EMPTY);
+ 
+ /* Internal fixed point gamma correction.  These APIs are called as
+  * required to convert single values - they don't need to be fast,
+@@ -2080,37 +2269,45 @@ PNG_INTERNAL_FUNCTION(png_fixed_point,png_resolve_file_gamma,
+  * While the input is an 'unsigned' value it must actually be the
+  * correct bit value - 0..255 or 0..65535 as required.
+  */
+-PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
+-   unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
+-   png_fixed_point gamma_value),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
+-   png_fixed_point gamma_value),PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(png_uint_16, png_gamma_correct,
++   (png_structrp png_ptr, unsigned int value, png_fixed_point gamma_value),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_uint_16, png_gamma_16bit_correct,
++   (unsigned int value, png_fixed_point gamma_value),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_byte, png_gamma_8bit_correct,
++   (unsigned int value, png_fixed_point gamma_value),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_destroy_gamma_table,
++   (png_structrp png_ptr),
++   PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_build_gamma_table,
++   (png_structrp png_ptr, int bit_depth),
+    PNG_EMPTY);
+-PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
+-   int bit_depth),PNG_EMPTY);
+ #endif /* READ_GAMMA */
+ 
+ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Set the RGB coefficients if not already set by png_set_rgb_to_gray */
+-PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients,(png_structrp png_ptr),
++PNG_INTERNAL_FUNCTION(void, png_set_rgb_coefficients,
++   (png_structrp png_ptr),
+    PNG_EMPTY);
+ #endif
+ 
+ #if defined(PNG_cHRM_SUPPORTED) || defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+-PNG_INTERNAL_FUNCTION(int,png_XYZ_from_xy,(png_XYZ *XYZ, const png_xy *xy),
++PNG_INTERNAL_FUNCTION(int, png_XYZ_from_xy,
++   (png_XYZ *XYZ, const png_xy *xy),
+    PNG_EMPTY);
+ #endif /* cHRM || READ_RGB_TO_GRAY */
+ 
+ #ifdef PNG_COLORSPACE_SUPPORTED
+-PNG_INTERNAL_FUNCTION(int,png_xy_from_XYZ,(png_xy *xy, const png_XYZ *XYZ),
++PNG_INTERNAL_FUNCTION(int, png_xy_from_XYZ,
++   (png_xy *xy, const png_XYZ *XYZ),
+    PNG_EMPTY);
+ #endif
+ 
+ /* SIMPLIFIED READ/WRITE SUPPORT */
+ #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+-   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
++    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+ /* The internal structure that png_image::opaque points to. */
+ typedef struct png_control
+ {
+@@ -2138,28 +2335,34 @@ typedef struct png_control
+  * errors that might occur.  Returns true on success, false on failure (either
+  * of the function or as a result of a png_error.)
+  */
+-PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr,
+-   png_const_charp error_message),PNG_NORETURN);
++PNG_INTERNAL_CALLBACK(void, png_safe_error,
++   (png_structp png_ptr, png_const_charp error_message),
++   PNG_NORETURN);
+ 
+ #ifdef PNG_WARNINGS_SUPPORTED
+-PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr,
+-   png_const_charp warning_message),PNG_EMPTY);
++PNG_INTERNAL_CALLBACK(void, png_safe_warning,
++   (png_structp png_ptr, png_const_charp warning_message),
++   PNG_EMPTY);
+ #else
+ #  define png_safe_warning 0/*dummy argument*/
+ #endif
+ 
+-PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,
+-   int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_safe_execute,
++   (png_imagep image, int (*function)(png_voidp), png_voidp arg),
++   PNG_EMPTY);
+ 
+ /* Utility to log an error; this also cleans up the png_image; the function
+  * always returns 0 (false).
+  */
+-PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,
+-   png_const_charp error_message),PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(int, png_image_error,
++   (png_imagep image, png_const_charp error_message),
++   PNG_EMPTY);
+ 
+ #ifndef PNG_SIMPLIFIED_READ_SUPPORTED
+ /* png_image_free is used by the write code but not exported */
+-PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, png_image_free,
++   (png_imagep image),
++   PNG_EMPTY);
+ #endif /* !SIMPLIFIED_READ */
+ 
+ #endif /* SIMPLIFIED READ/WRITE */
+@@ -2170,8 +2373,9 @@ PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
+  * the generic code is used.
+  */
+ #ifdef PNG_FILTER_OPTIMIZATIONS
+-PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
+-   unsigned int bpp), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS,
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+    /* Just declare the optimization that will be used */
+ #else
+    /* List *all* the possible optimizations here - this branch is required if
+@@ -2180,37 +2384,44 @@ PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
+     */
+ #  if PNG_ARM_NEON_OPT > 0
+ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
+-   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+ #endif
+ 
+ #if PNG_MIPS_MSA_IMPLEMENTATION == 1
+ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
+-   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+ #endif
+ 
+ #  if PNG_MIPS_MMI_IMPLEMENTATION > 0
+ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
+-   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+ #  endif
+ 
+ #  if PNG_INTEL_SSE_IMPLEMENTATION > 0
+ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
+-   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+ #  endif
+ #endif
+ 
+ #if PNG_LOONGARCH_LSX_OPT > 0
+ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx,
+-    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+ #endif
+ 
+ #  if PNG_RISCV_RVV_IMPLEMENTATION == 1
+ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_rvv,
+-   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
++   (png_structp png_ptr, unsigned int bpp),
++   PNG_EMPTY);
+ #endif
+ 
+-PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
+-   png_const_charp key, png_bytep new_key), PNG_EMPTY);
++PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword,
++   (png_structrp png_ptr, png_const_charp key, png_bytep new_key),
++   PNG_EMPTY);
+ 
+ #if PNG_ARM_NEON_IMPLEMENTATION == 1
+ PNG_INTERNAL_FUNCTION(void,
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
+index b53668a09ce..79fd9ad6a82 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
+@@ -29,7 +29,7 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * Copyright (c) 2018-2025 Cosmin Truta
++ * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+  * Copyright (c) 1996-1997 Andreas Dilger
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -52,7 +52,8 @@
+ /* Create a PNG structure for reading, and allocate any memory needed. */
+ PNG_FUNCTION(png_structp,PNGAPI
+ png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+-    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
++    png_error_ptr error_fn, png_error_ptr warn_fn),
++    PNG_ALLOCATED)
+ {
+ #ifndef PNG_USER_MEM_SUPPORTED
+    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+@@ -68,7 +69,8 @@ png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ PNG_FUNCTION(png_structp,PNGAPI
+ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+     png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+-    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
++    png_malloc_ptr malloc_fn, png_free_ptr free_fn),
++    PNG_ALLOCATED)
+ {
+    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+        error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+@@ -548,7 +550,6 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
+ 
+    if (png_ptr->read_row_fn != NULL)
+       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+-
+ }
+ #endif /* SEQUENTIAL_READ */
+ 
+@@ -896,7 +897,7 @@ png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
+ #ifdef PNG_INFO_IMAGE_SUPPORTED
+ void PNGAPI
+ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
+-    int transforms, voidp params)
++    int transforms, png_voidp params)
+ {
+    png_debug(1, "in png_read_png");
+ 
+@@ -1133,19 +1134,20 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
+ 
+ typedef struct
+ {
+-   /* Arguments: */
++   /* Arguments */
+    png_imagep image;
+-   png_voidp  buffer;
++   png_voidp buffer;
+    png_int_32 row_stride;
+-   png_voidp  colormap;
++   png_voidp colormap;
+    png_const_colorp background;
+-   /* Local variables: */
+-   png_voidp       local_row;
+-   png_voidp       first_row;
+-   ptrdiff_t       row_bytes;           /* step between rows */
+-   int             file_encoding;       /* E_ values above */
+-   png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */
+-   int             colormap_processing; /* PNG_CMAP_ values above */
++
++   /* Instance variables */
++   png_voidp local_row;
++   png_voidp first_row;
++   ptrdiff_t row_step;              /* step between rows */
++   int file_encoding;               /* E_ values above */
++   png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */
++   int colormap_processing;         /* PNG_CMAP_ values above */
+ } png_image_read_control;
+ 
+ /* Do all the *safe* initialization - 'safe' means that png_error won't be
+@@ -2866,17 +2868,17 @@ png_image_read_and_map(png_voidp argument)
+    }
+ 
+    {
+-      png_uint_32  height = image->height;
+-      png_uint_32  width = image->width;
+-      int          proc = display->colormap_processing;
+-      png_bytep    first_row = png_voidcast(png_bytep, display->first_row);
+-      ptrdiff_t    step_row = display->row_bytes;
++      png_uint_32 height = image->height;
++      png_uint_32 width = image->width;
++      int proc = display->colormap_processing;
++      png_bytep first_row = png_voidcast(png_bytep, display->first_row);
++      ptrdiff_t row_step = display->row_step;
+       int pass;
+ 
+       for (pass = 0; pass < passes; ++pass)
+       {
+-         unsigned int     startx, stepx, stepy;
+-         png_uint_32      y;
++         unsigned int startx, stepx, stepy;
++         png_uint_32 y;
+ 
+          if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+          {
+@@ -2900,7 +2902,7 @@ png_image_read_and_map(png_voidp argument)
+          for (; ylocal_row);
+-            png_bytep outrow = first_row + y * step_row;
++            png_bytep outrow = first_row + y * row_step;
+             png_const_bytep end_row = outrow + width;
+ 
+             /* Read read the libpng data into the temporary buffer. */
+@@ -3109,20 +3111,20 @@ png_image_read_colormapped(png_voidp argument)
+     */
+    {
+       png_voidp first_row = display->buffer;
+-      ptrdiff_t row_bytes = display->row_stride;
++      ptrdiff_t row_step = display->row_stride;
+ 
+-      /* The following expression is designed to work correctly whether it gives
+-       * a signed or an unsigned result.
++      /* The following adjustment is to ensure that calculations are correct,
++       * regardless whether row_step is positive or negative.
+        */
+-      if (row_bytes < 0)
++      if (row_step < 0)
+       {
+          char *ptr = png_voidcast(char*, first_row);
+-         ptr += (image->height-1) * (-row_bytes);
++         ptr += (image->height-1) * (-row_step);
+          first_row = png_voidcast(png_voidp, ptr);
+       }
+ 
+       display->first_row = first_row;
+-      display->row_bytes = row_bytes;
++      display->row_step = row_step;
+    }
+ 
+    if (passes == 0)
+@@ -3140,17 +3142,17 @@ png_image_read_colormapped(png_voidp argument)
+ 
+    else
+    {
+-      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
++      ptrdiff_t row_step = display->row_step;
+ 
+       while (--passes >= 0)
+       {
+-         png_uint_32      y = image->height;
+-         png_bytep        row = png_voidcast(png_bytep, display->first_row);
++         png_uint_32 y = image->height;
++         png_bytep row = png_voidcast(png_bytep, display->first_row);
+ 
+          for (; y > 0; --y)
+          {
+             png_read_row(png_ptr, row, NULL);
+-            row += row_bytes;
++            row += row_step;
+          }
+       }
+ 
+@@ -3166,9 +3168,11 @@ png_image_read_direct_scaled(png_voidp argument)
+        argument);
+    png_imagep image = display->image;
+    png_structrp png_ptr = image->opaque->png_ptr;
++   png_inforp info_ptr = image->opaque->info_ptr;
+    png_bytep local_row = png_voidcast(png_bytep, display->local_row);
+    png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+-   ptrdiff_t row_bytes = display->row_bytes;
++   ptrdiff_t row_step = display->row_step;
++   size_t row_bytes = png_get_rowbytes(png_ptr, info_ptr);
+    int passes;
+ 
+    /* Handle interlacing. */
+@@ -3197,9 +3201,14 @@ png_image_read_direct_scaled(png_voidp argument)
+          /* Read into local_row (gets transformed 8-bit data). */
+          png_read_row(png_ptr, local_row, NULL);
+ 
+-         /* Copy from local_row to user buffer. */
+-         memcpy(output_row, local_row, (size_t)row_bytes);
+-         output_row += row_bytes;
++         /* Copy from local_row to user buffer.
++          * Use row_bytes (i.e. the actual size in bytes of the row data) for
++          * copying into output_row. Use row_step for advancing output_row,
++          * to respect the caller's stride for padding or negative (bottom-up)
++          * layouts.
++          */
++         memcpy(output_row, local_row, row_bytes);
++         output_row += row_step;
+       }
+    }
+ 
+@@ -3231,17 +3240,18 @@ png_image_read_composite(png_voidp argument)
+    }
+ 
+    {
+-      png_uint_32  height = image->height;
+-      png_uint_32  width = image->width;
+-      ptrdiff_t    step_row = display->row_bytes;
++      png_uint_32 height = image->height;
++      png_uint_32 width = image->width;
++      ptrdiff_t row_step = display->row_step;
+       unsigned int channels =
+           (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
++      int optimize_alpha = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
+       int pass;
+ 
+       for (pass = 0; pass < passes; ++pass)
+       {
+-         unsigned int     startx, stepx, stepy;
+-         png_uint_32      y;
++         unsigned int startx, stepx, stepy;
++         png_uint_32 y;
+ 
+          if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+          {
+@@ -3273,7 +3283,7 @@ png_image_read_composite(png_voidp argument)
+             png_read_row(png_ptr, inrow, NULL);
+ 
+             outrow = png_voidcast(png_bytep, display->first_row);
+-            outrow += y * step_row;
++            outrow += y * row_step;
+             end_row = outrow + width * channels;
+ 
+             /* Now do the composition on each pixel in this row. */
+@@ -3292,20 +3302,44 @@ png_image_read_composite(png_voidp argument)
+ 
+                      if (alpha < 255) /* else just use component */
+                      {
+-                        /* This is PNG_OPTIMIZED_ALPHA, the component value
+-                         * is a linear 8-bit value.  Combine this with the
+-                         * current outrow[c] value which is sRGB encoded.
+-                         * Arithmetic here is 16-bits to preserve the output
+-                         * values correctly.
+-                         */
+-                        component *= 257*255; /* =65535 */
+-                        component += (255-alpha)*png_sRGB_table[outrow[c]];
++                        if (optimize_alpha != 0)
++                        {
++                           /* This is PNG_OPTIMIZED_ALPHA, the component value
++                            * is a linear 8-bit value.  Combine this with the
++                            * current outrow[c] value which is sRGB encoded.
++                            * Arithmetic here is 16-bits to preserve the output
++                            * values correctly.
++                            */
++                           component *= 257*255; /* =65535 */
++                           component += (255-alpha)*png_sRGB_table[outrow[c]];
+ 
+-                        /* So 'component' is scaled by 255*65535 and is
+-                         * therefore appropriate for the sRGB to linear
+-                         * conversion table.
+-                         */
+-                        component = PNG_sRGB_FROM_LINEAR(component);
++                           /* Clamp to the valid range to defend against
++                            * unforeseen cases where the data might be sRGB
++                            * instead of linear premultiplied.
++                            * (Belt-and-suspenders for CVE-2025-66293.)
++                            */
++                           if (component > 255*65535)
++                              component = 255*65535;
++
++                           /* So 'component' is scaled by 255*65535 and is
++                            * therefore appropriate for the sRGB-to-linear
++                            * conversion table.
++                            */
++                           component = PNG_sRGB_FROM_LINEAR(component);
++                        }
++                        else
++                        {
++                           /* Compositing was already done on the palette
++                            * entries.  The data is sRGB premultiplied on black.
++                            * Composite with the background in sRGB space.
++                            * This is not gamma-correct, but matches what was
++                            * done to the palette.
++                            */
++                           png_uint_32 background = outrow[c];
++                           component += ((255-alpha) * background + 127) / 255;
++                           if (component > 255)
++                              component = 255;
++                        }
+                      }
+ 
+                      outrow[c] = (png_byte)component;
+@@ -3394,12 +3428,12 @@ png_image_read_background(png_voidp argument)
+           */
+          {
+             png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+-            ptrdiff_t step_row = display->row_bytes;
++            ptrdiff_t row_step = display->row_step;
+ 
+             for (pass = 0; pass < passes; ++pass)
+             {
+-               unsigned int     startx, stepx, stepy;
+-               png_uint_32      y;
++               unsigned int startx, stepx, stepy;
++               png_uint_32 y;
+ 
+                if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+                {
+@@ -3426,7 +3460,7 @@ png_image_read_background(png_voidp argument)
+                   {
+                      png_bytep inrow = png_voidcast(png_bytep,
+                          display->local_row);
+-                     png_bytep outrow = first_row + y * step_row;
++                     png_bytep outrow = first_row + y * row_step;
+                      png_const_bytep end_row = outrow + width;
+ 
+                      /* Read the row, which is packed: */
+@@ -3471,7 +3505,7 @@ png_image_read_background(png_voidp argument)
+                   {
+                      png_bytep inrow = png_voidcast(png_bytep,
+                          display->local_row);
+-                     png_bytep outrow = first_row + y * step_row;
++                     png_bytep outrow = first_row + y * row_step;
+                      png_const_bytep end_row = outrow + width;
+ 
+                      /* Read the row, which is packed: */
+@@ -3517,9 +3551,9 @@ png_image_read_background(png_voidp argument)
+             png_uint_16p first_row = png_voidcast(png_uint_16p,
+                 display->first_row);
+             /* The division by two is safe because the caller passed in a
+-             * stride which was multiplied by 2 (below) to get row_bytes.
++             * stride which was multiplied by 2 (below) to get row_step.
+              */
+-            ptrdiff_t    step_row = display->row_bytes / 2;
++            ptrdiff_t row_step = display->row_step / 2;
+             unsigned int preserve_alpha = (image->format &
+                 PNG_FORMAT_FLAG_ALPHA) != 0;
+             unsigned int outchannels = 1U+preserve_alpha;
+@@ -3533,8 +3567,8 @@ png_image_read_background(png_voidp argument)
+ 
+             for (pass = 0; pass < passes; ++pass)
+             {
+-               unsigned int     startx, stepx, stepy;
+-               png_uint_32      y;
++               unsigned int startx, stepx, stepy;
++               png_uint_32 y;
+ 
+                /* The 'x' start and step are adjusted to output components here.
+                 */
+@@ -3561,7 +3595,7 @@ png_image_read_background(png_voidp argument)
+                for (; ybuffer;
+-      ptrdiff_t row_bytes = display->row_stride;
++      ptrdiff_t row_step = display->row_stride;
+ 
+       if (linear != 0)
+-         row_bytes *= 2;
++         row_step *= 2;
+ 
+-      /* The following expression is designed to work correctly whether it gives
+-       * a signed or an unsigned result.
++      /* The following adjustment is to ensure that calculations are correct,
++       * regardless whether row_step is positive or negative.
+        */
+-      if (row_bytes < 0)
++      if (row_step < 0)
+       {
+          char *ptr = png_voidcast(char*, first_row);
+-         ptr += (image->height-1) * (-row_bytes);
++         ptr += (image->height - 1) * (-row_step);
+          first_row = png_voidcast(png_voidp, ptr);
+       }
+ 
+       display->first_row = first_row;
+-      display->row_bytes = row_bytes;
++      display->row_step = row_step;
+    }
+ 
+    if (do_local_compose != 0)
+@@ -4063,17 +4097,17 @@ png_image_read_direct(png_voidp argument)
+ 
+    else
+    {
+-      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
++      ptrdiff_t row_step = display->row_step;
+ 
+       while (--passes >= 0)
+       {
+-         png_uint_32      y = image->height;
+-         png_bytep        row = png_voidcast(png_bytep, display->first_row);
++         png_uint_32 y = image->height;
++         png_bytep row = png_voidcast(png_bytep, display->first_row);
+ 
+          for (; y > 0; --y)
+          {
+             png_read_row(png_ptr, row, NULL);
+-            row += row_bytes;
++            row += row_step;
+          }
+       }
+ 
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
+index a19615f49fe..7680fe64828 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
+@@ -1149,8 +1149,8 @@ png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
+ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ void PNGAPI
+-png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+-    read_user_transform_fn)
++png_set_read_user_transform_fn(png_structrp png_ptr,
++    png_user_transform_ptr read_user_transform_fn)
+ {
+    png_debug(1, "in png_set_read_user_transform_fn");
+ 
+@@ -1872,6 +1872,7 @@ png_init_read_transformations(png_structrp png_ptr)
+              * transformations elsewhere.
+              */
+             png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
++            png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+          } /* color_type == PNG_COLOR_TYPE_PALETTE */
+ 
+          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
+index 07d53cb2c76..01bb0c8bedc 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
+@@ -2415,7 +2415,7 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+ static png_handle_result_code /* PRIVATE */
+ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+ {
+-   png_text  text_info;
++   png_text text_info;
+    png_bytep buffer;
+    png_charp key;
+    png_charp text;
+@@ -2488,8 +2488,8 @@ static png_handle_result_code /* PRIVATE */
+ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+ {
+    png_const_charp errmsg = NULL;
+-   png_bytep       buffer;
+-   png_uint_32     keyword_length;
++   png_bytep buffer;
++   png_uint_32 keyword_length;
+ 
+    png_debug(1, "in png_handle_zTXt");
+ 
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
+index 2350057e70e..b9f6cb5d437 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
+@@ -831,8 +831,8 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
+     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ void PNGAPI
+-png_set_user_transform_info(png_structrp png_ptr, png_voidp
+-   user_transform_ptr, int user_transform_depth, int user_transform_channels)
++png_set_user_transform_info(png_structrp png_ptr, png_voidp user_transform_ptr,
++    int user_transform_depth, int user_transform_channels)
+ {
+    png_debug(1, "in png_set_user_transform_info");
+ 
diff --git a/jdk8377526-libpng-1.6.55.patch b/jdk8377526-libpng-1.6.55.patch
new file mode 100644
index 0000000..d13ce67
--- /dev/null
+++ b/jdk8377526-libpng-1.6.55.patch
@@ -0,0 +1,248 @@
+commit b64f9e043d63b113682ea395e5bd8df2a26327ef
+Author:     Sergey Bylokhov 
+AuthorDate: Mon Mar 2 18:56:22 2026 +0000
+Commit:     Sergey Bylokhov 
+CommitDate: Mon Mar 2 18:56:22 2026 +0000
+
+    8377526: Update Libpng to 1.6.55
+    
+    Backport-of: fd74232d5dc4c6bfbcddb82e1b2621289aa2f65a
+
+diff --git a/src/java.desktop/share/legal/libpng.md b/src/java.desktop/share/legal/libpng.md
+index 80d12248ec4..a2ffcca1974 100644
+--- a/src/java.desktop/share/legal/libpng.md
++++ b/src/java.desktop/share/legal/libpng.md
+@@ -1,4 +1,4 @@
+-## libpng v1.6.54
++## libpng v1.6.55
+ 
+ ### libpng License
+ 
+@@ -170,6 +170,7 @@ ### AUTHORS File Information
+  * Guy Eric Schalnat
+  * James Yu
+  * John Bowler
++ * Joshua Inscoe
+  * Kevin Bracey
+  * Lucas Chollet
+  * Magnus Holmgren
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+index 3bb1baecd23..af9fcff6eb3 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+@@ -5988,7 +5988,7 @@ Version 1.6.32rc01 [August 18, 2017]
+ 
+ Version 1.6.32rc02 [August 22, 2017]
+   Added contrib/oss-fuzz directory which contains files used by the oss-fuzz
+-    project (https://github.com/google/oss-fuzz/tree/master/projects/libpng).
++    project .
+ 
+ Version 1.6.32 [August 24, 2017]
+   No changes.
+@@ -6323,15 +6323,21 @@ Version 1.6.53 [December 5, 2025]
+ 
+ Version 1.6.54 [January 12, 2026]
+   Fixed CVE-2026-22695 (medium severity):
+-    Heap buffer over-read in `png_image_read_direct_scaled.
++    Heap buffer over-read in `png_image_read_direct_scaled`.
+     (Reported and fixed by Petr Simecek.)
+   Fixed CVE-2026-22801 (medium severity):
+     Integer truncation causing heap buffer over-read in `png_image_write_*`.
+   Implemented various improvements in oss-fuzz.
+     (Contributed by Philippe Antoine.)
+ 
++Version 1.6.55 [February 9, 2026]
++  Fixed CVE-2026-25646 (high severity):
++    Heap buffer overflow in `png_set_quantize`.
++    (Reported and fixed by Joshua Inscoe.)
++  Resolved an oss-fuzz build issue involving nalloc.
++    (Contributed by Philippe Antoine.)
+ 
+ Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
+ Subscription is required; visit
+-https://lists.sourceforge.net/lists/listinfo/png-mng-implement
++
+ to subscribe.
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/README b/src/java.desktop/share/native/libsplashscreen/libpng/README
+index 63d1376edf7..6e0d1e33137 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/README
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/README
+@@ -1,4 +1,4 @@
+-README for libpng version 1.6.54
++README for libpng version 1.6.55
+ ================================
+ 
+ See the note about version numbers near the top of `png.h`.
+@@ -24,14 +24,14 @@ for more things than just PNG files.  You can use zlib as a drop-in
+ replacement for `fread()` and `fwrite()`, if you are so inclined.
+ 
+ zlib should be available at the same place that libpng is, or at
+-https://zlib.net .
++.
+ 
+ You may also want a copy of the PNG specification.  It is available
+ as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
+-these at http://www.libpng.org/pub/png/pngdocs.html .
++these at .
+ 
+-This code is currently being archived at https://libpng.sourceforge.io
+-in the download area, and at http://libpng.download/src .
++This code is currently being archived at 
++in the download area, and at .
+ 
+ This release, based in a large way on Glenn's, Guy's and Andreas'
+ earlier work, was created and will be supported by myself and the PNG
+@@ -39,12 +39,12 @@ development group.
+ 
+ Send comments, corrections and commendations to `png-mng-implement`
+ at `lists.sourceforge.net`.  (Subscription is required; visit
+-https://lists.sourceforge.net/lists/listinfo/png-mng-implement
++
+ to subscribe.)
+ 
+ Send general questions about the PNG specification to `png-mng-misc`
+ at `lists.sourceforge.net`.  (Subscription is required; visit
+-https://lists.sourceforge.net/lists/listinfo/png-mng-misc
++
+ to subscribe.)
+ 
+ Historical notes
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.c b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+index 5636b4a754e..955fda8dd7e 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+@@ -42,7 +42,7 @@
+ #include "pngpriv.h"
+ 
+ /* Generate a compiler error if there is an old png.h in the search path. */
+-typedef png_libpng_version_1_6_54 Your_png_h_is_not_version_1_6_54;
++typedef png_libpng_version_1_6_55 Your_png_h_is_not_version_1_6_55;
+ 
+ /* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
+  * corresponding macro definitions.  This causes a compile time failure if
+@@ -849,7 +849,7 @@ png_get_copyright(png_const_structrp png_ptr)
+    return PNG_STRING_COPYRIGHT
+ #else
+    return PNG_STRING_NEWLINE \
+-      "libpng version 1.6.54" PNG_STRING_NEWLINE \
++      "libpng version 1.6.55" PNG_STRING_NEWLINE \
+       "Copyright (c) 2018-2026 Cosmin Truta" PNG_STRING_NEWLINE \
+       "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
+       PNG_STRING_NEWLINE \
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.h b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+index ab8876a9626..e95c0444399 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+@@ -29,7 +29,7 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * libpng version 1.6.54
++ * libpng version 1.6.55
+  *
+  * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+@@ -43,7 +43,7 @@
+  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
+  *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
+  *     Glenn Randers-Pehrson
+- *   libpng versions 1.6.36, December 2018, through 1.6.54, January 2026:
++ *   libpng versions 1.6.36, December 2018, through 1.6.55, February 2026:
+  *     Cosmin Truta
+  *   See also "Contributing Authors", below.
+  */
+@@ -267,7 +267,7 @@
+  *    ...
+  *    1.5.30                  15    10530  15.so.15.30[.0]
+  *    ...
+- *    1.6.54                  16    10654  16.so.16.54[.0]
++ *    1.6.55                  16    10655  16.so.16.55[.0]
+  *
+  *    Henceforth the source version will match the shared-library major and
+  *    minor numbers; the shared-library major version number will be used for
+@@ -303,7 +303,7 @@
+  */
+ 
+ /* Version information for png.h - this should match the version in png.c */
+-#define PNG_LIBPNG_VER_STRING "1.6.54"
++#define PNG_LIBPNG_VER_STRING "1.6.55"
+ #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
+ 
+ /* The versions of shared library builds should stay in sync, going forward */
+@@ -314,7 +314,7 @@
+ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+ #define PNG_LIBPNG_VER_MAJOR   1
+ #define PNG_LIBPNG_VER_MINOR   6
+-#define PNG_LIBPNG_VER_RELEASE 54
++#define PNG_LIBPNG_VER_RELEASE 55
+ 
+ /* This should be zero for a public release, or non-zero for a
+  * development version.
+@@ -345,7 +345,7 @@
+  * From version 1.0.1 it is:
+  * XXYYZZ, where XX=major, YY=minor, ZZ=release
+  */
+-#define PNG_LIBPNG_VER 10654 /* 1.6.54 */
++#define PNG_LIBPNG_VER 10655 /* 1.6.55 */
+ 
+ /* Library configuration: these options cannot be changed after
+  * the library has been built.
+@@ -455,7 +455,7 @@ extern "C" {
+ /* This triggers a compiler error in png.c, if png.c and png.h
+  * do not agree upon the version number.
+  */
+-typedef char *png_libpng_version_1_6_54;
++typedef char *png_libpng_version_1_6_55;
+ 
+ /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
+  *
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+index 959c604edbc..b957f8b5061 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+@@ -29,7 +29,7 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * libpng version 1.6.54
++ * libpng version 1.6.55
+  *
+  * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+index b413b510acf..ae1ab462072 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+@@ -31,7 +31,7 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  */
+-/* libpng version 1.6.54 */
++/* libpng version 1.6.55 */
+ 
+ /* Copyright (c) 2018-2026 Cosmin Truta */
+ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
+diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
+index 7680fe64828..fcce80da1cb 100644
+--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
++++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
+@@ -29,7 +29,7 @@
+  * However, the following notice accompanied the original version of this
+  * file and, per its terms, should not be removed:
+  *
+- * Copyright (c) 2018-2025 Cosmin Truta
++ * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+  * Copyright (c) 1996-1997 Andreas Dilger
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -737,8 +737,8 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
+                          break;
+ 
+                      t->next = hash[d];
+-                     t->left = (png_byte)i;
+-                     t->right = (png_byte)j;
++                     t->left = png_ptr->palette_to_index[i];
++                     t->right = png_ptr->palette_to_index[j];
+                      hash[d] = t;
+                   }
+                }