summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSudarsana Babu Nagineni <sudarsana.babu@mapbox.com>2018-07-30 15:30:57 +0300
committerSudarsana Babu Nagineni <sudarsana.babu@mapbox.com>2018-08-06 16:55:30 +0300
commit0130c58fdd74edbbfe668f3125a9377554d7d605 (patch)
tree6be1c1d25d146e9273f04f40f2283e18048c17ac
parent7373abef92ed4911b91f9fca3d97784ed0d9e02e (diff)
downloadqtlocation-mapboxgl-0130c58fdd74edbbfe668f3125a9377554d7d605.tar.gz
Bump Mapbox GL Native
Bump version. mapbox-gl-native @ 377a6e42d687c419e6ae1012b8626336f5dfc1b6
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt.hpp)35
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/clip.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/clip.hpp)16
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/convert.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/convert.hpp)3
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/simplify.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/simplify.hpp)12
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/tile.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/tile.hpp)59
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/types.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/types.hpp)10
-rw-r--r--deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/wrap.hpp (renamed from deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/wrap.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/box.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/box.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/envelope.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/envelope.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/feature.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/feature.hpp)7
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/for_each_point.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/for_each_point.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/geometry.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/geometry.hpp)10
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/line_string.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/line_string.hpp)7
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/multi_line_string.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/multi_line_string.hpp)7
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/multi_point.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/multi_point.hpp)7
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/multi_polygon.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/multi_polygon.hpp)7
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/point.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/point.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/point_arithmetic.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/point_arithmetic.hpp)0
-rw-r--r--deps/geometry/0.9.3/include/mapbox/geometry/polygon.hpp (renamed from deps/geometry/0.9.2/include/mapbox/geometry/polygon.hpp)14
-rw-r--r--deps/optional/f27e7908/include/experimental/optional1052
-rw-r--r--deps/vector-tile/1.0.2/include/mapbox/vector_tile.hpp (renamed from deps/vector-tile/1.0.1/include/mapbox/vector_tile.hpp)8
-rw-r--r--deps/vector-tile/1.0.2/include/mapbox/vector_tile/vector_tile_config.hpp (renamed from deps/vector-tile/1.0.1/include/mapbox/vector_tile/vector_tile_config.hpp)0
-rw-r--r--deps/vector-tile/1.0.2/include/mapbox/vector_tile/version.hpp (renamed from deps/vector-tile/1.0.1/include/mapbox/vector_tile/version.hpp)4
-rw-r--r--include/mbgl/actor/actor.hpp61
-rw-r--r--include/mbgl/actor/aspiring_actor.hpp60
-rw-r--r--include/mbgl/actor/established_actor.hpp80
-rw-r--r--include/mbgl/actor/mailbox.hpp21
-rw-r--r--include/mbgl/actor/scheduler.hpp5
-rw-r--r--include/mbgl/map/map.hpp6
-rw-r--r--include/mbgl/math/log2.hpp13
-rw-r--r--include/mbgl/style/color_ramp_property_value.hpp (renamed from include/mbgl/style/heatmap_color_property_value.hpp)22
-rw-r--r--include/mbgl/style/conversion/color_ramp_property_value.hpp (renamed from include/mbgl/style/conversion/heatmap_color_property_value.hpp)14
-rw-r--r--include/mbgl/style/conversion/data_driven_property_value.hpp83
-rw-r--r--include/mbgl/style/conversion/function.hpp382
-rw-r--r--include/mbgl/style/conversion/property_value.hpp52
-rw-r--r--include/mbgl/style/data_driven_property_value.hpp38
-rw-r--r--include/mbgl/style/expression/array_assertion.hpp5
-rw-r--r--include/mbgl/style/expression/assertion.hpp5
-rw-r--r--include/mbgl/style/expression/at.hpp5
-rw-r--r--include/mbgl/style/expression/boolean_operator.hpp4
-rw-r--r--include/mbgl/style/expression/case.hpp2
-rw-r--r--include/mbgl/style/expression/coalesce.hpp2
-rw-r--r--include/mbgl/style/expression/collator.hpp29
-rw-r--r--include/mbgl/style/expression/collator_expression.hpp44
-rw-r--r--include/mbgl/style/expression/compound_expression.hpp16
-rw-r--r--include/mbgl/style/expression/dsl.hpp84
-rw-r--r--include/mbgl/style/expression/equals.hpp4
-rw-r--r--include/mbgl/style/expression/error.hpp39
-rw-r--r--include/mbgl/style/expression/expression.hpp27
-rw-r--r--include/mbgl/style/expression/find_zoom_curve.hpp4
-rw-r--r--include/mbgl/style/expression/interpolate.hpp153
-rw-r--r--include/mbgl/style/expression/interpolator.hpp50
-rw-r--r--include/mbgl/style/expression/is_constant.hpp3
-rw-r--r--include/mbgl/style/expression/let.hpp10
-rw-r--r--include/mbgl/style/expression/literal.hpp8
-rw-r--r--include/mbgl/style/expression/match.hpp2
-rw-r--r--include/mbgl/style/expression/step.hpp11
-rw-r--r--include/mbgl/style/expression/type.hpp8
-rw-r--r--include/mbgl/style/expression/value.hpp66
-rw-r--r--include/mbgl/style/filter.hpp284
-rw-r--r--include/mbgl/style/filter_evaluator.hpp55
-rw-r--r--include/mbgl/style/function/camera_function.hpp90
-rw-r--r--include/mbgl/style/function/categorical_stops.hpp40
-rw-r--r--include/mbgl/style/function/composite_categorical_stops.hpp30
-rw-r--r--include/mbgl/style/function/composite_exponential_stops.hpp35
-rw-r--r--include/mbgl/style/function/composite_function.hpp126
-rw-r--r--include/mbgl/style/function/composite_interval_stops.hpp32
-rw-r--r--include/mbgl/style/function/convert.hpp356
-rw-r--r--include/mbgl/style/function/exponential_stops.hpp56
-rw-r--r--include/mbgl/style/function/identity_stops.hpp20
-rw-r--r--include/mbgl/style/function/interval_stops.hpp51
-rw-r--r--include/mbgl/style/function/source_function.hpp80
-rw-r--r--include/mbgl/style/layers/heatmap_layer.hpp8
-rw-r--r--include/mbgl/style/layers/layer.hpp.ejs93
-rw-r--r--include/mbgl/style/layers/raster_layer.hpp6
-rw-r--r--include/mbgl/style/light.hpp.ejs40
-rw-r--r--include/mbgl/style/property_expression.hpp117
-rw-r--r--include/mbgl/style/property_value.hpp23
-rw-r--r--include/mbgl/style/types.hpp8
-rw-r--r--include/mbgl/tile/tile_id.hpp20
-rw-r--r--include/mbgl/util/constants.hpp2
-rw-r--r--include/mbgl/util/event.hpp1
-rw-r--r--include/mbgl/util/logging.hpp4
-rw-r--r--include/mbgl/util/projection.hpp3
-rw-r--r--include/mbgl/util/thread.hpp55
-rw-r--r--include/mbgl/util/unique_any.hpp16
-rw-r--r--mapbox-gl-native.pro47
-rw-r--r--platform/default/collator.cpp79
-rw-r--r--platform/default/default_file_source.cpp21
-rw-r--r--platform/default/http_file_source.cpp165
-rw-r--r--platform/default/mbgl/map/map_snapshotter.cpp75
-rw-r--r--platform/default/mbgl/map/map_snapshotter.hpp14
-rw-r--r--platform/default/mbgl/storage/.clang-tidy2
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp168
-rw-r--r--platform/default/mbgl/storage/offline_database.hpp12
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp40
-rw-r--r--platform/default/mbgl/storage/offline_download.hpp4
-rw-r--r--platform/default/mbgl/storage/offline_schema.hpp (renamed from platform/default/mbgl/storage/offline_schema.cpp.include)12
-rw-r--r--platform/default/mbgl/storage/offline_schema.js21
-rw-r--r--platform/default/mbgl/storage/offline_schema.sql64
-rw-r--r--platform/default/sqlite3.cpp146
-rw-r--r--platform/default/sqlite3.hpp19
-rw-r--r--platform/default/string_stdlib.cpp5
-rw-r--r--platform/default/unaccent.cpp43
-rw-r--r--platform/default/unaccent.hpp13
-rw-r--r--platform/qt/include/qmapboxgl.hpp4
-rw-r--r--platform/qt/src/qmapboxgl.cpp108
-rw-r--r--platform/qt/src/qmapboxgl_map_renderer.cpp67
-rw-r--r--platform/qt/src/qmapboxgl_map_renderer.hpp11
-rw-r--r--platform/qt/src/qmapboxgl_scheduler.cpp38
-rw-r--r--platform/qt/src/qmapboxgl_scheduler.hpp34
-rw-r--r--platform/qt/src/qt_geojson.cpp7
-rw-r--r--platform/qt/src/sqlite3.cpp107
-rw-r--r--qt_attribution.json13
-rw-r--r--src/csscolorparser/csscolorparser.cpp6
-rw-r--r--src/mbgl/actor/mailbox.cpp35
-rw-r--r--src/mbgl/algorithm/covered_by_children.hpp16
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp4
-rw-r--r--src/mbgl/geometry/feature_index.cpp12
-rw-r--r--src/mbgl/geometry/line_atlas.cpp7
-rw-r--r--src/mbgl/gl/attribute.cpp14
-rw-r--r--src/mbgl/gl/attribute.hpp18
-rw-r--r--src/mbgl/gl/context.cpp14
-rw-r--r--src/mbgl/gl/context.hpp8
-rw-r--r--src/mbgl/gl/program.hpp2
-rw-r--r--src/mbgl/gl/vertex_array.cpp6
-rw-r--r--src/mbgl/gl/vertex_array.hpp13
-rw-r--r--src/mbgl/layout/symbol_instance.cpp8
-rw-r--r--src/mbgl/layout/symbol_instance.hpp8
-rw-r--r--src/mbgl/layout/symbol_layout.cpp70
-rw-r--r--src/mbgl/map/map.cpp39
-rw-r--r--src/mbgl/map/transform.cpp57
-rw-r--r--src/mbgl/map/transform.hpp2
-rw-r--r--src/mbgl/map/transform_state.cpp6
-rw-r--r--src/mbgl/programs/program.hpp34
-rw-r--r--src/mbgl/programs/symbol_program.cpp19
-rw-r--r--src/mbgl/programs/symbol_program.hpp98
-rw-r--r--src/mbgl/renderer/backend_scope.cpp22
-rw-r--r--src/mbgl/renderer/bucket.hpp22
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.cpp3
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/fill_bucket.cpp3
-rw-r--r--src/mbgl/renderer/buckets/fill_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp7
-rw-r--r--src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/heatmap_bucket.cpp3
-rw-r--r--src/mbgl/renderer/buckets/heatmap_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/hillshade_bucket.cpp8
-rw-r--r--src/mbgl/renderer/buckets/hillshade_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.cpp3
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/raster_bucket.cpp10
-rw-r--r--src/mbgl/renderer/buckets/raster_bucket.hpp5
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp11
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp5
-rw-r--r--src/mbgl/renderer/cross_faded_property_evaluator.cpp8
-rw-r--r--src/mbgl/renderer/cross_faded_property_evaluator.hpp2
-rw-r--r--src/mbgl/renderer/data_driven_property_evaluator.hpp19
-rw-r--r--src/mbgl/renderer/layers/render_background_layer.cpp63
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.cpp44
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp111
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.cpp80
-rw-r--r--src/mbgl/renderer/layers/render_heatmap_layer.cpp75
-rw-r--r--src/mbgl/renderer/layers/render_hillshade_layer.cpp73
-rw-r--r--src/mbgl/renderer/layers/render_line_layer.cpp34
-rw-r--r--src/mbgl/renderer/layers/render_raster_layer.cpp50
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp64
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.hpp2
-rw-r--r--src/mbgl/renderer/paint_property_binder.hpp33
-rw-r--r--src/mbgl/renderer/possibly_evaluated_property_value.hpp23
-rw-r--r--src/mbgl/renderer/property_evaluator.hpp2
-rw-r--r--src/mbgl/renderer/render_layer.cpp29
-rw-r--r--src/mbgl/renderer/render_layer.hpp11
-rw-r--r--src/mbgl/renderer/render_tile.cpp70
-rw-r--r--src/mbgl/renderer/render_tile.hpp2
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp37
-rw-r--r--src/mbgl/renderer/sources/render_image_source.cpp30
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp40
-rw-r--r--src/mbgl/renderer/tile_pyramid.hpp4
-rw-r--r--src/mbgl/shaders/background.cpp26
-rw-r--r--src/mbgl/shaders/background_pattern.cpp57
-rw-r--r--src/mbgl/shaders/circle.cpp279
-rw-r--r--src/mbgl/shaders/clipping_mask.cpp19
-rw-r--r--src/mbgl/shaders/collision_box.cpp55
-rw-r--r--src/mbgl/shaders/collision_circle.cpp79
-rw-r--r--src/mbgl/shaders/debug.cpp21
-rw-r--r--src/mbgl/shaders/extrusion_texture.cpp31
-rw-r--r--src/mbgl/shaders/fill.cpp83
-rw-r--r--src/mbgl/shaders/fill_extrusion.cpp156
-rw-r--r--src/mbgl/shaders/fill_extrusion_pattern.cpp150
-rw-r--r--src/mbgl/shaders/fill_outline.cpp91
-rw-r--r--src/mbgl/shaders/fill_outline_pattern.cpp99
-rw-r--r--src/mbgl/shaders/fill_pattern.cpp88
-rw-r--r--src/mbgl/shaders/heatmap.cpp120
-rw-r--r--src/mbgl/shaders/heatmap_texture.cpp34
-rw-r--r--src/mbgl/shaders/hillshade.cpp72
-rw-r--r--src/mbgl/shaders/hillshade_prepare.cpp92
-rw-r--r--src/mbgl/shaders/line.cpp232
-rw-r--r--src/mbgl/shaders/line_pattern.cpp233
-rw-r--r--src/mbgl/shaders/line_sdf.cpp294
-rw-r--r--src/mbgl/shaders/preludes.cpp99
-rw-r--r--src/mbgl/shaders/raster.cpp82
-rw-r--r--src/mbgl/shaders/source.cpp1468
-rw-r--r--src/mbgl/shaders/source.hpp11
-rw-r--r--src/mbgl/shaders/symbol_icon.cpp141
-rw-r--r--src/mbgl/shaders/symbol_sdf.cpp296
-rw-r--r--src/mbgl/sprite/sprite_loader.cpp2
-rw-r--r--src/mbgl/storage/resource.cpp12
-rw-r--r--src/mbgl/style/conversion/filter.cpp368
-rw-r--r--src/mbgl/style/conversion/function.cpp724
-rw-r--r--src/mbgl/style/conversion/light.cpp8
-rw-r--r--src/mbgl/style/conversion/make_property_setters.hpp8
-rw-r--r--src/mbgl/style/conversion/make_property_setters.hpp.ejs46
-rw-r--r--src/mbgl/style/conversion/property_setter.hpp7
-rw-r--r--src/mbgl/style/conversion/stringify.hpp171
-rw-r--r--src/mbgl/style/conversion/tileset.cpp17
-rw-r--r--src/mbgl/style/conversion/transition_options.cpp6
-rw-r--r--src/mbgl/style/expression/assertion.cpp11
-rw-r--r--src/mbgl/style/expression/boolean_operator.cpp6
-rw-r--r--src/mbgl/style/expression/case.cpp3
-rw-r--r--src/mbgl/style/expression/coalesce.cpp3
-rw-r--r--src/mbgl/style/expression/coercion.cpp8
-rw-r--r--src/mbgl/style/expression/collator_expression.cpp121
-rw-r--r--src/mbgl/style/expression/compound_expression.cpp460
-rw-r--r--src/mbgl/style/expression/dsl.cpp183
-rw-r--r--src/mbgl/style/expression/equals.cpp54
-rw-r--r--src/mbgl/style/expression/expression.cpp (renamed from src/mbgl/style/function/expression.cpp)0
-rw-r--r--src/mbgl/style/expression/find_zoom_curve.cpp59
-rw-r--r--src/mbgl/style/expression/interpolate.cpp168
-rw-r--r--src/mbgl/style/expression/is_constant.cpp17
-rw-r--r--src/mbgl/style/expression/length.cpp5
-rw-r--r--src/mbgl/style/expression/literal.cpp1
-rw-r--r--src/mbgl/style/expression/match.cpp27
-rw-r--r--src/mbgl/style/expression/parsing_context.cpp19
-rw-r--r--src/mbgl/style/expression/step.cpp25
-rw-r--r--src/mbgl/style/expression/value.cpp98
-rw-r--r--src/mbgl/style/filter.cpp12
-rw-r--r--src/mbgl/style/filter_evaluator.cpp225
-rw-r--r--src/mbgl/style/function/categorical_stops.cpp41
-rw-r--r--src/mbgl/style/function/identity_stops.cpp89
-rw-r--r--src/mbgl/style/layers/heatmap_layer.cpp10
-rw-r--r--src/mbgl/style/layers/heatmap_layer_properties.hpp2
-rw-r--r--src/mbgl/style/layers/layer.cpp.ejs179
-rw-r--r--src/mbgl/style/layers/layer_properties.cpp.ejs14
-rw-r--r--src/mbgl/style/layers/layer_properties.hpp.ejs54
-rw-r--r--src/mbgl/style/layers/raster_layer.cpp27
-rw-r--r--src/mbgl/style/layers/raster_layer_properties.hpp5
-rw-r--r--src/mbgl/style/light.cpp.ejs60
-rw-r--r--src/mbgl/style/paint_property.hpp14
-rw-r--r--src/mbgl/style/properties.hpp5
-rw-r--r--src/mbgl/style/sources/custom_geometry_source.cpp6
-rw-r--r--src/mbgl/style/types.cpp6
-rw-r--r--src/mbgl/text/collision_feature.cpp8
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.cpp39
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.hpp4
-rw-r--r--src/mbgl/text/get_anchors.cpp77
-rw-r--r--src/mbgl/text/get_anchors.hpp10
-rw-r--r--src/mbgl/text/language_tag.cpp237
-rw-r--r--src/mbgl/text/language_tag.hpp44
-rw-r--r--src/mbgl/text/placement.cpp84
-rw-r--r--src/mbgl/text/placement.hpp4
-rw-r--r--src/mbgl/text/quads.cpp2
-rw-r--r--src/mbgl/tile/custom_geometry_tile.cpp7
-rw-r--r--src/mbgl/tile/geojson_tile.cpp1
-rw-r--r--src/mbgl/tile/geometry_tile.cpp11
-rw-r--r--src/mbgl/tile/geometry_tile_data.hpp16
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp14
-rw-r--r--src/mbgl/tile/raster_dem_tile.cpp2
-rw-r--r--src/mbgl/tile/raster_tile.cpp2
-rw-r--r--src/mbgl/tile/tile.hpp8
-rw-r--r--src/mbgl/util/chrono.cpp2
-rw-r--r--src/mbgl/util/event.cpp1
-rw-r--r--src/mbgl/util/http_header.cpp3
-rw-r--r--src/mbgl/util/interpolate.cpp3
-rw-r--r--src/mbgl/util/io.cpp25
-rw-r--r--src/mbgl/util/io.hpp4
-rw-r--r--src/mbgl/util/logging.cpp10
-rw-r--r--src/mbgl/util/stopwatch.hpp15
-rw-r--r--src/mbgl/util/tile_coordinate.hpp2
-rw-r--r--src/mbgl/util/tile_cover.cpp2
-rw-r--r--src/mbgl/util/tile_cover_impl.cpp129
-rw-r--r--src/mbgl/util/tile_cover_impl.hpp16
-rw-r--r--src/mbgl/util/token.hpp11
-rw-r--r--src/mbgl/util/url.cpp5
-rw-r--r--src/parsedate/parsedate.cpp (renamed from src/parsedate/parsedate.c)4
-rw-r--r--src/parsedate/parsedate.hpp (renamed from src/parsedate/parsedate.h)0
-rw-r--r--vendor/nunicode/LICENSE19
-rw-r--r--vendor/nunicode/files.txt20
-rw-r--r--vendor/nunicode/include/libnu/casemap.h140
-rw-r--r--vendor/nunicode/include/libnu/casemap_internal.h21
-rw-r--r--vendor/nunicode/include/libnu/config.h201
-rw-r--r--vendor/nunicode/include/libnu/defines.h43
-rw-r--r--vendor/nunicode/include/libnu/ducet.h37
-rw-r--r--vendor/nunicode/include/libnu/mph.h71
-rw-r--r--vendor/nunicode/include/libnu/strcoll.h199
-rw-r--r--vendor/nunicode/include/libnu/strcoll_internal.h232
-rw-r--r--vendor/nunicode/include/libnu/strings.h142
-rw-r--r--vendor/nunicode/include/libnu/udb.h81
-rw-r--r--vendor/nunicode/include/libnu/unaccent.h57
-rw-r--r--vendor/nunicode/include/libnu/utf8.h130
-rw-r--r--vendor/nunicode/include/libnu/utf8_internal.h168
-rw-r--r--vendor/nunicode/src/libnu/ducet.c65
-rw-r--r--vendor/nunicode/src/libnu/gen/_ducet.c6197
-rw-r--r--vendor/nunicode/src/libnu/gen/_ducet_switch.c1216
-rw-r--r--vendor/nunicode/src/libnu/gen/_tolower.c846
-rw-r--r--vendor/nunicode/src/libnu/gen/_tounaccent.c460
-rw-r--r--vendor/nunicode/src/libnu/gen/_toupper.c917
-rw-r--r--vendor/nunicode/src/libnu/strcoll.c452
-rw-r--r--vendor/nunicode/src/libnu/strings.c89
-rw-r--r--vendor/nunicode/src/libnu/tolower.c58
-rw-r--r--vendor/nunicode/src/libnu/tounaccent.c57
-rw-r--r--vendor/nunicode/src/libnu/toupper.c32
-rw-r--r--vendor/nunicode/src/libnu/utf8.c97
-rw-r--r--vendor/nunicode/version.txt1
315 files changed, 20751 insertions, 7093 deletions
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt.hpp
index ee1bbbca8d..af5bbc3129 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt.hpp
@@ -51,9 +51,6 @@ struct Options : TileOptions {
// max number of points per tile in the tile index
uint32_t indexMaxPoints = 100000;
-
- // whether to tile solid square tiles further
- bool solidChildren = false;
};
const Tile empty_tile{};
@@ -63,12 +60,12 @@ inline uint64_t toID(uint8_t z, uint32_t x, uint32_t y) {
}
inline const Tile geoJSONToTile(const geojson& geojson_,
- uint8_t z,
- uint32_t x,
- uint32_t y,
- const TileOptions& options = TileOptions(),
- bool wrap = false,
- bool clip = false) {
+ uint8_t z,
+ uint32_t x,
+ uint32_t y,
+ const TileOptions& options = TileOptions(),
+ bool wrap = false,
+ bool clip = false) {
const auto features_ = geojson::visit(geojson_, ToFeatureCollection{});
auto z2 = 1u << z;
@@ -83,8 +80,7 @@ inline const Tile geoJSONToTile(const geojson& geojson_,
const auto left = detail::clip<0>(features, (x - p) / z2, (x + 1 + p) / z2, -1, 2);
features = detail::clip<1>(left, (y - p) / z2, (y + 1 + p) / z2, -1, 2);
}
- return detail::InternalTile({ features, z, x, y, options.extent, options.buffer, tolerance })
- .tile;
+ return detail::InternalTile({ features, z, x, y, options.extent, tolerance }).tile;
}
class GeoJSONVT {
@@ -131,10 +127,6 @@ public:
// if we found a parent tile containing the original geometry, we can drill down from it
const auto& parent = it->second;
- // parent tile is a solid clipped square, return it instead since it's identical
- if (parent.is_solid)
- return parent.tile;
-
// drill down parent tile up to the requested one
splitTile(parent.source_features, parent.z, parent.x, parent.y, z, x, y);
@@ -146,11 +138,6 @@ public:
if (it == tiles.end())
throw std::runtime_error("Parent tile not found");
- // drilling stopped because parent was a solid square; return it instead
- if (it->second.is_solid)
- return it->second.tile;
-
- // otherwise it was an empty tile
return empty_tile;
}
@@ -198,8 +185,8 @@ private:
(z == options.maxZoom ? 0 : options.tolerance / (z2 * options.extent));
it = tiles
- .emplace(id, detail::InternalTile{ features, z, x, y, options.extent,
- options.buffer, tolerance })
+ .emplace(id,
+ detail::InternalTile{ features, z, x, y, options.extent, tolerance })
.first;
stats[z] = (stats.count(z) ? stats[z] + 1 : 1);
total++;
@@ -211,10 +198,6 @@ private:
if (features.empty())
return;
- // stop tiling if the tile is solid clipped square
- if (!options.solidChildren && tile.is_solid)
- return;
-
// if it's the first-pass tiling
if (cz == 0u) {
// stop tiling if we reached max zoom, or if the tile is too simple
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/clip.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/clip.hpp
index 212e2979d0..e6f305921f 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/clip.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/clip.hpp
@@ -116,13 +116,13 @@ private:
if (i == len - 2)
slice.push_back(b); // last point
}
- } else if (ak > k2) {
+ } else if (ak >= k2) {
if (bk < k1) { // <--|-----|---
slice.push_back(intersect<I>(a, b, k2));
slice.push_back(intersect<I>(a, b, k1));
slice = newSlice(slices, slice, dist);
- } else if (bk <= k2) { // | <--|---
+ } else if (bk < k2) { // | <--|---
slice.push_back(intersect<I>(a, b, k2));
if (i == len - 2)
slice.push_back(b); // last point
@@ -171,8 +171,8 @@ private:
else if (i == len - 2)
slice.push_back(b); // last point
}
- } else if (ak > k2) {
- if (bk <= k2) { // | <--|---
+ } else if (ak >= k2) {
+ if (bk < k2) { // | <--|---
slice.push_back(intersect<I>(a, b, k2));
if (bk < k1) // <--|-----|---
slice.push_back(intersect<I>(a, b, k1));
@@ -216,10 +216,10 @@ inline vt_features clip(const vt_features& features,
const double minAll,
const double maxAll) {
- if (minAll >= k1 && maxAll <= k2) // trivial accept
+ if (minAll >= k1 && maxAll < k2) // trivial accept
return features;
- if (minAll > k2 || maxAll < k1) // trivial reject
+ if (maxAll < k1 || minAll >= k2) // trivial reject
return {};
vt_features clipped;
@@ -232,10 +232,10 @@ inline vt_features clip(const vt_features& features,
const double min = get<I>(feature.bbox.min);
const double max = get<I>(feature.bbox.max);
- if (min >= k1 && max <= k2) { // trivial accept
+ if (min >= k1 && max < k2) { // trivial accept
clipped.push_back(feature);
- } else if (min > k2 || max < k1) { // trivial reject
+ } else if (max < k1 || min >= k2) { // trivial reject
continue;
} else {
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/convert.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/convert.hpp
index ba28f449b3..88c036f02c 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/convert.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/convert.hpp
@@ -99,8 +99,7 @@ inline vt_features convert(const geometry::feature_collection<double>& features,
for (const auto& feature : features) {
projected.emplace_back(
geometry::geometry<double>::visit(feature.geometry, project{ tolerance }),
- feature.properties,
- feature.id);
+ feature.properties, feature.id);
}
return projected;
}
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/simplify.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/simplify.hpp
index be0165b0f1..784f085e7f 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/simplify.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/simplify.hpp
@@ -37,6 +37,8 @@ inline double getSqSegDist(const vt_point& p, const vt_point& a, const vt_point&
inline void simplify(std::vector<vt_point>& points, size_t first, size_t last, double sqTolerance) {
double maxSqDist = sqTolerance;
size_t index = 0;
+ const int64_t mid = (last - first) >> 1;
+ int64_t minPosToMid = last - first;
for (auto i = first + 1; i < last; i++) {
const double sqDist = getSqSegDist(points[i], points[first], points[last]);
@@ -44,6 +46,16 @@ inline void simplify(std::vector<vt_point>& points, size_t first, size_t last, d
if (sqDist > maxSqDist) {
index = i;
maxSqDist = sqDist;
+
+ } else if (sqDist == maxSqDist) {
+ // a workaround to ensure we choose a pivot close to the middle of the list,
+ // reducing recursion depth, for certain degenerate inputs
+ // https://github.com/mapbox/geojson-vt/issues/104
+ auto posToMid = std::abs(static_cast<int64_t>(i) - mid);
+ if (posToMid < minPosToMid) {
+ index = i;
+ minPosToMid = posToMid;
+ }
}
}
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/tile.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/tile.hpp
index ccb230bb9c..e382346779 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/tile.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/tile.hpp
@@ -17,12 +17,16 @@ namespace detail {
class InternalTile {
public:
+ const uint16_t extent;
const uint8_t z;
const uint32_t x;
const uint32_t y;
+ const double z2;
+ const double tolerance;
+ const double sq_tolerance;
+
vt_features source_features;
- bool is_solid = false;
mapbox::geometry::box<double> bbox = { { 2, 1 }, { -1, 0 } };
Tile tile;
@@ -32,13 +36,12 @@ public:
const uint32_t x_,
const uint32_t y_,
const uint16_t extent_,
- const uint16_t buffer,
const double tolerance_)
- : z(z_),
+ : extent(extent_),
+ z(z_),
x(x_),
y(y_),
z2(std::pow(2, z)),
- extent(extent_),
tolerance(tolerance_),
sq_tolerance(tolerance_ * tolerance_) {
@@ -59,59 +62,33 @@ public:
bbox.max.x = std::max(feature.bbox.max.x, bbox.max.x);
bbox.max.y = std::max(feature.bbox.max.y, bbox.max.y);
}
-
- is_solid = isSolid(buffer);
}
private:
- const double z2;
- const uint16_t extent;
- const double tolerance;
- const double sq_tolerance;
-
- bool isSolid(const uint16_t buffer) {
- if (tile.features.size() != 1)
- return false;
-
- const auto& geom = tile.features.front().geometry;
- if (!geom.is<mapbox::geometry::polygon<int16_t>>())
- return false;
-
- const auto& rings = geom.get<mapbox::geometry::polygon<int16_t>>();
- if (rings.size() > 1)
- return false;
-
- const auto& ring = rings.front();
- if (ring.size() != 5)
- return false;
-
- const int16_t min = -static_cast<int16_t>(buffer);
- const int16_t max = static_cast<int16_t>(extent + buffer);
- for (const auto& p : ring) {
- if ((p.x != min && p.x != max) || (p.y != min && p.y != max))
- return false;
- }
-
- return true;
- }
-
- void addFeature(const vt_point& point, const property_map& props, const optional<identifier>& id) {
+ void
+ addFeature(const vt_point& point, const property_map& props, const optional<identifier>& id) {
tile.features.push_back({ transform(point), props, id });
}
- void addFeature(const vt_line_string& line, const property_map& props, const optional<identifier>& id) {
+ void addFeature(const vt_line_string& line,
+ const property_map& props,
+ const optional<identifier>& id) {
const auto new_line = transform(line);
if (!new_line.empty())
tile.features.push_back({ std::move(new_line), props, id });
}
- void addFeature(const vt_polygon& polygon, const property_map& props, const optional<identifier>& id) {
+ void addFeature(const vt_polygon& polygon,
+ const property_map& props,
+ const optional<identifier>& id) {
const auto new_polygon = transform(polygon);
if (!new_polygon.empty())
tile.features.push_back({ std::move(new_polygon), props, id });
}
- void addFeature(const vt_geometry_collection& collection, const property_map& props, const optional<identifier>& id) {
+ void addFeature(const vt_geometry_collection& collection,
+ const property_map& props,
+ const optional<identifier>& id) {
for (const auto& geom : collection) {
vt_geometry::visit(geom, [&](const auto& g) {
// `this->` is a workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/types.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/types.hpp
index b54357a7b9..b65844f432 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/types.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/types.hpp
@@ -60,13 +60,19 @@ using vt_multi_point = std::vector<vt_point>;
struct vt_line_string : std::vector<vt_point> {
using container_type = std::vector<vt_point>;
- using container_type::container_type;
+ vt_line_string() = default;
+ vt_line_string(std::initializer_list<vt_point> args)
+ : container_type(std::move(args)) {}
+
double dist = 0.0; // line length
};
struct vt_linear_ring : std::vector<vt_point> {
using container_type = std::vector<vt_point>;
- using container_type::container_type;
+ vt_linear_ring() = default;
+ vt_linear_ring(std::initializer_list<vt_point> args)
+ : container_type(std::move(args)) {}
+
double area = 0.0; // polygon ring area
};
diff --git a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/wrap.hpp b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/wrap.hpp
index 495ccc5800..495ccc5800 100644
--- a/deps/geojsonvt/6.3.0/include/mapbox/geojsonvt/wrap.hpp
+++ b/deps/geojsonvt/6.5.1/include/mapbox/geojsonvt/wrap.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry.hpp b/deps/geometry/0.9.3/include/mapbox/geometry.hpp
index e232453179..e232453179 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/box.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/box.hpp
index bf81b703ec..bf81b703ec 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/box.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/box.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/envelope.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/envelope.hpp
index 8603583985..8603583985 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/envelope.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/envelope.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/feature.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/feature.hpp
index 20d2ddf6b8..685c01229f 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/feature.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/feature.hpp
@@ -84,7 +84,12 @@ struct feature_collection : Cont<feature<T>>
using coordinate_type = T;
using feature_type = feature<T>;
using container_type = Cont<feature_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ feature_collection(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ feature_collection(std::initializer_list<feature_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/for_each_point.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/for_each_point.hpp
index 44d6e77bd0..44d6e77bd0 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/for_each_point.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/for_each_point.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/geometry.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/geometry.hpp
index a9d072be7e..3b86117220 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/geometry.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/geometry.hpp
@@ -46,12 +46,12 @@ struct geometry_collection : Cont<geometry<T>>
using coordinate_type = T;
using geometry_type = geometry<T>;
using container_type = Cont<geometry_type>;
+ using size_type = typename container_type::size_type;
- geometry_collection() = default;
- geometry_collection(geometry_collection const&) = default;
- geometry_collection(geometry_collection &&) = default;
- geometry_collection(std::initializer_list<geometry_type> && args)
- : container_type(std::forward<std::initializer_list<geometry_type>>(args)) {};
+ template <class... Args>
+ geometry_collection(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ geometry_collection(std::initializer_list<geometry_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/line_string.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/line_string.hpp
index 6d811ce221..d11d06bd84 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/line_string.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/line_string.hpp
@@ -14,7 +14,12 @@ struct line_string : Cont<point<T> >
using coordinate_type = T;
using point_type = point<T>;
using container_type = Cont<point_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ line_string(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ line_string(std::initializer_list<point_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/multi_line_string.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/multi_line_string.hpp
index 07a7a1d609..7dfefd8ffa 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/multi_line_string.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/multi_line_string.hpp
@@ -14,7 +14,12 @@ struct multi_line_string : Cont<line_string<T>>
using coordinate_type = T;
using line_string_type = line_string<T>;
using container_type = Cont<line_string_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ multi_line_string(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ multi_line_string(std::initializer_list<line_string_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/multi_point.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/multi_point.hpp
index a3c73cff91..d2d7a6768a 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/multi_point.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/multi_point.hpp
@@ -14,7 +14,12 @@ struct multi_point : Cont<point<T>>
using coordinate_type = T;
using point_type = point<T>;
using container_type = Cont<point_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ multi_point(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ multi_point(std::initializer_list<point_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/multi_polygon.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/multi_polygon.hpp
index ad230a04c8..0e3cb321a4 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/multi_polygon.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/multi_polygon.hpp
@@ -14,7 +14,12 @@ struct multi_polygon : Cont<polygon<T>>
using coordinate_type = T;
using polygon_type = polygon<T>;
using container_type = Cont<polygon_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ multi_polygon(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ multi_polygon(std::initializer_list<polygon_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/point.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/point.hpp
index 0cba4996e7..0cba4996e7 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/point.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/point.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/point_arithmetic.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/point_arithmetic.hpp
index 0c4c63278a..0c4c63278a 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/point_arithmetic.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/point_arithmetic.hpp
diff --git a/deps/geometry/0.9.2/include/mapbox/geometry/polygon.hpp b/deps/geometry/0.9.3/include/mapbox/geometry/polygon.hpp
index 99a66aa125..0c7e1161cb 100644
--- a/deps/geometry/0.9.2/include/mapbox/geometry/polygon.hpp
+++ b/deps/geometry/0.9.3/include/mapbox/geometry/polygon.hpp
@@ -15,7 +15,12 @@ struct linear_ring : Cont<point<T>>
using coordinate_type = T;
using point_type = point<T>;
using container_type = Cont<point_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ linear_ring(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ linear_ring(std::initializer_list<point_type> args)
+ : container_type(std::move(args)) {}
};
template <typename T, template <typename...> class Cont = std::vector>
@@ -24,7 +29,12 @@ struct polygon : Cont<linear_ring<T>>
using coordinate_type = T;
using linear_ring_type = linear_ring<T>;
using container_type = Cont<linear_ring_type>;
- using container_type::container_type;
+ using size_type = typename container_type::size_type;
+
+ template <class... Args>
+ polygon(Args&&... args) : container_type(std::forward<Args>(args)...) {}
+ polygon(std::initializer_list<linear_ring_type> args)
+ : container_type(std::move(args)) {}
};
} // namespace geometry
diff --git a/deps/optional/f27e7908/include/experimental/optional b/deps/optional/f27e7908/include/experimental/optional
new file mode 100644
index 0000000000..7b9148f3a7
--- /dev/null
+++ b/deps/optional/f27e7908/include/experimental/optional
@@ -0,0 +1,1052 @@
+// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// The idea and interface is based on Boost.Optional library
+// authored by Fernando Luis Cacciola Carballal
+
+# ifndef ___OPTIONAL_HPP___
+# define ___OPTIONAL_HPP___
+
+# include <utility>
+# include <type_traits>
+# include <initializer_list>
+# include <cassert>
+# include <functional>
+# include <string>
+# include <stdexcept>
+
+# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false
+
+# if defined __GNUC__ // NOTE: GNUC is also defined for Clang
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# endif
+#
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
+# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
+# endif
+#
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# endif
+# endif
+#
+# if defined __clang_major__
+# if (__clang_major__ == 3 && __clang_minor__ >= 5)
+# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# elif (__clang_major__ > 3)
+# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# endif
+# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
+# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+# endif
+# endif
+#
+# if defined _MSC_VER
+# if (_MSC_VER >= 1900)
+# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+# endif
+# endif
+
+# if defined __clang__
+# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# else
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
+# endif
+# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# else
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
+# endif
+
+
+# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
+# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
+# else
+# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
+# define OPTIONAL_CONSTEXPR_INIT_LIST
+# endif
+
+# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L)
+# define OPTIONAL_HAS_MOVE_ACCESSORS 1
+# else
+# define OPTIONAL_HAS_MOVE_ACCESSORS 0
+# endif
+
+# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
+# if (defined __cplusplus) && (__cplusplus == 201103L)
+# define OPTIONAL_MUTABLE_CONSTEXPR
+# else
+# define OPTIONAL_MUTABLE_CONSTEXPR constexpr
+# endif
+
+namespace std{
+
+namespace experimental{
+
+// BEGIN workaround for missing is_trivially_destructible
+# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
+ // leave it: the user doesn't want it
+# else
+ template <typename T>
+ using is_trivially_destructible = std::has_trivial_destructor<T>;
+# endif
+// END workaround for missing is_trivially_destructible
+
+# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___)
+ // leave it; our metafunctions are already defined.
+# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+ // leave it; our metafunctions are already defined.
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
+ // leave it: the user doesn't want it
+# else
+
+
+// workaround for missing traits in GCC and CLANG
+template <class T>
+struct is_nothrow_move_constructible
+{
+ constexpr static bool value = std::is_nothrow_constructible<T, T&&>::value;
+};
+
+
+template <class T, class U>
+struct is_assignable
+{
+ template <class X, class Y>
+ constexpr static bool has_assign(...) { return false; }
+
+ template <class X, class Y, size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true)) >
+ // the comma operator is necessary for the cases where operator= returns void
+ constexpr static bool has_assign(bool) { return true; }
+
+ constexpr static bool value = has_assign<T, U>(true);
+};
+
+
+template <class T>
+struct is_nothrow_move_assignable
+{
+ template <class X, bool has_any_move_assign>
+ struct has_nothrow_move_assign {
+ constexpr static bool value = false;
+ };
+
+ template <class X>
+ struct has_nothrow_move_assign<X, true> {
+ constexpr static bool value = noexcept( std::declval<X&>() = std::declval<X&&>() );
+ };
+
+ constexpr static bool value = has_nothrow_move_assign<T, is_assignable<T&, T&&>::value>::value;
+};
+// end workaround
+
+
+# endif
+
+
+
+// 20.5.4, optional for object types
+template <class T> class optional;
+
+// 20.5.5, optional for lvalue reference types
+template <class T> class optional<T&>;
+
+
+// workaround: std utility functions aren't constexpr yet
+template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type& t) noexcept
+{
+ return static_cast<T&&>(t);
+}
+
+template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type&& t) noexcept
+{
+ static_assert(!std::is_lvalue_reference<T>::value, "!!");
+ return static_cast<T&&>(t);
+}
+
+template <class T> inline constexpr typename std::remove_reference<T>::type&& constexpr_move(T&& t) noexcept
+{
+ return static_cast<typename std::remove_reference<T>::type&&>(t);
+}
+
+
+#if defined NDEBUG
+# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
+#else
+# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
+#endif
+
+
+namespace detail_
+{
+
+// static_addressof: a constexpr version of addressof
+template <typename T>
+struct has_overloaded_addressof
+{
+ template <class X>
+ constexpr static bool has_overload(...) { return false; }
+
+ template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
+ constexpr static bool has_overload(bool) { return true; }
+
+ constexpr static bool value = has_overload<T>(true);
+};
+
+template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
+constexpr T* static_addressof(T& ref)
+{
+ return &ref;
+}
+
+template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
+T* static_addressof(T& ref)
+{
+ return std::addressof(ref);
+}
+
+
+// the call to convert<A>(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
+template <class U>
+constexpr U convert(U v) { return v; }
+
+} // namespace detail
+
+
+constexpr struct trivial_init_t{} trivial_init{};
+
+
+// 20.5.6, In-place construction
+constexpr struct in_place_t{} in_place{};
+
+
+// 20.5.7, Disengaged state indicator
+struct nullopt_t
+{
+ struct init{};
+ constexpr explicit nullopt_t(init){}
+};
+constexpr nullopt_t nullopt{nullopt_t::init()};
+
+
+// 20.5.8, class bad_optional_access
+class bad_optional_access : public logic_error {
+public:
+ explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {}
+ explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {}
+};
+
+
+template <class T>
+union storage_t
+{
+ unsigned char dummy_;
+ T value_;
+
+ constexpr storage_t( trivial_init_t ) noexcept : dummy_() {};
+
+ template <class... Args>
+ constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
+
+ ~storage_t(){}
+};
+
+
+template <class T>
+union constexpr_storage_t
+{
+ unsigned char dummy_;
+ T value_;
+
+ constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {};
+
+ template <class... Args>
+ constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
+
+ ~constexpr_storage_t() = default;
+};
+
+
+template <class T>
+struct optional_base
+{
+ bool init_;
+ storage_t<T> storage_;
+
+ constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {};
+
+ explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
+
+ explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
+
+ template <class... Args> explicit optional_base(in_place_t, Args&&... args)
+ : init_(true), storage_(constexpr_forward<Args>(args)...) {}
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
+ explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
+ : init_(true), storage_(il, std::forward<Args>(args)...) {}
+
+ ~optional_base() { if (init_) storage_.value_.T::~T(); }
+};
+
+
+template <class T>
+struct constexpr_optional_base
+{
+ bool init_;
+ constexpr_storage_t<T> storage_;
+
+ constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {};
+
+ explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {}
+
+ explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
+
+ template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
+ : init_(true), storage_(constexpr_forward<Args>(args)...) {}
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
+ OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
+ : init_(true), storage_(il, std::forward<Args>(args)...) {}
+
+ ~constexpr_optional_base() = default;
+};
+
+template <class T>
+using OptionalBase = typename std::conditional<
+ is_trivially_destructible<T>::value, // if possible
+ constexpr_optional_base<typename std::remove_const<T>::type>, // use base with trivial destructor
+ optional_base<typename std::remove_const<T>::type>
+>::type;
+
+
+
+template <class T>
+class optional : private OptionalBase<T>
+{
+ static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
+ static_assert( !std::is_same<typename std::decay<T>::type, in_place_t>::value, "bad T" );
+
+
+ constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
+ typename std::remove_const<T>::type* dataptr() { return std::addressof(OptionalBase<T>::storage_.value_); }
+ constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+ constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+ OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
+ OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage_.value_; }
+# else
+ T& contained_val() & { return OptionalBase<T>::storage_.value_; }
+ T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
+# endif
+# else
+ constexpr const T& contained_val() const { return OptionalBase<T>::storage_.value_; }
+ T& contained_val() { return OptionalBase<T>::storage_.value_; }
+# endif
+
+ void clear() noexcept {
+ if (initialized()) dataptr()->T::~T();
+ OptionalBase<T>::init_ = false;
+ }
+
+ template <class... Args>
+ void initialize(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
+ {
+ assert(!OptionalBase<T>::init_);
+ ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
+ OptionalBase<T>::init_ = true;
+ }
+
+ template <class U, class... Args>
+ void initialize(std::initializer_list<U> il, Args&&... args) noexcept(noexcept(T(il, std::forward<Args>(args)...)))
+ {
+ assert(!OptionalBase<T>::init_);
+ ::new (static_cast<void*>(dataptr())) T(il, std::forward<Args>(args)...);
+ OptionalBase<T>::init_ = true;
+ }
+
+public:
+ typedef T value_type;
+
+ // 20.5.5.1, constructors
+ constexpr optional() noexcept : OptionalBase<T>() {};
+ constexpr optional(nullopt_t) noexcept : OptionalBase<T>() {};
+
+ optional(const optional& rhs)
+ : OptionalBase<T>()
+ {
+ if (rhs.initialized()) {
+ ::new (static_cast<void*>(dataptr())) T(*rhs);
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ optional(optional&& rhs) noexcept(is_nothrow_move_constructible<T>::value)
+ : OptionalBase<T>()
+ {
+ if (rhs.initialized()) {
+ ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ constexpr optional(const T& v) : OptionalBase<T>(v) {}
+
+ constexpr optional(T&& v) : OptionalBase<T>(constexpr_move(v)) {}
+
+ template <class... Args>
+ explicit constexpr optional(in_place_t, Args&&... args)
+ : OptionalBase<T>(in_place_t{}, constexpr_forward<Args>(args)...) {}
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
+ OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list<U> il, Args&&... args)
+ : OptionalBase<T>(in_place_t{}, il, constexpr_forward<Args>(args)...) {}
+
+ // 20.5.4.2, Destructor
+ ~optional() = default;
+
+ // 20.5.4.3, assignment
+ optional& operator=(nullopt_t) noexcept
+ {
+ clear();
+ return *this;
+ }
+
+ optional& operator=(const optional& rhs)
+ {
+ if (initialized() == true && rhs.initialized() == false) clear();
+ else if (initialized() == false && rhs.initialized() == true) initialize(*rhs);
+ else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
+ return *this;
+ }
+
+ optional& operator=(optional&& rhs)
+ noexcept(is_nothrow_move_assignable<T>::value && is_nothrow_move_constructible<T>::value)
+ {
+ if (initialized() == true && rhs.initialized() == false) clear();
+ else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs));
+ else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs);
+ return *this;
+ }
+
+ template <class U>
+ auto operator=(U&& v)
+ -> typename enable_if
+ <
+ is_same<typename decay<U>::type, T>::value,
+ optional&
+ >::type
+ {
+ if (initialized()) { contained_val() = std::forward<U>(v); }
+ else { initialize(std::forward<U>(v)); }
+ return *this;
+ }
+
+
+ template <class... Args>
+ void emplace(Args&&... args)
+ {
+ clear();
+ initialize(std::forward<Args>(args)...);
+ }
+
+ template <class U, class... Args>
+ void emplace(initializer_list<U> il, Args&&... args)
+ {
+ clear();
+ initialize<U, Args...>(il, std::forward<Args>(args)...);
+ }
+
+ // 20.5.4.4, Swap
+ void swap(optional<T>& rhs) noexcept(is_nothrow_move_constructible<T>::value && noexcept(swap(declval<T&>(), declval<T&>())))
+ {
+ if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); }
+ else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); }
+ else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); }
+ }
+
+ // 20.5.4.5, Observers
+
+ explicit constexpr operator bool() const noexcept { return initialized(); }
+ constexpr bool has_value() const noexcept { return initialized(); }
+
+ constexpr T const* operator ->() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
+ }
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+
+ OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
+ assert (initialized());
+ return dataptr();
+ }
+
+ constexpr T const& operator *() const& {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
+ assert (initialized());
+ return contained_val();
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
+ assert (initialized());
+ return constexpr_move(contained_val());
+ }
+
+ constexpr T const& value() const& {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
+ if (!initialized()) throw bad_optional_access("bad optional access");
+ return std::move(contained_val());
+ }
+
+# else
+
+ T* operator ->() {
+ assert (initialized());
+ return dataptr();
+ }
+
+ constexpr T const& operator *() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
+ }
+
+ T& operator *() {
+ assert (initialized());
+ return contained_val();
+ }
+
+ constexpr T const& value() const {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ T& value() {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+# endif
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+
+ template <class V>
+ constexpr T value_or(V&& v) const&
+ {
+ return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+
+ template <class V>
+ OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
+ {
+ return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# else
+
+ template <class V>
+ T value_or(V&& v) &&
+ {
+ return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# endif
+
+# else
+
+ template <class V>
+ constexpr T value_or(V&& v) const
+ {
+ return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# endif
+
+ // 20.6.3.6, modifiers
+ void reset() noexcept { clear(); }
+};
+
+
+template <class T>
+class optional<T&>
+{
+ static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
+ static_assert( !std::is_same<T, in_place_t>::value, "bad T" );
+ T* ref;
+
+public:
+
+ // 20.5.5.1, construction/destruction
+ constexpr optional() noexcept : ref(nullptr) {}
+
+ constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
+
+ constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
+
+ optional(T&&) = delete;
+
+ constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
+
+ explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
+
+ explicit optional(in_place_t, T&&) = delete;
+
+ ~optional() = default;
+
+ // 20.5.5.2, mutation
+ optional& operator=(nullopt_t) noexcept {
+ ref = nullptr;
+ return *this;
+ }
+
+ // optional& operator=(const optional& rhs) noexcept {
+ // ref = rhs.ref;
+ // return *this;
+ // }
+
+ // optional& operator=(optional&& rhs) noexcept {
+ // ref = rhs.ref;
+ // return *this;
+ // }
+
+ template <typename U>
+ auto operator=(U&& rhs) noexcept
+ -> typename enable_if
+ <
+ is_same<typename decay<U>::type, optional<T&>>::value,
+ optional&
+ >::type
+ {
+ ref = rhs.ref;
+ return *this;
+ }
+
+ template <typename U>
+ auto operator=(U&& rhs) noexcept
+ -> typename enable_if
+ <
+ !is_same<typename decay<U>::type, optional<T&>>::value,
+ optional&
+ >::type
+ = delete;
+
+ void emplace(T& v) noexcept {
+ ref = detail_::static_addressof(v);
+ }
+
+ void emplace(T&&) = delete;
+
+
+ void swap(optional<T&>& rhs) noexcept
+ {
+ std::swap(ref, rhs.ref);
+ }
+
+ // 20.5.5.3, observers
+ constexpr T* operator->() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
+ }
+
+ constexpr T& operator*() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
+ }
+
+ constexpr T& value() const {
+ return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
+ }
+
+ explicit constexpr operator bool() const noexcept {
+ return ref != nullptr;
+ }
+
+ constexpr bool has_value() const noexcept {
+ return ref != nullptr;
+ }
+
+ template <class V>
+ constexpr typename decay<T>::type value_or(V&& v) const
+ {
+ return *this ? **this : detail_::convert<typename decay<T>::type>(constexpr_forward<V>(v));
+ }
+
+ // x.x.x.x, modifiers
+ void reset() noexcept { ref = nullptr; }
+};
+
+
+template <class T>
+class optional<T&&>
+{
+ static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
+};
+
+
+// 20.5.8, Relational operators
+template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y)
+{
+ return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y)
+{
+ return !(x == y);
+}
+
+template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y)
+{
+ return (!y) ? false : (!x) ? true : *x < *y;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, const optional<T>& y)
+{
+ return (y < x);
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, const optional<T>& y)
+{
+ return !(y < x);
+}
+
+template <class T> constexpr bool operator>=(const optional<T>& x, const optional<T>& y)
+{
+ return !(x < y);
+}
+
+
+// 20.5.9, Comparison with nullopt
+template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept
+{
+ return false;
+}
+
+template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept
+{
+ return true;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept
+{
+ return false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept
+{
+ return true;
+}
+
+template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept
+{
+ return (!x);
+}
+
+
+
+// 20.5.10, Comparison with T
+template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+
+// Comparison of optional<T&> with T
+template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+// Comparison of optional<T const&> with T
+template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+
+// 20.5.12, Specialized algorithms
+template <class T>
+void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)))
+{
+ x.swap(y);
+}
+
+
+template <class T>
+constexpr optional<typename decay<T>::type> make_optional(T&& v)
+{
+ return optional<typename decay<T>::type>(constexpr_forward<T>(v));
+}
+
+template <class X>
+constexpr optional<X&> make_optional(reference_wrapper<X> v)
+{
+ return optional<X&>(v.get());
+}
+
+
+} // namespace experimental
+} // namespace std
+
+namespace std
+{
+ template <typename T>
+ struct hash<std::experimental::optional<T>>
+ {
+ typedef typename hash<T>::result_type result_type;
+ typedef std::experimental::optional<T> argument_type;
+
+ constexpr result_type operator()(argument_type const& arg) const {
+ return arg ? std::hash<T>{}(*arg) : result_type{};
+ }
+ };
+
+ template <typename T>
+ struct hash<std::experimental::optional<T&>>
+ {
+ typedef typename hash<T>::result_type result_type;
+ typedef std::experimental::optional<T&> argument_type;
+
+ constexpr result_type operator()(argument_type const& arg) const {
+ return arg ? std::hash<T>{}(*arg) : result_type{};
+ }
+ };
+}
+
+# undef TR2_OPTIONAL_REQUIRES
+# undef TR2_OPTIONAL_ASSERTED_EXPRESSION
+
+# endif //___OPTIONAL_HPP___
diff --git a/deps/vector-tile/1.0.1/include/mapbox/vector_tile.hpp b/deps/vector-tile/1.0.2/include/mapbox/vector_tile.hpp
index 2308462c68..5ddae485f0 100644
--- a/deps/vector-tile/1.0.1/include/mapbox/vector_tile.hpp
+++ b/deps/vector-tile/1.0.2/include/mapbox/vector_tile.hpp
@@ -23,13 +23,15 @@ using point_type = mapbox::geometry::point<std::int16_t>;
class points_array_type : public std::vector<point_type> {
public:
using coordinate_type = point_type::coordinate_type;
- using std::vector<point_type>::vector;
+ template <class... Args>
+ points_array_type(Args&&... args) : std::vector<point_type>(std::forward<Args>(args)...) {}
};
class points_arrays_type : public std::vector<points_array_type> {
public:
using coordinate_type = points_array_type::coordinate_type;
- using std::vector<points_array_type>::vector;
+ template <class... Args>
+ points_arrays_type(Args&&... args) : std::vector<points_array_type>(std::forward<Args>(args)...) {}
};
class layer;
@@ -137,7 +139,7 @@ inline feature::feature(protozero::data_view const& feature_view, layer const& l
while (feature_pbf.next()) {
switch (feature_pbf.tag()) {
case FeatureType::ID:
- id = { feature_pbf.get_uint64() };
+ id = optional<mapbox::geometry::identifier>{ feature_pbf.get_uint64() };
break;
case FeatureType::TAGS:
tags_iter = feature_pbf.get_packed_uint32();
diff --git a/deps/vector-tile/1.0.1/include/mapbox/vector_tile/vector_tile_config.hpp b/deps/vector-tile/1.0.2/include/mapbox/vector_tile/vector_tile_config.hpp
index acf1185673..acf1185673 100644
--- a/deps/vector-tile/1.0.1/include/mapbox/vector_tile/vector_tile_config.hpp
+++ b/deps/vector-tile/1.0.2/include/mapbox/vector_tile/vector_tile_config.hpp
diff --git a/deps/vector-tile/1.0.1/include/mapbox/vector_tile/version.hpp b/deps/vector-tile/1.0.2/include/mapbox/vector_tile/version.hpp
index 13b8755d3c..cc1974d63c 100644
--- a/deps/vector-tile/1.0.1/include/mapbox/vector_tile/version.hpp
+++ b/deps/vector-tile/1.0.2/include/mapbox/vector_tile/version.hpp
@@ -7,10 +7,10 @@
#define VECTOR_TILE_VERSION_MINOR 0
/// The patch number
-#define VECTOR_TILE_VERSION_PATCH 1
+#define VECTOR_TILE_VERSION_PATCH 2
/// The complete version number
#define VECTOR_TILE_VERSION_CODE (VECTOR_TILE_VERSION_MAJOR * 10000 + VECTOR_TILE_VERSION_MINOR * 100 + VECTOR_TILE_VERSION_PATCH)
/// Version number as string
-#define VECTOR_TILE_VERSION_STRING "1.0.1"
+#define VECTOR_TILE_VERSION_STRING "1.0.2"
diff --git a/include/mbgl/actor/actor.hpp b/include/mbgl/actor/actor.hpp
index a0df19208e..0052fad242 100644
--- a/include/mbgl/actor/actor.hpp
+++ b/include/mbgl/actor/actor.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/actor/aspiring_actor.hpp>
+#include <mbgl/actor/established_actor.hpp>
#include <mbgl/actor/mailbox.hpp>
#include <mbgl/actor/message.hpp>
#include <mbgl/actor/actor_ref.hpp>
@@ -8,6 +10,7 @@
#include <memory>
#include <future>
#include <type_traits>
+#include <cassert>
namespace mbgl {
@@ -34,65 +37,33 @@ namespace mbgl {
the lifetime of the owning Actor, and sending a message to a `Ref` whose `Actor` has died is
a no-op. (In the future, a dead-letters queue or log may be implemented.)
- Construction and destruction of an actor is currently synchronous: the corresponding `O`
+ Construction and destruction of an Actor is synchronous: the corresponding `O`
object is constructed synchronously by the `Actor` constructor, and destructed synchronously
by the `~Actor` destructor, after ensuring that the `O` is not currently receiving an
- asynchronous message. (Construction and destruction may change to be asynchronous in the
- future.) The constructor of `O` is passed an `ActorRef<O>` referring to itself (which it
- can use to self-send messages), followed by the forwarded arguments passed to `Actor<O>`.
+ asynchronous message. The constructor of `O` is passed an `ActorRef<O>` referring to itself
+ (which it can use to self-send messages), followed by the forwarded arguments passed to
+ `Actor<O>`. Asynchronous object construction can be accomplished by directly using the
+ lower-level types, `AspiringActor<O>` and `EstablishedActor<O>`.
Please don't send messages that contain shared pointers or references. That subverts the
purpose of the actor model: prohibiting direct concurrent access to shared state.
*/
-
template <class Object>
-class Actor : public util::noncopyable {
+class Actor {
public:
+ template <class... Args>
+ Actor(Scheduler& scheduler, Args&&... args)
+ : target(scheduler, parent, std::forward<Args>(args)...) {}
- // Enabled for Objects with a constructor taking ActorRef<Object> as the first parameter
- template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
- Actor(Scheduler& scheduler, Args&&... args_)
- : mailbox(std::make_shared<Mailbox>(scheduler)),
- object(self(), std::forward<Args>(args_)...) {
- }
-
- // Enabled for plain Objects
- template<typename U = Object, class... Args, typename std::enable_if<!std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
- Actor(Scheduler& scheduler, Args&& ... args_)
- : mailbox(std::make_shared<Mailbox>(scheduler)), object(std::forward<Args>(args_)...) {
- }
-
- ~Actor() {
- mailbox->close();
- }
-
- template <typename Fn, class... Args>
- void invoke(Fn fn, Args&&... args) {
- mailbox->push(actor::makeMessage(object, fn, std::forward<Args>(args)...));
- }
-
- template <typename Fn, class... Args>
- auto ask(Fn fn, Args&&... args) {
- // Result type is deduced from the function's return type
- using ResultType = typename std::result_of<decltype(fn)(Object, Args...)>::type;
-
- std::promise<ResultType> promise;
- auto future = promise.get_future();
- mailbox->push(actor::makeMessage(std::move(promise), object, fn, std::forward<Args>(args)...));
- return future;
- }
+ Actor(const Actor&) = delete;
ActorRef<std::decay_t<Object>> self() {
- return ActorRef<std::decay_t<Object>>(object, mailbox);
- }
-
- operator ActorRef<std::decay_t<Object>>() {
- return self();
+ return parent.self();
}
private:
- std::shared_ptr<Mailbox> mailbox;
- Object object;
+ AspiringActor<Object> parent;
+ EstablishedActor<Object> target;
};
} // namespace mbgl
diff --git a/include/mbgl/actor/aspiring_actor.hpp b/include/mbgl/actor/aspiring_actor.hpp
new file mode 100644
index 0000000000..6c410cdfca
--- /dev/null
+++ b/include/mbgl/actor/aspiring_actor.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <mbgl/actor/mailbox.hpp>
+#include <mbgl/actor/message.hpp>
+#include <mbgl/actor/actor_ref.hpp>
+
+#include <memory>
+#include <future>
+#include <type_traits>
+#include <cassert>
+
+namespace mbgl {
+
+template <class Object>
+class EstablishedActor;
+
+template <class Object>
+class Actor;
+
+/*
+ An `AspiringActor<O>` is one half of the pair of types that comprise an actor (see `Actor<O>`),
+ the other half being `EstablishedActor<O>`. It is responsible for:
+ - ownership of the actor's `Mailbox`
+ - allocating the memory for (but *not* constructing) the target object `O`
+
+ Using these two pieces--the mailbox and a stable address for `O`--an `AspiringActor<O>` can
+ accept messages for the target object, or provide `ActorRef<O>`s that do so, before the object
+ has actually been constructed by the corresponding `EstablishedActor<O>`. (Such messages are
+ queued in the mailbox until after the object is constructed.)
+
+ This allows for an `AspiringActor<O>` to be created and safely used by a thread other than the
+ one on which the target object will (eventually) live.
+*/
+template <class Object>
+class AspiringActor {
+public:
+ AspiringActor() : mailbox(std::make_shared<Mailbox>()) {
+ // mailbox starts closed because the `Object` hasn't yet been constructed
+ assert(!mailbox->isOpen());
+ }
+
+ AspiringActor(const AspiringActor&) = delete;
+
+ ActorRef<std::decay_t<Object>> self() {
+ return ActorRef<std::decay_t<Object>>(object(), mailbox);
+ }
+
+private:
+ std::shared_ptr<Mailbox> mailbox;
+ std::aligned_storage_t<sizeof(Object)> objectStorage;
+
+ Object& object() {
+ return *reinterpret_cast<Object *>(&objectStorage);
+ }
+
+ friend class EstablishedActor<Object>;
+ friend class Actor<Object>;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/actor/established_actor.hpp b/include/mbgl/actor/established_actor.hpp
new file mode 100644
index 0000000000..da0d8ac705
--- /dev/null
+++ b/include/mbgl/actor/established_actor.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <mbgl/actor/aspiring_actor.hpp>
+#include <mbgl/actor/mailbox.hpp>
+#include <mbgl/actor/message.hpp>
+#include <mbgl/actor/actor_ref.hpp>
+
+#include <memory>
+#include <future>
+#include <type_traits>
+#include <cassert>
+
+namespace mbgl {
+
+/*
+ An `EstablishedActor<O>` is one half of the pair of types that comprise an actor (see `Actor<O>`),
+ the other half being `AspiringActor<O>`. It is responsible for managing the lifetime of the
+ target object `O` and the open/closed state of the parent's `mailbox`.
+
+ The `O` object's lifetime is contained by that of its owning `EstablishedActor<O>`: the
+ `EstablishedActor` constructor executes the `O` constructor via "placement new", constructing
+ it at the address provided by the parent `AspiringActor`, and the `~EstablishedActor` destructor
+ similarly executes the `~O` destructor (after closing the mailbox). `EstablishedActor` should
+ therefore live entirely on the thread intended to own `O`.
+*/
+
+template <class Object>
+class EstablishedActor {
+public:
+ // Construct the Object from a parameter pack `args` (i.e. `Object(args...)`)
+ template <typename U = Object, class... Args, typename std::enable_if<
+ std::is_constructible<U, Args...>::value ||
+ std::is_constructible<U, ActorRef<U>, Args...>::value
+ >::type * = nullptr>
+ EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, Args&& ... args)
+ : parent(parent_) {
+ emplaceObject(std::forward<Args>(args)...);
+ parent.mailbox->open(scheduler);
+ }
+
+ // Construct the `Object` from a tuple containing the constructor arguments (i.e.
+ // `Object(std::get<0>(args), std::get<1>(args), ...)`)
+ template <class ArgsTuple, std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value>
+ EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args)
+ : parent(parent_) {
+ emplaceObject(std::forward<ArgsTuple>(args), std::make_index_sequence<ArgCount>{});
+ parent.mailbox->open(scheduler);
+ }
+
+ EstablishedActor(const EstablishedActor&) = delete;
+
+ ~EstablishedActor() {
+ parent.mailbox->close();
+ parent.object().~Object();
+ }
+
+private:
+ // Enabled for Objects with a constructor taking ActorRef<Object> as the first parameter
+ template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
+ void emplaceObject(Args&&... args_) {
+ new (&parent.objectStorage) Object(parent.self(), std::forward<Args>(args_)...);
+ }
+
+ // Enabled for plain Objects
+ template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, Args...>::value>::type * = nullptr>
+ void emplaceObject(Args&&... args_) {
+ new (&parent.objectStorage) Object(std::forward<Args>(args_)...);
+ }
+
+ // Used to expand a tuple holding the constructor arguments
+ template <class ArgsTuple, std::size_t... I>
+ void emplaceObject(ArgsTuple&& args, std::index_sequence<I...>) {
+ emplaceObject(std::move(std::get<I>(std::forward<ArgsTuple>(args)))...);
+ (void) args; // mark args as used: if it's empty tuple, it's not actually used above.
+ }
+
+ AspiringActor<Object>& parent;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/actor/mailbox.hpp b/include/mbgl/actor/mailbox.hpp
index 8ecf91701a..23c579917a 100644
--- a/include/mbgl/actor/mailbox.hpp
+++ b/include/mbgl/actor/mailbox.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/optional.hpp>
+
#include <memory>
#include <mutex>
#include <queue>
@@ -11,17 +13,30 @@ class Message;
class Mailbox : public std::enable_shared_from_this<Mailbox> {
public:
+
+ // Create a "holding" mailbox, messages to which will remain queued,
+ // unconsumed, until the mailbox is associated with a Scheduler using
+ // start(). This allows a Mailbox object to be created on one thread and
+ // later transferred to a different target thread that may not yet exist.
+ Mailbox();
+
Mailbox(Scheduler&);
- void push(std::unique_ptr<Message>);
-
+ // Attach the given scheduler to this mailbox and begin processing messages
+ // sent to it. The mailbox must be a "holding" mailbox, as created by the
+ // default constructor Mailbox().
+ void open(Scheduler& scheduler_);
void close();
+
+ bool isOpen() const;
+
+ void push(std::unique_ptr<Message>);
void receive();
static void maybeReceive(std::weak_ptr<Mailbox>);
private:
- Scheduler& scheduler;
+ optional<Scheduler*> scheduler;
std::recursive_mutex receivingMutex;
std::mutex pushingMutex;
diff --git a/include/mbgl/actor/scheduler.hpp b/include/mbgl/actor/scheduler.hpp
index d8a26ebeab..75ead29f0a 100644
--- a/include/mbgl/actor/scheduler.hpp
+++ b/include/mbgl/actor/scheduler.hpp
@@ -31,6 +31,11 @@ class Mailbox;
class Scheduler {
public:
virtual ~Scheduler() = default;
+
+ // Used by a Mailbox when it has a message in its queue to request that it
+ // be scheduled. Specifically, the scheduler is expected to asynchronously
+ // call `receive() on the given mailbox, provided it still exists at that
+ // time.
virtual void schedule(std::weak_ptr<Mailbox>) = 0;
// Set/Get the current Scheduler for this thread
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 5ba23a76dd..3aee932070 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -67,9 +67,9 @@ public:
void jumpTo(const CameraOptions&);
void easeTo(const CameraOptions&, const AnimationOptions&);
void flyTo(const CameraOptions&, const AnimationOptions&);
- CameraOptions cameraForLatLngBounds(const LatLngBounds&, const EdgeInsets&, optional<double> bearing = {}) const;
- CameraOptions cameraForLatLngs(const std::vector<LatLng>&, const EdgeInsets&, optional<double> bearing = {}) const;
- CameraOptions cameraForGeometry(const Geometry<double>&, const EdgeInsets&, optional<double> bearing = {}) const;
+ CameraOptions cameraForLatLngBounds(const LatLngBounds&, const EdgeInsets&, optional<double> bearing = {}, optional<double> pitch = {}) const;
+ CameraOptions cameraForLatLngs(const std::vector<LatLng>&, const EdgeInsets&, optional<double> bearing = {}, optional<double> pitch = {}) const;
+ CameraOptions cameraForGeometry(const Geometry<double>&, const EdgeInsets&, optional<double> bearing = {}, optional<double> pitch = {}) const;
LatLngBounds latLngBoundsForCamera(const CameraOptions&) const;
// Position
diff --git a/include/mbgl/math/log2.hpp b/include/mbgl/math/log2.hpp
index 53d5e45545..6a1ba23ed9 100644
--- a/include/mbgl/math/log2.hpp
+++ b/include/mbgl/math/log2.hpp
@@ -2,7 +2,6 @@
#include <cmath>
#include <cstdint>
-#include <type_traits>
namespace mbgl {
namespace util {
@@ -11,17 +10,5 @@ namespace util {
// (== number of bits required to store x)
uint32_t ceil_log2(uint64_t x);
-template <typename T>
-typename std::enable_if_t<std::is_floating_point<T>::value, T> log2(T x)
-{
-// log2() is producing wrong results on ARMv5 binaries
-// running on ARMv7+ CPUs.
-#if defined(__ANDROID__)
- return ::log(x) / M_LN2;
-#else
- return ::log2(x);
-#endif
-}
-
} // namespace util
} // namespace mbgl
diff --git a/include/mbgl/style/heatmap_color_property_value.hpp b/include/mbgl/style/color_ramp_property_value.hpp
index 130639c6e2..bc5639c899 100644
--- a/include/mbgl/style/heatmap_color_property_value.hpp
+++ b/include/mbgl/style/color_ramp_property_value.hpp
@@ -2,7 +2,7 @@
#include <mbgl/util/variant.hpp>
#include <mbgl/style/undefined.hpp>
-#include <mbgl/style/function/camera_function.hpp>
+#include <mbgl/style/expression/expression.hpp>
namespace mbgl {
namespace style {
@@ -11,21 +11,21 @@ namespace style {
* Special-case implementation of (a subset of) the PropertyValue<T> interface
* used for building the HeatmapColor paint property traits class.
*/
-class HeatmapColorPropertyValue {
+class ColorRampPropertyValue {
private:
std::shared_ptr<expression::Expression> value;
- friend bool operator==(const HeatmapColorPropertyValue& lhs, const HeatmapColorPropertyValue& rhs) {
+ friend bool operator==(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) {
return (lhs.isUndefined() && rhs.isUndefined()) || (lhs.value && rhs.value && *(lhs.value) == *(rhs.value));
}
- friend bool operator!=(const HeatmapColorPropertyValue& lhs, const HeatmapColorPropertyValue& rhs) {
+ friend bool operator!=(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) {
return !(lhs == rhs);
}
public:
- HeatmapColorPropertyValue() : value(nullptr) {}
- HeatmapColorPropertyValue(std::shared_ptr<expression::Expression> value_) : value(std::move(value_)) {}
+ ColorRampPropertyValue() : value(nullptr) {}
+ ColorRampPropertyValue(std::shared_ptr<expression::Expression> value_) : value(std::move(value_)) {}
bool isUndefined() const { return value.get() == nullptr; }
@@ -33,14 +33,14 @@ public:
template <typename Evaluator>
Color evaluate(const Evaluator&, TimePoint = {}) const { return {}; }
- Color evaluate(double heatmapDensity) const {
- const auto result = value->evaluate(expression::EvaluationContext({}, nullptr, {heatmapDensity}));
+ Color evaluate(double rampEvaluationParameter) const {
+ const auto result = value->evaluate(expression::EvaluationContext({}, nullptr, {rampEvaluationParameter}));
return *expression::fromExpressionValue<Color>(*result);
}
- bool isDataDriven() const { return false; }
- bool hasDataDrivenPropertyDifference(const HeatmapColorPropertyValue&) const { return false; }
-
+ bool isDataDriven() const { return false; }
+ bool hasDataDrivenPropertyDifference(const ColorRampPropertyValue&) const { return false; }
+
const expression::Expression& getExpression() const { return *value; }
};
diff --git a/include/mbgl/style/conversion/heatmap_color_property_value.hpp b/include/mbgl/style/conversion/color_ramp_property_value.hpp
index a4710792d2..290ee6a56c 100644
--- a/include/mbgl/style/conversion/heatmap_color_property_value.hpp
+++ b/include/mbgl/style/conversion/color_ramp_property_value.hpp
@@ -1,13 +1,11 @@
#pragma once
-#include <mbgl/style/heatmap_color_property_value.hpp>
+#include <mbgl/style/color_ramp_property_value.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
-#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/is_expression.hpp>
-#include <mbgl/style/expression/find_zoom_curve.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
namespace mbgl {
@@ -15,11 +13,11 @@ namespace style {
namespace conversion {
template <>
-struct Converter<HeatmapColorPropertyValue> {
- optional<HeatmapColorPropertyValue> operator()(const Convertible& value, Error& error) const {
+struct Converter<ColorRampPropertyValue> {
+ optional<ColorRampPropertyValue> operator()(const Convertible& value, Error& error, bool /* convertTokens */ = false) const {
using namespace mbgl::style::expression;
if (isUndefined(value)) {
- return HeatmapColorPropertyValue();
+ return ColorRampPropertyValue();
} else if (isExpression(value)) {
ParsingContext ctx(type::Color);
ParseResult expression = ctx.parseLayerPropertyExpression(value);
@@ -36,9 +34,9 @@ struct Converter<HeatmapColorPropertyValue> {
error = { "zoom expressions not supported" };
return {};
}
- return {HeatmapColorPropertyValue(std::move(*expression))};
+ return {ColorRampPropertyValue(std::move(*expression))};
} else {
- error = { "heatmap-color must be an expression" };
+ error = { "color ramp must be an expression" };
return {};
}
}
diff --git a/include/mbgl/style/conversion/data_driven_property_value.hpp b/include/mbgl/style/conversion/data_driven_property_value.hpp
index 07ed201c99..59d197b216 100644
--- a/include/mbgl/style/conversion/data_driven_property_value.hpp
+++ b/include/mbgl/style/conversion/data_driven_property_value.hpp
@@ -6,76 +6,71 @@
#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/expression/is_expression.hpp>
#include <mbgl/style/expression/is_constant.hpp>
-#include <mbgl/style/expression/find_zoom_curve.hpp>
#include <mbgl/style/expression/literal.hpp>
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
-#include <unordered_set>
-
-
namespace mbgl {
namespace style {
namespace conversion {
template <class T>
struct Converter<DataDrivenPropertyValue<T>> {
-
- optional<DataDrivenPropertyValue<T>> operator()(const Convertible& value, Error& error) const {
+ optional<DataDrivenPropertyValue<T>> operator()(const Convertible& value, Error& error, bool convertTokens) const {
using namespace mbgl::style::expression;
-
+
if (isUndefined(value)) {
return DataDrivenPropertyValue<T>();
- } else if (isExpression(value)) {
+ }
+
+ optional<PropertyExpression<T>> expression;
+
+ if (isExpression(value)) {
ParsingContext ctx(valueTypeToExpressionType<T>());
- ParseResult expression = ctx.parseLayerPropertyExpression(value);
- if (!expression) {
+ ParseResult parsed = ctx.parseLayerPropertyExpression(value);
+ if (!parsed) {
error = { ctx.getCombinedErrors() };
return {};
}
-
- bool featureConstant = isFeatureConstant(**expression);
- bool zoomConstant = isZoomConstant(**expression);
-
- if (featureConstant && !zoomConstant) {
- return DataDrivenPropertyValue<T>(CameraFunction<T>(std::move(*expression)));
- } else if (!featureConstant && zoomConstant) {
- return DataDrivenPropertyValue<T>(SourceFunction<T>(std::move(*expression)));
- } else if (!featureConstant && !zoomConstant) {
- return DataDrivenPropertyValue<T>(CompositeFunction<T>(std::move(*expression)));
- } else {
- auto literal = dynamic_cast<Literal*>(expression->get());
- assert(literal);
- optional<T> constant = fromExpressionValue<T>(literal->getValue());
- if (!constant) {
- return {};
- }
- return DataDrivenPropertyValue<T>(*constant);
- }
- } else if (!isObject(value)) {
+ expression = PropertyExpression<T>(std::move(*parsed));
+ } else if (isObject(value)) {
+ expression = convertFunctionToExpression<T>(value, error, convertTokens);
+ } else {
optional<T> constant = convert<T>(value, error);
if (!constant) {
return {};
}
- return DataDrivenPropertyValue<T>(*constant);
- } else if (!objectMember(value, "property")) {
- optional<CameraFunction<T>> function = convert<CameraFunction<T>>(value, error);
- if (!function) {
+ return convertTokens ? maybeConvertTokens(*constant) : DataDrivenPropertyValue<T>(*constant);
+ }
+
+ if (!expression) {
+ return {};
+ } else if (!(*expression).isFeatureConstant() || !(*expression).isZoomConstant()) {
+ return { std::move(*expression) };
+ } else if ((*expression).getExpression().getKind() == Kind::Literal) {
+ optional<T> constant = fromExpressionValue<T>(
+ static_cast<const Literal&>((*expression).getExpression()).getValue());
+ if (!constant) {
return {};
}
- return DataDrivenPropertyValue<T>(*function);
+ return DataDrivenPropertyValue<T>(*constant);
} else {
- optional<CompositeFunction<T>> composite = convert<CompositeFunction<T>>(value, error);
- if (composite) {
- return DataDrivenPropertyValue<T>(*composite);
- }
- optional<SourceFunction<T>> source = convert<SourceFunction<T>>(value, error);
- if (!source) {
- return {};
- }
- return DataDrivenPropertyValue<T>(*source);
+ assert(false);
+ error = { "expected a literal expression" };
+ return {};
}
}
+
+ template <class S>
+ DataDrivenPropertyValue<T> maybeConvertTokens(const S& t) const {
+ return DataDrivenPropertyValue<T>(t);
+ };
+
+ DataDrivenPropertyValue<T> maybeConvertTokens(const std::string& t) const {
+ return hasTokens(t)
+ ? DataDrivenPropertyValue<T>(PropertyExpression<T>(convertTokenStringToExpression(t)))
+ : DataDrivenPropertyValue<T>(t);
+ }
};
} // namespace conversion
diff --git a/include/mbgl/style/conversion/function.hpp b/include/mbgl/style/conversion/function.hpp
index e230884944..8799e9faa4 100644
--- a/include/mbgl/style/conversion/function.hpp
+++ b/include/mbgl/style/conversion/function.hpp
@@ -1,392 +1,40 @@
#pragma once
-#include <mbgl/style/function/camera_function.hpp>
-#include <mbgl/style/function/source_function.hpp>
-#include <mbgl/style/function/composite_function.hpp>
+#include <mbgl/style/property_expression.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
-#include <mbgl/util/ignore.hpp>
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/expression/value.hpp>
namespace mbgl {
namespace style {
namespace conversion {
-template <class D, class R>
-optional<std::map<D, R>> convertStops(const Convertible& value, Error& error) {
- auto stopsValue = objectMember(value, "stops");
- if (!stopsValue) {
- error = { "function value must specify stops" };
- return {};
- }
-
- if (!isArray(*stopsValue)) {
- error = { "function stops must be an array" };
- return {};
- }
-
- if (arrayLength(*stopsValue) == 0) {
- error = { "function must have at least one stop" };
- return {};
- }
-
- std::map<D, R> stops;
- for (std::size_t i = 0; i < arrayLength(*stopsValue); ++i) {
- const auto& stopValue = arrayMember(*stopsValue, i);
-
- if (!isArray(stopValue)) {
- error = { "function stop must be an array" };
- return {};
- }
-
- if (arrayLength(stopValue) != 2) {
- error = { "function stop must have two elements" };
- return {};
- }
-
- optional<D> d = convert<D>(arrayMember(stopValue, 0), error);
- if (!d) {
- return {};
- }
-
- optional<R> r = convert<R>(arrayMember(stopValue, 1), error);
- if (!r) {
- return {};
- }
+bool hasTokens(const std::string&);
+std::unique_ptr<expression::Expression> convertTokenStringToExpression(const std::string&);
- stops.emplace(*d, *r);
- }
-
- return stops;
-}
+optional<std::unique_ptr<expression::Expression>> convertFunctionToExpression(expression::type::Type, const Convertible&, Error&, bool convertTokens);
template <class T>
-struct Converter<ExponentialStops<T>> {
- static constexpr const char * type = "exponential";
-
- optional<ExponentialStops<T>> operator()(const Convertible& value, Error& error) const {
- auto stops = convertStops<float, T>(value, error);
- if (!stops) {
- return {};
- }
-
- auto baseValue = objectMember(value, "base");
- if (!baseValue) {
- return ExponentialStops<T>(*stops);
- }
-
- optional<float> base = toNumber(*baseValue);
- if (!base) {
- error = { "function base must be a number"};
- return {};
- }
-
- return ExponentialStops<T>(*stops, *base);
- }
-};
-
-template <class T>
-struct Converter<IntervalStops<T>> {
- static constexpr const char * type = "interval";
-
- optional<IntervalStops<T>> operator()(const Convertible& value, Error& error) const {
- auto stops = convertStops<float, T>(value, error);
- if (!stops) {
- return {};
- }
- return IntervalStops<T>(*stops);
- }
-};
-
-template <>
-struct Converter<CategoricalValue> {
- optional<CategoricalValue> operator()(const Convertible& value, Error& error) const {
- auto b = toBool(value);
- if (b) {
- return { *b };
- }
-
- auto n = toNumber(value);
- if (n) {
- return { int64_t(*n) };
- }
-
- auto s = toString(value);
- if (s) {
- return { *s };
- }
-
- error = { "stop domain value must be a number, string, or boolean" };
+optional<PropertyExpression<T>> convertFunctionToExpression(const Convertible& value, Error& error, bool convertTokens) {
+ auto expression = convertFunctionToExpression(expression::valueTypeToExpressionType<T>(), value, error, convertTokens);
+ if (!expression) {
return {};
}
-};
-
-template <class T>
-struct Converter<CategoricalStops<T>> {
- static constexpr const char * type = "categorical";
-
- optional<CategoricalStops<T>> operator()(const Convertible& value, Error& error) const {
- auto stops = convertStops<CategoricalValue, T>(value, error);
- if (!stops) {
- return {};
- }
- return CategoricalStops<T>(
- std::map<CategoricalValue, T>((*stops).begin(), (*stops).end()));
- }
-};
-
-template <class T>
-struct Converter<IdentityStops<T>> {
- static constexpr const char * type = "identity";
-
- optional<IdentityStops<T>> operator()(const Convertible&, Error&) const {
- return IdentityStops<T>();
- }
-};
-
-template <class, class>
-struct StopsConverter;
-
-template <class T, class... Ts>
-struct StopsConverter<T, variant<Ts...>> {
-public:
- optional<variant<Ts...>> operator()(const Convertible& value, Error& error) const {
- std::string type = util::Interpolatable<T>::value ? "exponential" : "interval";
-
- auto typeValue = objectMember(value, "type");
- if (typeValue && toString(*typeValue)) {
- type = *toString(*typeValue);
- }
-
- bool matched = false;
- optional<variant<Ts...>> result;
-
- // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
- auto tryConvert = [&] (auto* tp) {
- using Stops = std::decay_t<decltype(*tp)>;
- if (type == Converter<Stops>::type) {
- matched = true;
- optional<Stops> stops = convert<Stops>(value, error);
- if (stops) {
- result = variant<Ts...>(*stops);
- }
- }
- };
- util::ignore({
- (tryConvert((Ts*)nullptr), 0)...
- });
+ optional<T> defaultValue;
- if (!matched) {
- error = { "unsupported function type" };
- return {};
- }
-
- return result;
- }
-};
-
-template <class T>
-struct Converter<CameraFunction<T>> {
- optional<CameraFunction<T>> operator()(const Convertible& value, Error& error) const {
- if (!isObject(value)) {
- error = { "function must be an object" };
- return {};
- }
-
- auto stops = StopsConverter<T, typename CameraFunction<T>::Stops>()(value, error);
- if (!stops) {
- return {};
- }
-
- return CameraFunction<T>(*stops);
- }
-};
-
-template <class T>
-optional<optional<T>> convertDefaultValue(const Convertible& value, Error& error) {
auto defaultValueValue = objectMember(value, "default");
- if (!defaultValueValue) {
- return optional<T>();
- }
-
- auto defaultValue = convert<T>(*defaultValueValue, error);
- if (!defaultValue) {
- error = { R"(wrong type for "default": )" + error.message };
- return {};
- }
-
- return { *defaultValue };
-}
-
-template <class T>
-struct Converter<SourceFunction<T>> {
- optional<SourceFunction<T>> operator()(const Convertible& value, Error& error) const {
- if (!isObject(value)) {
- error = { "function must be an object" };
- return {};
- }
-
- auto propertyValue = objectMember(value, "property");
- if (!propertyValue) {
- error = { "function must specify property" };
- return {};
- }
-
- auto propertyString = toString(*propertyValue);
- if (!propertyString) {
- error = { "function property must be a string" };
- return {};
- }
-
- auto stops = StopsConverter<T, typename SourceFunction<T>::Stops>()(value, error);
- if (!stops) {
- return {};
- }
-
- auto defaultValue = convertDefaultValue<T>(value, error);
+ if (defaultValueValue) {
+ defaultValue = convert<T>(*defaultValueValue, error);
if (!defaultValue) {
+ error = { R"(wrong type for "default": )" + error.message };
return {};
}
-
- return SourceFunction<T>(*propertyString, *stops, *defaultValue);
- }
-};
-
-template <class S>
-struct CompositeValue : std::pair<float, S> {
- using std::pair<float, S>::pair;
-};
-
-template <class S>
-struct Converter<CompositeValue<S>> {
- optional<CompositeValue<S>> operator()(const Convertible& value, Error& error) const {
- if (!isObject(value)) {
- error = { "stop must be an object" };
- return {};
- }
-
- auto zoomValue = objectMember(value, "zoom");
- if (!zoomValue) {
- error = { "stop must specify zoom" };
- return {};
- }
-
- auto propertyValue = objectMember(value, "value");
- if (!propertyValue) {
- error = { "stop must specify value" };
- return {};
- }
-
- optional<float> z = convert<float>(*zoomValue, error);
- if (!z) {
- return {};
- }
-
- optional<S> s = convert<S>(*propertyValue, error);
- if (!s) {
- return {};
- }
-
- return CompositeValue<S> { *z, *s };
- }
-};
-
-template <class T>
-struct Converter<CompositeExponentialStops<T>> {
- static constexpr const char * type = "exponential";
-
- optional<CompositeExponentialStops<T>> operator()(const Convertible& value, Error& error) const {
- auto stops = convertStops<CompositeValue<float>, T>(value, error);
- if (!stops) {
- return {};
- }
-
- auto base = 1.0f;
- auto baseValue = objectMember(value, "base");
- if (baseValue && toNumber(*baseValue)) {
- base = *toNumber(*baseValue);
- }
-
- std::map<float, std::map<float, T>> convertedStops;
- for (const auto& stop : *stops) {
- convertedStops[stop.first.first].emplace(stop.first.second, stop.second);
- }
-
- return CompositeExponentialStops<T>(convertedStops, base);
- }
-};
-
-template <class T>
-struct Converter<CompositeIntervalStops<T>> {
- static constexpr const char * type = "interval";
-
- optional<CompositeIntervalStops<T>> operator()(const Convertible& value, Error& error) const {
- auto stops = convertStops<CompositeValue<float>, T>(value, error);
- if (!stops) {
- return {};
- }
-
- std::map<float, std::map<float, T>> convertedStops;
- for (const auto& stop : *stops) {
- convertedStops[stop.first.first].emplace(stop.first.second, stop.second);
- }
-
- return CompositeIntervalStops<T>(convertedStops);
}
-};
-
-template <class T>
-struct Converter<CompositeCategoricalStops<T>> {
- static constexpr const char * type = "categorical";
-
- optional<CompositeCategoricalStops<T>> operator()(const Convertible& value, Error& error) const {
- auto stops = convertStops<CompositeValue<CategoricalValue>, T>(value, error);
- if (!stops) {
- return {};
- }
- std::map<float, std::map<CategoricalValue, T>> convertedStops;
- for (const auto& stop : *stops) {
- convertedStops[stop.first.first].emplace(stop.first.second, stop.second);
- }
-
- return CompositeCategoricalStops<T>(convertedStops);
- }
-};
-
-template <class T>
-struct Converter<CompositeFunction<T>> {
- optional<CompositeFunction<T>> operator()(const Convertible& value, Error& error) const {
- if (!isObject(value)) {
- error = { "function must be an object" };
- return {};
- }
-
- auto propertyValue = objectMember(value, "property");
- if (!propertyValue) {
- error = { "function must specify property" };
- return {};
- }
-
- auto propertyString = toString(*propertyValue);
- if (!propertyString) {
- error = { "function property must be a string" };
- return {};
- }
-
- auto stops = StopsConverter<T, typename CompositeFunction<T>::Stops>()(value, error);
- if (!stops) {
- return {};
- }
-
- auto defaultValue = convertDefaultValue<T>(value, error);
- if (!defaultValue) {
- return {};
- }
-
- return CompositeFunction<T>(*propertyString, *stops, *defaultValue);
- }
-};
+ return PropertyExpression<T>(std::move(*expression), defaultValue);
+}
} // namespace conversion
} // namespace style
diff --git a/include/mbgl/style/conversion/property_value.hpp b/include/mbgl/style/conversion/property_value.hpp
index 3130661f61..b03655a848 100644
--- a/include/mbgl/style/conversion/property_value.hpp
+++ b/include/mbgl/style/conversion/property_value.hpp
@@ -7,8 +7,8 @@
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/is_expression.hpp>
-#include <mbgl/style/expression/find_zoom_curve.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
+#include <mbgl/style/expression/literal.hpp>
namespace mbgl {
namespace style {
@@ -16,31 +16,29 @@ namespace conversion {
template <class T>
struct Converter<PropertyValue<T>> {
- optional<PropertyValue<T>> operator()(const Convertible& value, Error& error) const {
+ optional<PropertyValue<T>> operator()(const Convertible& value, Error& error, bool convertTokens = false) const {
using namespace mbgl::style::expression;
+ // Only icon-image and text-field support tokens, and they are both data-driven.
+ assert(!convertTokens);
+ (void)convertTokens;
+
if (isUndefined(value)) {
return PropertyValue<T>();
- } else if (isExpression(value)) {
+ }
+
+ optional<PropertyExpression<T>> expression;
+
+ if (isExpression(value)) {
ParsingContext ctx(valueTypeToExpressionType<T>());
- ParseResult expression = ctx.parseLayerPropertyExpression(value);
- if (!expression) {
+ ParseResult parsed = ctx.parseLayerPropertyExpression(value);
+ if (!parsed) {
error = { ctx.getCombinedErrors() };
return {};
}
-
- if (isFeatureConstant(**expression)) {
- return { CameraFunction<T>(std::move(*expression)) };
- } else {
- error = { "property expressions not supported" };
- return {};
- }
+ expression = PropertyExpression<T>(std::move(*parsed));
} else if (isObject(value)) {
- optional<CameraFunction<T>> function = convert<CameraFunction<T>>(value, error);
- if (!function) {
- return {};
- }
- return { *function };
+ expression = convertFunctionToExpression<T>(value, error, false);
} else {
optional<T> constant = convert<T>(value, error);
if (!constant) {
@@ -48,6 +46,26 @@ struct Converter<PropertyValue<T>> {
}
return { *constant };
}
+
+ if (!expression) {
+ return {};
+ } else if (!(*expression).isFeatureConstant()) {
+ error = { "data expressions not supported" };
+ return {};
+ } else if (!(*expression).isZoomConstant()) {
+ return { std::move(*expression) };
+ } else if ((*expression).getExpression().getKind() == Kind::Literal) {
+ optional<T> constant = fromExpressionValue<T>(
+ static_cast<const Literal&>((*expression).getExpression()).getValue());
+ if (!constant) {
+ return {};
+ }
+ return PropertyValue<T>(*constant);
+ } else {
+ assert(false);
+ error = { "expected a literal expression" };
+ return {};
+ }
}
};
diff --git a/include/mbgl/style/data_driven_property_value.hpp b/include/mbgl/style/data_driven_property_value.hpp
index 0a1fce29c7..baea861f62 100644
--- a/include/mbgl/style/data_driven_property_value.hpp
+++ b/include/mbgl/style/data_driven_property_value.hpp
@@ -2,9 +2,7 @@
#include <mbgl/util/variant.hpp>
#include <mbgl/style/undefined.hpp>
-#include <mbgl/style/function/camera_function.hpp>
-#include <mbgl/style/function/source_function.hpp>
-#include <mbgl/style/function/composite_function.hpp>
+#include <mbgl/style/property_expression.hpp>
namespace mbgl {
namespace style {
@@ -15,9 +13,7 @@ private:
using Value = variant<
Undefined,
T,
- CameraFunction<T>,
- SourceFunction<T>,
- CompositeFunction<T>>;
+ PropertyExpression<T>>;
Value value;
@@ -33,32 +29,32 @@ private:
public:
DataDrivenPropertyValue() = default;
- DataDrivenPropertyValue( T v) : value(std::move(v)) {}
- DataDrivenPropertyValue( CameraFunction<T> v) : value(std::move(v)) {}
- DataDrivenPropertyValue( SourceFunction<T> v) : value(std::move(v)) {}
- DataDrivenPropertyValue(CompositeFunction<T> v) : value(std::move(v)) {}
+ DataDrivenPropertyValue( T v) : value(std::move(v)) {}
+ DataDrivenPropertyValue(PropertyExpression<T> v) : value(std::move(v)) {}
bool isUndefined() const {
return value.template is<Undefined>();
}
bool isDataDriven() const {
- return value.template is<SourceFunction<T>>() || value.template is<CompositeFunction<T>>();
- }
-
- bool isZoomConstant() const {
- return !value.template is<CameraFunction<T>>() && !value.template is<CompositeFunction<T>>();
+ return value.match(
+ [] (const Undefined&) { return false; },
+ [] (const T&) { return false; },
+ [] (const PropertyExpression<T>& fn) { return !fn.isFeatureConstant(); }
+ );
}
- bool isExpression() const {
+ bool isZoomConstant() const {
return value.match(
- [] (const Undefined&) { return false; },
- [] (const T&) { return false; },
- [] (const CameraFunction<T>& fn) { return fn.isExpression; },
- [] (const SourceFunction<T>& fn) { return fn.isExpression; },
- [] (const CompositeFunction<T>& fn) { return fn.isExpression; });
+ [] (const Undefined&) { return true; },
+ [] (const T&) { return true; },
+ [] (const PropertyExpression<T>& fn) { return fn.isZoomConstant(); }
+ );
}
+ const T & asConstant() const { return value.template get< T >(); }
+ const PropertyExpression<T>& asExpression() const { return value.template get<PropertyExpression<T>>(); }
+
template <class... Ts>
auto match(Ts&&... ts) const {
return value.match(std::forward<Ts>(ts)...);
diff --git a/include/mbgl/style/expression/array_assertion.hpp b/include/mbgl/style/expression/array_assertion.hpp
index af153611ff..0c0912b73e 100644
--- a/include/mbgl/style/expression/array_assertion.hpp
+++ b/include/mbgl/style/expression/array_assertion.hpp
@@ -14,7 +14,7 @@ namespace expression {
class ArrayAssertion : public Expression {
public:
ArrayAssertion(type::Array type_, std::unique_ptr<Expression> input_) :
- Expression(type_),
+ Expression(Kind::ArrayAssertion, type_),
input(std::move(input_))
{}
@@ -24,7 +24,8 @@ public:
void eachChild(const std::function<void(const Expression&)>& visit) const override;
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const ArrayAssertion*>(&e)) {
+ if (e.getKind() == Kind::ArrayAssertion) {
+ auto rhs = static_cast<const ArrayAssertion*>(&e);
return getType() == rhs->getType() && *input == *(rhs->input);
}
return false;
diff --git a/include/mbgl/style/expression/assertion.hpp b/include/mbgl/style/expression/assertion.hpp
index d1e919b10f..90da16b068 100644
--- a/include/mbgl/style/expression/assertion.hpp
+++ b/include/mbgl/style/expression/assertion.hpp
@@ -13,10 +13,7 @@ namespace expression {
class Assertion : public Expression {
public:
- Assertion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
- Expression(type_),
- inputs(std::move(inputs_))
- {}
+ Assertion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_);
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
diff --git a/include/mbgl/style/expression/at.hpp b/include/mbgl/style/expression/at.hpp
index 1e6f1c7dd2..f0dbccb794 100644
--- a/include/mbgl/style/expression/at.hpp
+++ b/include/mbgl/style/expression/at.hpp
@@ -11,7 +11,7 @@ namespace expression {
class At : public Expression {
public:
At(std::unique_ptr<Expression> index_, std::unique_ptr<Expression> input_) :
- Expression(input_->getType().get<type::Array>().itemType),
+ Expression(Kind::At, input_->getType().get<type::Array>().itemType),
index(std::move(index_)),
input(std::move(input_))
{}
@@ -22,7 +22,8 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const At*>(&e)) {
+ if (e.getKind() == Kind::At) {
+ auto rhs = static_cast<const At*>(&e);
return *index == *(rhs->index) && *input == *(rhs->input);
}
return false;
diff --git a/include/mbgl/style/expression/boolean_operator.hpp b/include/mbgl/style/expression/boolean_operator.hpp
index 6d0f85756a..d254747513 100644
--- a/include/mbgl/style/expression/boolean_operator.hpp
+++ b/include/mbgl/style/expression/boolean_operator.hpp
@@ -12,7 +12,7 @@ namespace expression {
class Any : public Expression {
public:
Any(std::vector<std::unique_ptr<Expression>> inputs_) :
- Expression(type::Boolean),
+ Expression(Kind::Any, type::Boolean),
inputs(std::move(inputs_))
{}
@@ -31,7 +31,7 @@ private:
class All : public Expression {
public:
All(std::vector<std::unique_ptr<Expression>> inputs_) :
- Expression(type::Boolean),
+ Expression(Kind::All, type::Boolean),
inputs(std::move(inputs_))
{}
diff --git a/include/mbgl/style/expression/case.hpp b/include/mbgl/style/expression/case.hpp
index 667ca53712..02dc3bc4c2 100644
--- a/include/mbgl/style/expression/case.hpp
+++ b/include/mbgl/style/expression/case.hpp
@@ -16,7 +16,7 @@ public:
using Branch = std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>;
Case(type::Type type_, std::vector<Branch> branches_, std::unique_ptr<Expression> otherwise_)
- : Expression(type_), branches(std::move(branches_)), otherwise(std::move(otherwise_)) {
+ : Expression(Kind::Case, type_), branches(std::move(branches_)), otherwise(std::move(otherwise_)) {
}
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
diff --git a/include/mbgl/style/expression/coalesce.hpp b/include/mbgl/style/expression/coalesce.hpp
index a858bef695..cd60cee02e 100644
--- a/include/mbgl/style/expression/coalesce.hpp
+++ b/include/mbgl/style/expression/coalesce.hpp
@@ -15,7 +15,7 @@ class Coalesce : public Expression {
public:
using Args = std::vector<std::unique_ptr<Expression>>;
Coalesce(const type::Type& type_, Args args_) :
- Expression(type_),
+ Expression(Kind::Coalesce, type_),
args(std::move(args_))
{}
diff --git a/include/mbgl/style/expression/collator.hpp b/include/mbgl/style/expression/collator.hpp
new file mode 100644
index 0000000000..2a79e55556
--- /dev/null
+++ b/include/mbgl/style/expression/collator.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <mbgl/util/feature.hpp>
+#include <mbgl/util/optional.hpp>
+
+#include <string>
+#include <memory>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+class Collator {
+public:
+ Collator(bool caseSensitive, bool diacriticSensitive, optional<std::string> locale = {});
+
+ bool operator==(const Collator& other) const;
+
+ int compare(const std::string& lhs, const std::string& rhs) const;
+
+ std::string resolvedLocale() const;
+private:
+ class Impl;
+ std::shared_ptr<Impl> impl;
+};
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/collator_expression.hpp b/include/mbgl/style/expression/collator_expression.hpp
new file mode 100644
index 0000000000..2551cd19c8
--- /dev/null
+++ b/include/mbgl/style/expression/collator_expression.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/expression/parsing_context.hpp>
+#include <mbgl/style/conversion.hpp>
+
+#include <memory>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+class CollatorExpression : public Expression {
+public:
+ CollatorExpression(std::unique_ptr<Expression> caseSensitive,
+ std::unique_ptr<Expression> diacriticSensitive,
+ optional<std::unique_ptr<Expression>> locale);
+
+ EvaluationResult evaluate(const EvaluationContext&) const override;
+ static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
+
+ void eachChild(const std::function<void(const Expression&)>&) const override;
+
+ bool operator==(const Expression& e) const override;
+
+ std::vector<optional<Value>> possibleOutputs() const override {
+ // Technically the set of possible outputs is the combinatoric set of Collators produced
+ // by all possibleOutputs of locale/caseSensitive/diacriticSensitive
+ // But for the primary use of Collators in comparison operators, we ignore the Collator's
+ // possibleOutputs anyway, so we can get away with leaving this undefined for now.
+ return { nullopt };
+ }
+
+ mbgl::Value serialize() const override;
+ std::string getOperator() const override { return "collator"; }
+private:
+ std::unique_ptr<Expression> caseSensitive;
+ std::unique_ptr<Expression> diacriticSensitive;
+ optional<std::unique_ptr<Expression>> locale;
+};
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/compound_expression.hpp b/include/mbgl/style/expression/compound_expression.hpp
index 6baaae862f..c618f2f206 100644
--- a/include/mbgl/style/expression/compound_expression.hpp
+++ b/include/mbgl/style/expression/compound_expression.hpp
@@ -33,10 +33,13 @@ namespace expression {
*/
struct VarargsType { type::Type type; };
template <typename T>
-struct Varargs : std::vector<T> { using std::vector<T>::vector; };
+struct Varargs : std::vector<T> {
+ template <class... Args>
+ Varargs(Args&&... args) : std::vector<T>(std::forward<Args>(args)...) {}
+};
namespace detail {
-// Base class for the Signature<Fn> structs that are used to determine the
+// Base class for the Signature<Fn> structs that are used to determine
// each CompoundExpression definition's type::Type data from the type of its
// "evaluate" function.
struct SignatureBase {
@@ -62,7 +65,7 @@ struct SignatureBase {
class CompoundExpressionBase : public Expression {
public:
CompoundExpressionBase(std::string name_, const detail::SignatureBase& signature) :
- Expression(signature.result),
+ Expression(Kind::CompoundExpression, signature.result),
name(std::move(name_)),
params(signature.params)
{}
@@ -108,7 +111,8 @@ public:
}
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const CompoundExpression*>(&e)) {
+ if (e.getKind() == Kind::CompoundExpression) {
+ auto rhs = static_cast<const CompoundExpression*>(&e);
return getName() == rhs->getName() && Expression::childrenEqual(args, rhs->args);
}
return false;
@@ -134,10 +138,6 @@ struct CompoundExpressionRegistry {
ParseResult parseCompoundExpression(const std::string name, const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
-ParseResult createCompoundExpression(const CompoundExpressionRegistry::Definition& definition,
- std::vector<std::unique_ptr<Expression>> args,
- ParsingContext& ctx);
-
ParseResult createCompoundExpression(const std::string& name,
std::vector<std::unique_ptr<Expression>> args,
ParsingContext& ctx);
diff --git a/include/mbgl/style/expression/dsl.hpp b/include/mbgl/style/expression/dsl.hpp
new file mode 100644
index 0000000000..e9de20de18
--- /dev/null
+++ b/include/mbgl/style/expression/dsl.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <mbgl/style/expression/value.hpp>
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/expression/interpolator.hpp>
+#include <mbgl/util/ignore.hpp>
+
+#include <memory>
+#include <string>
+#include <initializer_list>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+namespace dsl {
+
+// This convenience API does little to no expression validation or type-checking, and is intended for
+// use only by test and other non-production code.
+
+template <class... Args>
+std::vector<std::unique_ptr<Expression>> vec(Args... args) {
+ std::vector<std::unique_ptr<Expression>> result;
+ util::ignore({ (result.push_back(std::move(args)), 0)... });
+ return result;
+}
+
+std::unique_ptr<Expression> error(std::string);
+
+std::unique_ptr<Expression> literal(const char* value);
+std::unique_ptr<Expression> literal(Value value);
+std::unique_ptr<Expression> literal(std::initializer_list<double> value);
+std::unique_ptr<Expression> literal(std::initializer_list<const char *> value);
+
+std::unique_ptr<Expression> number(std::unique_ptr<Expression>);
+std::unique_ptr<Expression> string(std::unique_ptr<Expression>);
+std::unique_ptr<Expression> boolean(std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> toColor(std::unique_ptr<Expression>);
+std::unique_ptr<Expression> toString(std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> get(const char* value);
+std::unique_ptr<Expression> get(std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> id();
+std::unique_ptr<Expression> zoom();
+
+std::unique_ptr<Expression> eq(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+std::unique_ptr<Expression> ne(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+std::unique_ptr<Expression> gt(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+std::unique_ptr<Expression> lt(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> step(std::unique_ptr<Expression> input,
+ std::unique_ptr<Expression> output0,
+ double input1, std::unique_ptr<Expression> output1);
+
+Interpolator linear();
+Interpolator exponential(double base);
+Interpolator cubicBezier(double x1, double y1, double x2, double y2);
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1);
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2);
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2,
+ double input3, std::unique_ptr<Expression> output3);
+
+std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inputs);
+
+} // namespace dsl
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/equals.hpp b/include/mbgl/style/expression/equals.hpp
index 54df890a68..1e8bf7acef 100644
--- a/include/mbgl/style/expression/equals.hpp
+++ b/include/mbgl/style/expression/equals.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/style/expression/collator_expression.hpp>
#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <mbgl/style/conversion.hpp>
@@ -12,7 +13,7 @@ namespace expression {
class Equals : public Expression {
public:
- Equals(std::unique_ptr<Expression> lhs, std::unique_ptr<Expression> rhs, bool negate);
+ Equals(std::unique_ptr<Expression> lhs, std::unique_ptr<Expression> rhs, optional<std::unique_ptr<Expression>> collator, bool negate);
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
@@ -25,6 +26,7 @@ public:
private:
std::unique_ptr<Expression> lhs;
std::unique_ptr<Expression> rhs;
+ optional<std::unique_ptr<Expression>> collator;
bool negate;
};
diff --git a/include/mbgl/style/expression/error.hpp b/include/mbgl/style/expression/error.hpp
new file mode 100644
index 0000000000..9e1da2f0f0
--- /dev/null
+++ b/include/mbgl/style/expression/error.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <mbgl/style/expression/expression.hpp>
+
+#include <string>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+class Error : public Expression {
+public:
+ Error(std::string message_)
+ : Expression(Kind::Error, type::Error),
+ message(std::move(message_)) {}
+
+ void eachChild(const std::function<void(const Expression&)>&) const override {}
+
+ bool operator==(const Expression& e) const override {
+ return e.getKind() == Kind::Error;
+ }
+
+ EvaluationResult evaluate(const EvaluationContext&) const override {
+ return EvaluationError{message};
+ }
+
+ std::vector<optional<Value>> possibleOutputs() const override {
+ return {};
+ }
+
+ std::string getOperator() const override { return "error"; }
+
+private:
+ std::string message;
+};
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp
index c41ac0b5f1..8301f1572c 100644
--- a/include/mbgl/style/expression/expression.hpp
+++ b/include/mbgl/style/expression/expression.hpp
@@ -113,9 +113,32 @@ public:
ParseResult ExpressionClass::parse(const V&, ParsingContext),
which handles parsing a style-spec JSON representation of the expression.
*/
+
+enum class Kind : int32_t {
+ Coalesce,
+ CompoundExpression,
+ Literal,
+ ArrayAssertion,
+ At,
+ Interpolate,
+ Assertion,
+ Length,
+ Step,
+ Let,
+ Var,
+ CollatorExpression,
+ Coercion,
+ Match,
+ Error,
+ Case,
+ Any,
+ All,
+ Equals,
+};
+
class Expression {
public:
- Expression(type::Type type_) : type(std::move(type_)) {}
+ Expression(Kind kind_, type::Type type_) : kind(kind_), type(std::move(type_)) {}
virtual ~Expression() = default;
virtual EvaluationResult evaluate(const EvaluationContext& params) const = 0;
@@ -125,6 +148,7 @@ public:
return !operator==(rhs);
}
+ Kind getKind() const { return kind; };
type::Type getType() const { return type; };
EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> heatmapDensity) const;
@@ -182,6 +206,7 @@ protected:
}
private:
+ Kind kind;
type::Type type;
};
diff --git a/include/mbgl/style/expression/find_zoom_curve.hpp b/include/mbgl/style/expression/find_zoom_curve.hpp
index 6301938033..6f1419a69f 100644
--- a/include/mbgl/style/expression/find_zoom_curve.hpp
+++ b/include/mbgl/style/expression/find_zoom_curve.hpp
@@ -11,9 +11,9 @@ namespace mbgl {
namespace style {
namespace expression {
-optional<variant<const InterpolateBase*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e);
+optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e);
-variant<const InterpolateBase*, const Step*> findZoomCurveChecked(const expression::Expression* e);
+variant<std::nullptr_t, const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e);
} // namespace expression
} // namespace style
diff --git a/include/mbgl/style/expression/interpolate.hpp b/include/mbgl/style/expression/interpolate.hpp
index cc744ac7b7..0e78504719 100644
--- a/include/mbgl/style/expression/interpolate.hpp
+++ b/include/mbgl/style/expression/interpolate.hpp
@@ -3,12 +3,9 @@
#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <mbgl/style/expression/get_covering_stops.hpp>
+#include <mbgl/style/expression/interpolator.hpp>
#include <mbgl/style/conversion.hpp>
-#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/range.hpp>
-#include <mbgl/util/unitbezier.hpp>
-
#include <memory>
#include <map>
#include <cmath>
@@ -17,57 +14,14 @@ namespace mbgl {
namespace style {
namespace expression {
-class ExponentialInterpolator {
-public:
- ExponentialInterpolator(double base_) : base(base_) {}
-
- double base;
-
- double interpolationFactor(const Range<double>& inputLevels, const double input) const {
- return util::interpolationFactor(base,
- Range<float> {
- static_cast<float>(inputLevels.min),
- static_cast<float>(inputLevels.max)
- },
- input);
- }
-
- bool operator==(const ExponentialInterpolator& rhs) const {
- return base == rhs.base;
- }
-};
-
-class CubicBezierInterpolator {
-public:
- CubicBezierInterpolator(double x1_, double y1_, double x2_, double y2_) : ub(x1_, y1_, x2_, y2_) {}
-
- double interpolationFactor(const Range<double>& inputLevels, const double input) const {
- return ub.solve(input / (inputLevels.max - inputLevels.min), 1e-6);
- }
-
- bool operator==(const CubicBezierInterpolator& rhs) const {
- return ub == rhs.ub;
- }
-
- util::UnitBezier ub;
-};
-
-
ParseResult parseInterpolate(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
-class InterpolateBase : public Expression {
+class Interpolate : public Expression {
public:
- using Interpolator = variant<ExponentialInterpolator, CubicBezierInterpolator>;
-
- InterpolateBase(const type::Type& type_,
- Interpolator interpolator_,
- std::unique_ptr<Expression> input_,
- std::map<double, std::unique_ptr<Expression>> stops_
- ) : Expression(type_),
- interpolator(std::move(interpolator_)),
- input(std::move(input_)),
- stops(std::move(stops_))
- {}
+ Interpolate(const type::Type& type_,
+ Interpolator interpolator_,
+ std::unique_ptr<Expression> input_,
+ std::map<double, std::unique_ptr<Expression>> stops_);
const std::unique_ptr<Expression>& getInput() const { return input; }
const Interpolator& getInterpolator() const { return interpolator; }
@@ -96,100 +50,37 @@ public:
);
}
- std::vector<optional<Value>> possibleOutputs() const override;
-
-protected:
- const Interpolator interpolator;
- const std::unique_ptr<Expression> input;
- const std::map<double, std::unique_ptr<Expression>> stops;
-};
-
-template <typename T>
-class Interpolate : public InterpolateBase {
-public:
- Interpolate(type::Type type_,
- Interpolator interpolator_,
- std::unique_ptr<Expression> input_,
- std::map<double, std::unique_ptr<Expression>> stops_
- ) : InterpolateBase(std::move(type_), std::move(interpolator_), std::move(input_), std::move(stops_))
- {
- static_assert(util::Interpolatable<T>::value, "Interpolate expression requires an interpolatable value type.");
- }
-
- EvaluationResult evaluate(const EvaluationContext& params) const override {
- const EvaluationResult evaluatedInput = input->evaluate(params);
- if (!evaluatedInput) {
- return evaluatedInput.error();
- }
-
- float x = *fromExpressionValue<float>(*evaluatedInput);
- if (std::isnan(x)) {
- return EvaluationError { "Input is not a number." };
- }
-
- if (stops.empty()) {
- return EvaluationError { "No stops in exponential curve." };
- }
-
- auto it = stops.upper_bound(x);
- if (it == stops.end()) {
- return stops.rbegin()->second->evaluate(params);
- } else if (it == stops.begin()) {
- return stops.begin()->second->evaluate(params);
- } else {
- float t = interpolationFactor({ std::prev(it)->first, it->first }, x);
-
- if (t == 0.0f) {
- return std::prev(it)->second->evaluate(params);
- }
- if (t == 1.0f) {
- return it->second->evaluate(params);
- }
-
- EvaluationResult lower = std::prev(it)->second->evaluate(params);
- if (!lower) {
- return lower.error();
- }
- EvaluationResult upper = it->second->evaluate(params);
- if (!upper) {
- return upper.error();
- }
-
- if (!lower->is<T>()) {
- return EvaluationError {
- "Expected value to be of type " + toString(valueTypeToExpressionType<T>()) +
- ", but found " + toString(typeOf(*lower)) + " instead."
- };
- }
-
- if (!upper->is<T>()) {
- return EvaluationError {
- "Expected value to be of type " + toString(valueTypeToExpressionType<T>()) +
- ", but found " + toString(typeOf(*upper)) + " instead."
- };
- }
- return util::interpolate(lower->get<T>(), upper->get<T>(), t);
- }
- }
-
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const Interpolate*>(&e)) {
+ if (e.getKind() == Kind::Interpolate) {
+ auto rhs = static_cast<const Interpolate*>(&e);
if (interpolator != rhs->interpolator ||
*input != *(rhs->input) ||
stops.size() != rhs->stops.size())
{
return false;
}
-
+
return Expression::childrenEqual(stops, rhs->stops);
}
return false;
}
-
+
+ std::vector<optional<Value>> possibleOutputs() const override;
mbgl::Value serialize() const override;
std::string getOperator() const override { return "interpolate"; }
+
+protected:
+ const Interpolator interpolator;
+ const std::unique_ptr<Expression> input;
+ const std::map<double, std::unique_ptr<Expression>> stops;
};
+ParseResult createInterpolate(type::Type type,
+ Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ std::map<double, std::unique_ptr<Expression>> stops,
+ ParsingContext& ctx);
+
} // namespace expression
} // namespace style
} // namespace mbgl
diff --git a/include/mbgl/style/expression/interpolator.hpp b/include/mbgl/style/expression/interpolator.hpp
new file mode 100644
index 0000000000..f37fb2c9cd
--- /dev/null
+++ b/include/mbgl/style/expression/interpolator.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <mbgl/util/interpolate.hpp>
+#include <mbgl/util/range.hpp>
+#include <mbgl/util/unitbezier.hpp>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+class ExponentialInterpolator {
+public:
+ ExponentialInterpolator(double base_) : base(base_) {}
+
+ double base;
+
+ double interpolationFactor(const Range<double>& inputLevels, const double input) const {
+ return util::interpolationFactor(base,
+ Range<float> {
+ static_cast<float>(inputLevels.min),
+ static_cast<float>(inputLevels.max)
+ },
+ input);
+ }
+
+ bool operator==(const ExponentialInterpolator& rhs) const {
+ return base == rhs.base;
+ }
+};
+
+class CubicBezierInterpolator {
+public:
+ CubicBezierInterpolator(double x1_, double y1_, double x2_, double y2_) : ub(x1_, y1_, x2_, y2_) {}
+
+ double interpolationFactor(const Range<double>& inputLevels, const double input) const {
+ return ub.solve(input / (inputLevels.max - inputLevels.min), 1e-6);
+ }
+
+ bool operator==(const CubicBezierInterpolator& rhs) const {
+ return ub == rhs.ub;
+ }
+
+ util::UnitBezier ub;
+};
+
+using Interpolator = variant<ExponentialInterpolator, CubicBezierInterpolator>;
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/is_constant.hpp b/include/mbgl/style/expression/is_constant.hpp
index 29e03ccbc0..065fa30db1 100644
--- a/include/mbgl/style/expression/is_constant.hpp
+++ b/include/mbgl/style/expression/is_constant.hpp
@@ -9,7 +9,8 @@ namespace expression {
template <typename T>
bool isGlobalPropertyConstant(const Expression& expression, const T& properties) {
- if (auto e = dynamic_cast<const CompoundExpressionBase*>(&expression)) {
+ if (expression.getKind() == Kind::CompoundExpression) {
+ auto e = static_cast<const CompoundExpressionBase*>(&expression);
for (const std::string& property : properties) {
if (e->getName() == property) {
return false;
diff --git a/include/mbgl/style/expression/let.hpp b/include/mbgl/style/expression/let.hpp
index d0210d8bba..d11ba1b976 100644
--- a/include/mbgl/style/expression/let.hpp
+++ b/include/mbgl/style/expression/let.hpp
@@ -16,7 +16,7 @@ public:
using Bindings = std::map<std::string, std::shared_ptr<Expression>>;
Let(Bindings bindings_, std::unique_ptr<Expression> result_) :
- Expression(result_->getType()),
+ Expression(Kind::Let, result_->getType()),
bindings(std::move(bindings_)),
result(std::move(result_))
{}
@@ -27,7 +27,8 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const Let*>(&e)) {
+ if (e.getKind() == Kind::Let) {
+ auto rhs = static_cast<const Let*>(&e);
return *result == *(rhs->result);
}
return false;
@@ -49,7 +50,7 @@ private:
class Var : public Expression {
public:
Var(std::string name_, std::shared_ptr<Expression> value_) :
- Expression(value_->getType()),
+ Expression(Kind::Var, value_->getType()),
name(std::move(name_)),
value(value_)
{}
@@ -60,7 +61,8 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override;
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const Var*>(&e)) {
+ if (e.getKind() == Kind::Var) {
+ auto rhs = static_cast<const Var*>(&e);
return *value == *(rhs->value);
}
return false;
diff --git a/include/mbgl/style/expression/literal.hpp b/include/mbgl/style/expression/literal.hpp
index a00c468efc..bcae23b1fa 100644
--- a/include/mbgl/style/expression/literal.hpp
+++ b/include/mbgl/style/expression/literal.hpp
@@ -13,12 +13,12 @@ namespace expression {
class Literal : public Expression {
public:
Literal(Value value_)
- : Expression(typeOf(value_))
+ : Expression(Kind::Literal, typeOf(value_))
, value(value_)
{}
Literal(type::Array type_, std::vector<Value> value_)
- : Expression(type_)
+ : Expression(Kind::Literal, type_)
, value(value_)
{}
@@ -31,7 +31,8 @@ public:
void eachChild(const std::function<void(const Expression&)>&) const override {}
bool operator==(const Expression& e) const override {
- if (auto rhs = dynamic_cast<const Literal*>(&e)) {
+ if (e.getKind() == Kind::Literal) {
+ auto rhs = static_cast<const Literal*>(&e);
return value == rhs->value;
}
return false;
@@ -47,6 +48,7 @@ public:
mbgl::Value serialize() const override;
std::string getOperator() const override { return "literal"; }
+
private:
Value value;
};
diff --git a/include/mbgl/style/expression/match.hpp b/include/mbgl/style/expression/match.hpp
index 3775e38067..2ce4b7a533 100644
--- a/include/mbgl/style/expression/match.hpp
+++ b/include/mbgl/style/expression/match.hpp
@@ -19,7 +19,7 @@ public:
std::unique_ptr<Expression> input_,
Branches branches_,
std::unique_ptr<Expression> otherwise_
- ) : Expression(type_),
+ ) : Expression(Kind::Match, type_),
input(std::move(input_)),
branches(std::move(branches_)),
otherwise(std::move(otherwise_))
diff --git a/include/mbgl/style/expression/step.hpp b/include/mbgl/style/expression/step.hpp
index 2f9524a53c..24e29b1a4e 100644
--- a/include/mbgl/style/expression/step.hpp
+++ b/include/mbgl/style/expression/step.hpp
@@ -1,4 +1,3 @@
-
#pragma once
#include <mbgl/style/expression/expression.hpp>
@@ -10,7 +9,6 @@
#include <memory>
#include <map>
-
namespace mbgl {
namespace style {
namespace expression {
@@ -18,12 +16,8 @@ namespace expression {
class Step : public Expression {
public:
Step(const type::Type& type_,
- std::unique_ptr<Expression> input_,
- std::map<double, std::unique_ptr<Expression>> stops_
- ) : Expression(type_),
- input(std::move(input_)),
- stops(std::move(stops_))
- {}
+ std::unique_ptr<Expression> input_,
+ std::map<double, std::unique_ptr<Expression>> stops_);
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
@@ -40,6 +34,7 @@ public:
mbgl::Value serialize() const override;
std::string getOperator() const override { return "step"; }
+
private:
const std::unique_ptr<Expression> input;
const std::map<double, std::unique_ptr<Expression>> stops;
diff --git a/include/mbgl/style/expression/type.hpp b/include/mbgl/style/expression/type.hpp
index 513c4bdc17..316496839b 100644
--- a/include/mbgl/style/expression/type.hpp
+++ b/include/mbgl/style/expression/type.hpp
@@ -60,6 +60,12 @@ struct ValueType {
std::string getName() const { return "value"; }
bool operator==(const ValueType&) const { return true; }
};
+
+struct CollatorType {
+ constexpr CollatorType() {}; // NOLINT
+ std::string getName() const { return "collator"; }
+ bool operator==(const CollatorType&) const { return true; }
+};
constexpr NullType Null;
constexpr NumberType Number;
@@ -68,6 +74,7 @@ constexpr BooleanType Boolean;
constexpr ColorType Color;
constexpr ValueType Value;
constexpr ObjectType Object;
+constexpr CollatorType Collator;
constexpr ErrorType Error;
struct Array;
@@ -81,6 +88,7 @@ using Type = variant<
ObjectType,
ValueType,
mapbox::util::recursive_wrapper<Array>,
+ CollatorType,
ErrorType>;
struct Array {
diff --git a/include/mbgl/style/expression/value.hpp b/include/mbgl/style/expression/value.hpp
index 7839ff2ca7..b1126118a9 100644
--- a/include/mbgl/style/expression/value.hpp
+++ b/include/mbgl/style/expression/value.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/style/expression/collator.hpp>
#include <mbgl/style/expression/type.hpp>
#include <mbgl/style/position.hpp>
#include <mbgl/style/types.hpp>
@@ -23,6 +24,7 @@ using ValueBase = variant<
double,
std::string,
Color,
+ Collator,
mapbox::util::recursive_wrapper<std::vector<Value>>,
mapbox::util::recursive_wrapper<std::unordered_map<std::string, Value>>>;
struct Value : ValueBase {
@@ -58,64 +60,39 @@ type::Type valueTypeToExpressionType();
Conversions between style value types and expression::Value
*/
-// no-op overloads
-Value toExpressionValue(const Value&);
-
-// T = Value (just wrap in optional)
-template <typename T>
-std::enable_if_t<std::is_same<T, Value>::value,
-optional<T>> fromExpressionValue(const Value& v)
-{
- return optional<T>(v);
-}
-
-// T = member type of Value
-template <typename T>
-std::enable_if_t< std::is_convertible<T, Value>::value && !std::is_same<T, Value>::value,
-optional<T>> fromExpressionValue(const Value& v)
-{
- return v.template is<T>() ? v.template get<T>() : optional<T>();
-}
-
-// real conversions
-template <typename T, typename Enable = std::enable_if_t< !std::is_convertible<T, Value>::value >>
-Value toExpressionValue(const T& value);
-
-template <typename T>
-std::enable_if_t< !std::is_convertible<T, Value>::value,
-optional<T>> fromExpressionValue(const Value& v);
-
-
-
template <class T, class Enable = void>
struct ValueConverter {
- using ExpressionType = T;
-
static Value toExpressionValue(const T& value) {
return Value(value);
}
+
static optional<T> fromExpressionValue(const Value& value) {
return value.template is<T>() ? value.template get<T>() : optional<T>();
}
};
template <>
-struct ValueConverter<float> {
- using ExpressionType = double;
- static type::Type expressionType() { return type::Number; }
- static Value toExpressionValue(const float value);
- static optional<float> fromExpressionValue(const Value& value);
+struct ValueConverter<Value> {
+ static type::Type expressionType() { return type::Value; }
+ static Value toExpressionValue(const Value& value) { return value; }
+ static optional<Value> fromExpressionValue(const Value& value) { return value; }
};
-template<>
+template <>
struct ValueConverter<mbgl::Value> {
static Value toExpressionValue(const mbgl::Value& value);
static mbgl::Value fromExpressionValue(const Value& value);
};
+template <>
+struct ValueConverter<float> {
+ static type::Type expressionType() { return type::Number; }
+ static Value toExpressionValue(const float value);
+ static optional<float> fromExpressionValue(const Value& value);
+};
+
template <typename T, std::size_t N>
struct ValueConverter<std::array<T, N>> {
- using ExpressionType = std::vector<Value>;
static type::Type expressionType() {
return type::Array(valueTypeToExpressionType<T>(), N);
}
@@ -125,7 +102,6 @@ struct ValueConverter<std::array<T, N>> {
template <typename T>
struct ValueConverter<std::vector<T>> {
- using ExpressionType = std::vector<Value>;
static type::Type expressionType() {
return type::Array(valueTypeToExpressionType<T>());
}
@@ -135,7 +111,6 @@ struct ValueConverter<std::vector<T>> {
template <>
struct ValueConverter<Position> {
- using ExpressionType = std::vector<Value>;
static type::Type expressionType() { return type::Array(type::Number, 3); }
static Value toExpressionValue(const mbgl::style::Position& value);
static optional<Position> fromExpressionValue(const Value& v);
@@ -143,13 +118,22 @@ struct ValueConverter<Position> {
template <typename T>
struct ValueConverter<T, std::enable_if_t< std::is_enum<T>::value >> {
- using ExpressionType = std::string;
static type::Type expressionType() { return type::String; }
static Value toExpressionValue(const T& value);
static optional<T> fromExpressionValue(const Value& value);
};
template <typename T>
+Value toExpressionValue(const T& value) {
+ return ValueConverter<T>::toExpressionValue(value);
+}
+
+template <typename T>
+optional<T> fromExpressionValue(const Value& value) {
+ return ValueConverter<T>::fromExpressionValue(value);
+}
+
+template <typename T>
std::vector<optional<T>> fromExpressionValues(const std::vector<optional<Value>>& values) {
std::vector<optional<T>> result;
for (const auto& value : values) {
diff --git a/include/mbgl/style/filter.hpp b/include/mbgl/style/filter.hpp
index ccf8dce188..c9dc9fb1ec 100644
--- a/include/mbgl/style/filter.hpp
+++ b/include/mbgl/style/filter.hpp
@@ -12,270 +12,44 @@
namespace mbgl {
namespace style {
-class Filter;
-
-class NullFilter {
-public:
- friend bool operator==(const NullFilter&, const NullFilter&) {
- return true;
- }
-};
-
-class EqualsFilter {
-public:
- std::string key;
- Value value;
-
- friend bool operator==(const EqualsFilter& lhs, const EqualsFilter& rhs) {
- return std::tie(lhs.key, lhs.value) == std::tie(rhs.key, rhs.value);
- }
-};
-
-class NotEqualsFilter {
-public:
- std::string key;
- Value value;
-
- friend bool operator==(const NotEqualsFilter& lhs, const NotEqualsFilter& rhs) {
- return std::tie(lhs.key, lhs.value) == std::tie(rhs.key, rhs.value);
- }
-};
-
-class LessThanFilter {
-public:
- std::string key;
- Value value;
-
- friend bool operator==(const LessThanFilter& lhs, const LessThanFilter& rhs) {
- return std::tie(lhs.key, lhs.value) == std::tie(rhs.key, rhs.value);
- }
-};
-
-class LessThanEqualsFilter {
-public:
- std::string key;
- Value value;
-
- friend bool operator==(const LessThanEqualsFilter& lhs, const LessThanEqualsFilter& rhs) {
- return std::tie(lhs.key, lhs.value) == std::tie(rhs.key, rhs.value);
- }
-};
-
-class GreaterThanFilter {
+class Filter {
public:
- std::string key;
- Value value;
-
- friend bool operator==(const GreaterThanFilter& lhs, const GreaterThanFilter& rhs) {
- return std::tie(lhs.key, lhs.value) == std::tie(rhs.key, rhs.value);
- }
-};
-
-class GreaterThanEqualsFilter {
+ optional<std::shared_ptr<const expression::Expression>> expression;
+private:
+ optional<mbgl::Value> legacyFilter;
public:
- std::string key;
- Value value;
-
- friend bool operator==(const GreaterThanEqualsFilter& lhs, const GreaterThanEqualsFilter& rhs) {
- return std::tie(lhs.key, lhs.value) == std::tie(rhs.key, rhs.value);
- }
-};
-
-class InFilter {
-public:
- std::string key;
- std::vector<Value> values;
-
- friend bool operator==(const InFilter& lhs, const InFilter& rhs) {
- return std::tie(lhs.key, lhs.values) == std::tie(rhs.key, rhs.values);
- }
-};
-
-class NotInFilter {
-public:
- std::string key;
- std::vector<Value> values;
-
- friend bool operator==(const NotInFilter& lhs, const NotInFilter& rhs) {
- return std::tie(lhs.key, lhs.values) == std::tie(rhs.key, rhs.values);
- }
-};
-
-class AnyFilter {
-public:
- std::vector<Filter> filters;
-
- friend bool operator==(const AnyFilter& lhs, const AnyFilter& rhs) {
- return lhs.filters == rhs.filters;
- }
-};
-
-class AllFilter {
-public:
- std::vector<Filter> filters;
-
- friend bool operator==(const AllFilter& lhs, const AllFilter& rhs) {
- return lhs.filters == rhs.filters;
- }
-};
-
-class NoneFilter {
-public:
- std::vector<Filter> filters;
-
- friend bool operator==(const NoneFilter& lhs, const NoneFilter& rhs) {
- return lhs.filters == rhs.filters;
- }
-};
-
-class HasFilter {
-public:
- std::string key;
-
- friend bool operator==(const HasFilter& lhs, const HasFilter& rhs) {
- return lhs.key == rhs.key;
- }
-};
-
-class NotHasFilter {
-public:
- std::string key;
-
- friend bool operator==(const NotHasFilter& lhs, const NotHasFilter& rhs) {
- return lhs.key == rhs.key;
- }
-};
-
-
-class TypeEqualsFilter {
-public:
- FeatureType value;
-
- friend bool operator==(const TypeEqualsFilter& lhs, const TypeEqualsFilter& rhs) {
- return lhs.value == rhs.value;
- }
-};
-
-class TypeNotEqualsFilter {
-public:
- FeatureType value;
-
- friend bool operator==(const TypeNotEqualsFilter& lhs, const TypeNotEqualsFilter& rhs) {
- return lhs.value == rhs.value;
- }
-};
-
-class TypeInFilter {
-public:
- std::vector<FeatureType> values;
-
- friend bool operator==(const TypeInFilter& lhs, const TypeInFilter& rhs) {
- return lhs.values == rhs.values;
- }
-};
-
-class TypeNotInFilter {
-public:
- std::vector<FeatureType> values;
-
- friend bool operator==(const TypeNotInFilter& lhs, const TypeNotInFilter& rhs) {
- return lhs.values == rhs.values;
- }
-};
-
-
-class IdentifierEqualsFilter {
-public:
- FeatureIdentifier value;
-
- friend bool operator==(const IdentifierEqualsFilter& lhs, const IdentifierEqualsFilter& rhs) {
- return lhs.value == rhs.value;
- }
-};
-
-class IdentifierNotEqualsFilter {
-public:
- FeatureIdentifier value;
-
- friend bool operator==(const IdentifierNotEqualsFilter& lhs, const IdentifierNotEqualsFilter& rhs) {
- return lhs.value == rhs.value;
- }
-};
-
-class IdentifierInFilter {
-public:
- std::vector<FeatureIdentifier> values;
-
- friend bool operator==(const IdentifierInFilter& lhs, const IdentifierInFilter& rhs) {
- return lhs.values == rhs.values;
- }
-};
-
-class IdentifierNotInFilter {
-public:
- std::vector<FeatureIdentifier> values;
-
- friend bool operator==(const IdentifierNotInFilter& lhs, const IdentifierNotInFilter& rhs) {
- return lhs.values == rhs.values;
- }
-};
-
-class HasIdentifierFilter {
-public:
- friend bool operator==(const HasIdentifierFilter&, const HasIdentifierFilter&) {
- return true;
+ Filter() : expression() {}
+
+ Filter(expression::ParseResult _expression, optional<mbgl::Value> _filter = {})
+ : expression(std::move(*_expression)),
+ legacyFilter(std::move(_filter)){
+ assert(!expression || *expression != nullptr);
}
-};
+
+ bool operator()(const expression::EvaluationContext& context) const;
-class NotHasIdentifierFilter {
-public:
- friend bool operator==(const NotHasIdentifierFilter&, const NotHasIdentifierFilter&) {
- return true;
+ friend bool operator==(const Filter& lhs, const Filter& rhs) {
+ if (!lhs.expression || !rhs.expression) {
+ return lhs.expression == rhs.expression;
+ } else {
+ return *(lhs.expression) == *(rhs.expression);
+ }
}
-};
-class ExpressionFilter {
-public:
- std::shared_ptr<const expression::Expression> expression;
+ friend bool operator!=(const Filter& lhs, const Filter& rhs) {
+ return !(lhs == rhs);
+ }
- friend bool operator==(const ExpressionFilter& lhs, const ExpressionFilter& rhs) {
- return *(lhs.expression) == *(rhs.expression);
+ mbgl::Value serialize() const {
+ if (legacyFilter) {
+ return *legacyFilter;
+ }
+ else if (expression) {
+ return (**expression).serialize();
+ }
+ return NullValue();
}
};
-
-using FilterBase = variant<
- class NullFilter,
- class EqualsFilter,
- class NotEqualsFilter,
- class LessThanFilter,
- class LessThanEqualsFilter,
- class GreaterThanFilter,
- class GreaterThanEqualsFilter,
- class InFilter,
- class NotInFilter,
- class AnyFilter,
- class AllFilter,
- class NoneFilter,
- class HasFilter,
- class NotHasFilter,
- class TypeEqualsFilter,
- class TypeNotEqualsFilter,
- class TypeInFilter,
- class TypeNotInFilter,
- class IdentifierEqualsFilter,
- class IdentifierNotEqualsFilter,
- class IdentifierInFilter,
- class IdentifierNotInFilter,
- class HasIdentifierFilter,
- class NotHasIdentifierFilter,
- class ExpressionFilter>;
-
-class Filter : public FilterBase {
-public:
- using FilterBase::FilterBase;
- bool operator()(const expression::EvaluationContext& context) const;
-};
-
} // namespace style
} // namespace mbgl
diff --git a/include/mbgl/style/filter_evaluator.hpp b/include/mbgl/style/filter_evaluator.hpp
deleted file mode 100644
index a4a4098b3f..0000000000
--- a/include/mbgl/style/filter_evaluator.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include <mbgl/style/filter.hpp>
-#include <mbgl/util/geometry.hpp>
-
-#include <type_traits>
-
-namespace mbgl {
-namespace style {
-
-/*
- A visitor that evaluates a `Filter` for a given feature.
-
- Use via `Filter::operator()`. For example:
-
- if (filter(feature)) {
- // matches the filter
- } else {
- // does not match
- }
-*/
-class FilterEvaluator {
-public:
- const expression::EvaluationContext context;
-
- bool operator()(const NullFilter&) const;
- bool operator()(const EqualsFilter& filter) const;
- bool operator()(const NotEqualsFilter& filter) const;
- bool operator()(const LessThanFilter& filter) const;
- bool operator()(const LessThanEqualsFilter& filter) const;
- bool operator()(const GreaterThanFilter& filter) const;
- bool operator()(const GreaterThanEqualsFilter& filter) const;
- bool operator()(const InFilter& filter) const;
- bool operator()(const NotInFilter& filter) const;
- bool operator()(const AnyFilter& filter) const;
- bool operator()(const AllFilter& filter) const;
- bool operator()(const NoneFilter& filter) const;
- bool operator()(const HasFilter& filter) const;
- bool operator()(const NotHasFilter& filter) const;
- bool operator()(const TypeEqualsFilter& filter) const;
- bool operator()(const TypeNotEqualsFilter& filter) const;
- bool operator()(const TypeInFilter& filter) const;
- bool operator()(const TypeNotInFilter& filter) const;
- bool operator()(const IdentifierEqualsFilter& filter) const;
- bool operator()(const IdentifierNotEqualsFilter& filter) const;
- bool operator()(const IdentifierInFilter& filter) const;
- bool operator()(const IdentifierNotInFilter& filter) const;
- bool operator()(const HasIdentifierFilter&) const;
- bool operator()(const NotHasIdentifierFilter&) const;
- bool operator()(const ExpressionFilter&) const;
-
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/camera_function.hpp b/include/mbgl/style/function/camera_function.hpp
deleted file mode 100644
index 97ba633e44..0000000000
--- a/include/mbgl/style/function/camera_function.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#pragma once
-
-#include <mbgl/style/expression/expression.hpp>
-#include <mbgl/style/expression/interpolate.hpp>
-#include <mbgl/style/expression/step.hpp>
-#include <mbgl/style/expression/find_zoom_curve.hpp>
-#include <mbgl/style/expression/value.hpp>
-#include <mbgl/style/expression/is_constant.hpp>
-#include <mbgl/style/function/convert.hpp>
-#include <mbgl/style/function/exponential_stops.hpp>
-#include <mbgl/style/function/interval_stops.hpp>
-#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/variant.hpp>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class CameraFunction {
-public:
- using Stops = std::conditional_t<
- util::Interpolatable<T>::value,
- variant<
- ExponentialStops<T>,
- IntervalStops<T>>,
- variant<
- IntervalStops<T>>>;
-
- CameraFunction(std::unique_ptr<expression::Expression> expression_)
- : isExpression(true),
- expression(std::move(expression_)),
- zoomCurve(expression::findZoomCurveChecked(expression.get()))
- {
- assert(!expression::isZoomConstant(*expression));
- assert(expression::isFeatureConstant(*expression));
- }
-
- CameraFunction(const Stops& stops)
- : isExpression(false),
- expression(stops.match([&] (const auto& s) {
- return expression::Convert::toExpression(s);
- })),
- zoomCurve(expression::findZoomCurveChecked(expression.get()))
- {}
-
- T evaluate(float zoom) const {
- const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr));
- if (result) {
- const optional<T> typed = expression::fromExpressionValue<T>(*result);
- return typed ? *typed : T();
- }
- return T();
- }
-
- float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const {
- return zoomCurve.match(
- [&](const expression::InterpolateBase* z) {
- return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue);
- },
- [&](const expression::Step*) { return 0.0f; }
- );
- }
-
- Range<float> getCoveringStops(const float lower, const float upper) const {
- return zoomCurve.match(
- [&](auto z) { return z->getCoveringStops(lower, upper); }
- );
- }
-
- std::vector<optional<T>> possibleOutputs() const {
- return expression::fromExpressionValues<T>(expression->possibleOutputs());
- }
-
- friend bool operator==(const CameraFunction& lhs,
- const CameraFunction& rhs) {
- return *lhs.expression == *rhs.expression;
- }
-
- bool useIntegerZoom = false;
- bool isExpression;
-
- const expression::Expression& getExpression() const { return *expression; }
-
-private:
- std::shared_ptr<expression::Expression> expression;
- const variant<const expression::InterpolateBase*, const expression::Step*> zoomCurve;
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/categorical_stops.hpp b/include/mbgl/style/function/categorical_stops.hpp
deleted file mode 100644
index c8505115ab..0000000000
--- a/include/mbgl/style/function/categorical_stops.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <mbgl/util/feature.hpp>
-#include <mbgl/util/variant.hpp>
-
-#include <cassert>
-#include <utility>
-#include <map>
-
-namespace mbgl {
-namespace style {
-
-class CategoricalValue : public variant<bool, int64_t, std::string> {
-public:
- using variant<bool, int64_t, std::string>::variant;
-};
-
-template <class T>
-class CategoricalStops {
-public:
- using Stops = std::map<CategoricalValue, T>;
-
- Stops stops;
-
- CategoricalStops() = default;
- CategoricalStops(Stops stops_)
- : stops(std::move(stops_)) {
- assert(stops.size() > 0);
- }
-
- optional<T> evaluate(const Value&) const;
-
- friend bool operator==(const CategoricalStops& lhs,
- const CategoricalStops& rhs) {
- return lhs.stops == rhs.stops;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/composite_categorical_stops.hpp b/include/mbgl/style/function/composite_categorical_stops.hpp
deleted file mode 100644
index b796621d1a..0000000000
--- a/include/mbgl/style/function/composite_categorical_stops.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <mbgl/style/function/categorical_stops.hpp>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class CompositeCategoricalStops {
-public:
- using Stops = std::map<float, std::map<CategoricalValue, T>>;
- Stops stops;
-
- CompositeCategoricalStops() = default;
- CompositeCategoricalStops(Stops stops_)
- : stops(std::move(stops_)) {
- }
-
- CategoricalStops<T> innerStops(const std::map<CategoricalValue, T>& stops_) const {
- return CategoricalStops<T>(stops_);
- }
-
- friend bool operator==(const CompositeCategoricalStops& lhs,
- const CompositeCategoricalStops& rhs) {
- return lhs.stops == rhs.stops;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/composite_exponential_stops.hpp b/include/mbgl/style/function/composite_exponential_stops.hpp
deleted file mode 100644
index f1ad32a04d..0000000000
--- a/include/mbgl/style/function/composite_exponential_stops.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <mbgl/style/function/exponential_stops.hpp>
-
-#include <map>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class CompositeExponentialStops {
-public:
- using Stops = std::map<float, std::map<float, T>>;
-
- Stops stops;
- float base = 1.0f;
-
- CompositeExponentialStops() = default;
- CompositeExponentialStops(Stops stops_, float base_ = 1.0f)
- : stops(std::move(stops_)),
- base(base_) {
- }
-
- ExponentialStops<T> innerStops(const std::map<float, T>& stops_) const {
- return ExponentialStops<T>(stops_, base);
- }
-
- friend bool operator==(const CompositeExponentialStops& lhs,
- const CompositeExponentialStops& rhs) {
- return lhs.stops == rhs.stops && lhs.base == rhs.base;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/composite_function.hpp b/include/mbgl/style/function/composite_function.hpp
deleted file mode 100644
index 614c345c25..0000000000
--- a/include/mbgl/style/function/composite_function.hpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#pragma once
-
-#include <mbgl/style/expression/expression.hpp>
-#include <mbgl/style/expression/interpolate.hpp>
-#include <mbgl/style/expression/step.hpp>
-#include <mbgl/style/expression/find_zoom_curve.hpp>
-#include <mbgl/style/expression/value.hpp>
-#include <mbgl/style/expression/is_constant.hpp>
-#include <mbgl/style/function/convert.hpp>
-#include <mbgl/style/function/composite_exponential_stops.hpp>
-#include <mbgl/style/function/composite_interval_stops.hpp>
-#include <mbgl/style/function/composite_categorical_stops.hpp>
-#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/range.hpp>
-#include <mbgl/util/variant.hpp>
-
-#include <string>
-#include <tuple>
-
-namespace mbgl {
-
-class GeometryTileFeature;
-
-namespace style {
-
-// A CompositeFunction consists of an outer zoom function whose stop range values are
-// "inner" source functions. It provides the GL Native implementation of
-// "zoom-and-property" functions from the style spec.
-
-template <class T>
-class CompositeFunction {
-public:
- using InnerStops = std::conditional_t<
- util::Interpolatable<T>::value,
- variant<
- ExponentialStops<T>,
- IntervalStops<T>,
- CategoricalStops<T>>,
- variant<
- IntervalStops<T>,
- CategoricalStops<T>>>;
-
- using Stops = std::conditional_t<
- util::Interpolatable<T>::value,
- variant<
- CompositeExponentialStops<T>,
- CompositeIntervalStops<T>,
- CompositeCategoricalStops<T>>,
- variant<
- CompositeIntervalStops<T>,
- CompositeCategoricalStops<T>>>;
-
- CompositeFunction(std::unique_ptr<expression::Expression> expression_)
- : isExpression(true),
- expression(std::move(expression_)),
- zoomCurve(expression::findZoomCurveChecked(expression.get()))
- {
- assert(!expression::isZoomConstant(*expression));
- assert(!expression::isFeatureConstant(*expression));
- }
-
- CompositeFunction(const std::string& property, const Stops& stops, optional<T> defaultValue_ = {})
- : isExpression(false),
- defaultValue(std::move(defaultValue_)),
- expression(stops.match([&] (const auto& s) {
- return expression::Convert::toExpression(property, s);
- })),
- zoomCurve(expression::findZoomCurveChecked(expression.get()))
- {}
-
- // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange
- template <class Feature>
- Range<T> evaluate(const Range<float>& zoomRange, const Feature& feature, T finalDefaultValue) {
- return Range<T> {
- evaluate(zoomRange.min, feature, finalDefaultValue),
- evaluate(zoomRange.max, feature, finalDefaultValue)
- };
- }
-
- template <class Feature>
- T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const {
- const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext({zoom}, &feature));
- if (result) {
- const optional<T> typed = expression::fromExpressionValue<T>(*result);
- return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue;
- }
- return defaultValue ? *defaultValue : finalDefaultValue;
- }
-
- float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const {
- return zoomCurve.match(
- [&](const expression::InterpolateBase* z) {
- return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue);
- },
- [&](const expression::Step*) { return 0.0f; }
- );
- }
-
- Range<float> getCoveringStops(const float lower, const float upper) const {
- return zoomCurve.match(
- [&](auto z) { return z->getCoveringStops(lower, upper); }
- );
- }
-
- std::vector<optional<T>> possibleOutputs() const {
- return expression::fromExpressionValues<T>(expression->possibleOutputs());
- }
-
- friend bool operator==(const CompositeFunction& lhs,
- const CompositeFunction& rhs) {
- return *lhs.expression == *rhs.expression;
- }
-
- const expression::Expression& getExpression() const { return *expression; }
-
- bool useIntegerZoom = false;
- bool isExpression;
-
-private:
- optional<T> defaultValue;
- std::shared_ptr<expression::Expression> expression;
- const variant<const expression::InterpolateBase*, const expression::Step*> zoomCurve;
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/composite_interval_stops.hpp b/include/mbgl/style/function/composite_interval_stops.hpp
deleted file mode 100644
index 3c495f2a7f..0000000000
--- a/include/mbgl/style/function/composite_interval_stops.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <mbgl/style/function/interval_stops.hpp>
-
-#include <map>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class CompositeIntervalStops {
-public:
- using Stops = std::map<float, std::map<float, T>>;
- Stops stops;
-
- CompositeIntervalStops() = default;
- CompositeIntervalStops(Stops stops_)
- : stops(std::move(stops_)) {
- }
-
- IntervalStops<T> innerStops(const std::map<float, T>& stops_) const {
- return IntervalStops<T>(stops_);
- }
-
- friend bool operator==(const CompositeIntervalStops& lhs,
- const CompositeIntervalStops& rhs) {
- return lhs.stops == rhs.stops;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/convert.hpp b/include/mbgl/style/function/convert.hpp
deleted file mode 100644
index 401a81d52e..0000000000
--- a/include/mbgl/style/function/convert.hpp
+++ /dev/null
@@ -1,356 +0,0 @@
-#pragma once
-
-#include <mbgl/style/expression/array_assertion.hpp>
-#include <mbgl/style/expression/assertion.hpp>
-#include <mbgl/style/expression/case.hpp>
-#include <mbgl/style/expression/coalesce.hpp>
-#include <mbgl/style/expression/compound_expression.hpp>
-#include <mbgl/style/expression/coercion.hpp>
-#include <mbgl/style/expression/interpolate.hpp>
-#include <mbgl/style/expression/expression.hpp>
-#include <mbgl/style/expression/literal.hpp>
-#include <mbgl/style/expression/match.hpp>
-#include <mbgl/style/expression/step.hpp>
-
-#include <mbgl/style/function/exponential_stops.hpp>
-#include <mbgl/style/function/interval_stops.hpp>
-#include <mbgl/style/function/categorical_stops.hpp>
-#include <mbgl/style/function/composite_exponential_stops.hpp>
-#include <mbgl/style/function/composite_interval_stops.hpp>
-#include <mbgl/style/function/composite_categorical_stops.hpp>
-#include <mbgl/style/function/identity_stops.hpp>
-
-#include <mbgl/util/enum.hpp>
-#include <mbgl/style/types.hpp>
-
-#include <string>
-
-
-namespace mbgl {
-namespace style {
-namespace expression {
-
-namespace detail {
-
-class ErrorExpression : public Expression {
-public:
- ErrorExpression(std::string message_) : Expression(type::Error), message(std::move(message_)) {}
- void eachChild(const std::function<void(const Expression&)>&) const override {}
-
- bool operator==(const Expression& e) const override {
- return dynamic_cast<const ErrorExpression*>(&e);
- }
-
- EvaluationResult evaluate(const EvaluationContext&) const override {
- return EvaluationError{message};
- }
-
- std::vector<optional<Value>> possibleOutputs() const override {
- return {};
- }
-
- std::string getOperator() const override { return "error"; }
-private:
- std::string message;
-};
-
-} // namespace detail
-
-
-// Create expressions representing 'classic' (i.e. stop-based) style functions
-
-struct Convert {
- template <typename T>
- static std::unique_ptr<Literal> makeLiteral(const T& value) {
- return std::make_unique<Literal>(Value(toExpressionValue(value)));
- }
-
- static std::unique_ptr<Expression> makeGet(type::Type type, const std::string& property) {
- ParsingContext ctx;
- std::vector<std::unique_ptr<Expression>> getArgs;
- getArgs.push_back(makeLiteral(property));
- ParseResult get = createCompoundExpression("get", std::move(getArgs), ctx);
- assert(get);
- assert(ctx.getErrors().size() == 0);
-
- std::vector<std::unique_ptr<Expression>> assertionArgs;
- assertionArgs.push_back(std::move(*get));
-
- return std::make_unique<Assertion>(type, std::move(assertionArgs));
- }
-
- static std::unique_ptr<Expression> makeZoom() {
- ParsingContext ctx;
- ParseResult zoom = createCompoundExpression("zoom", std::vector<std::unique_ptr<Expression>>(), ctx);
- assert(zoom);
- assert(ctx.getErrors().size() == 0);
- return std::move(*zoom);
- }
-
- static std::unique_ptr<Expression> makeError(std::string message) {
- return std::make_unique<detail::ErrorExpression>(message);
- }
-
- template <typename OutputType>
- static ParseResult makeInterpolate(type::Type type,
- std::unique_ptr<Expression> input,
- std::map<double, std::unique_ptr<Expression>> convertedStops,
- typename Interpolate<OutputType>::Interpolator interpolator)
- {
- ParseResult curve = ParseResult(std::make_unique<Interpolate<OutputType>>(
- std::move(type),
- std::move(interpolator),
- std::move(input),
- std::move(convertedStops)
- ));
- assert(curve);
- return std::move(*curve);
- }
-
- template <typename Key>
- static ParseResult makeMatch(type::Type type,
- std::unique_ptr<Expression> input,
- std::map<CategoricalValue, std::unique_ptr<Expression>> stops) {
- // match expression
- typename Match<Key>::Branches branches;
- for(auto it = stops.begin(); it != stops.end(); it++) {
- assert(it->first.template is<Key>());
- Key key = it->first.template get<Key>();
- branches.emplace(
- std::move(key),
- std::move(it->second)
- );
- }
-
- return ParseResult(std::make_unique<Match<Key>>(std::move(type),
- std::move(input),
- std::move(branches),
- makeError("No matching label")));
- }
-
- static ParseResult makeCase(type::Type type,
- std::unique_ptr<Expression> input,
- std::map<CategoricalValue, std::unique_ptr<Expression>> stops) {
- // case expression
- std::vector<typename Case::Branch> branches;
-
- auto it = stops.find(true);
- std::unique_ptr<Expression> true_case = it == stops.end() ?
- makeError("No matching label") :
- std::move(it->second);
-
- it = stops.find(false);
- std::unique_ptr<Expression> false_case = it == stops.end() ?
- makeError("No matching label") :
- std::move(it->second);
-
- branches.push_back(std::make_pair(std::move(input), std::move(true_case)));
- return ParseResult(std::make_unique<Case>(std::move(type), std::move(branches), std::move(false_case)));
- }
-
- template <typename T>
- static ParseResult fromCategoricalStops(std::map<CategoricalValue, T> stops, const std::string& property) {
- assert(stops.size() > 0);
-
- std::map<CategoricalValue, std::unique_ptr<Expression>> convertedStops;
- for(const std::pair<CategoricalValue, T>& stop : stops) {
- convertedStops.emplace(
- stop.first,
- makeLiteral(stop.second)
- );
- }
-
- type::Type type = valueTypeToExpressionType<T>();
-
- const CategoricalValue& firstKey = stops.begin()->first;
- return firstKey.match(
- [&](bool) {
- return makeCase(type, makeGet(type::Boolean, property), std::move(convertedStops));
- },
- [&](const std::string&) {
- return makeMatch<std::string>(type, makeGet(type::String, property), std::move(convertedStops));
- },
- [&](int64_t) {
- return makeMatch<int64_t>(type, makeGet(type::Number, property), std::move(convertedStops));
- }
- );
- }
-
- template <typename T>
- static std::map<double, std::unique_ptr<Expression>> convertStops(const std::map<float, T>& stops) {
- std::map<double, std::unique_ptr<Expression>> convertedStops;
- for(const auto& stop : stops) {
- convertedStops.emplace(
- stop.first,
- makeLiteral(stop.second)
- );
- }
- return convertedStops;
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const ExponentialStops<T>& stops)
- {
- ParseResult e = makeInterpolate<typename ValueConverter<T>::ExpressionType>(
- valueTypeToExpressionType<T>(),
- makeZoom(),
- convertStops(stops.stops),
- ExponentialInterpolator(stops.base));
- assert(e);
- return std::move(*e);
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const IntervalStops<T>& stops)
- {
- ParseResult e(std::make_unique<Step>(valueTypeToExpressionType<T>(),
- makeZoom(),
- convertStops(stops.stops)));
- assert(e);
- return std::move(*e);
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const std::string& property,
- const ExponentialStops<T>& stops)
- {
- ParseResult e = makeInterpolate<typename ValueConverter<T>::ExpressionType>(valueTypeToExpressionType<T>(),
- makeGet(type::Number, property),
- convertStops(stops.stops),
- ExponentialInterpolator(stops.base));
- assert(e);
- return std::move(*e);
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const std::string& property,
- const IntervalStops<T>& stops)
- {
- std::unique_ptr<Expression> get = makeGet(type::Number, property);
- ParseResult e(std::make_unique<Step>(valueTypeToExpressionType<T>(),
- std::move(get),
- convertStops(stops.stops)));
- assert(e);
- return std::move(*e);
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const std::string& property,
- const CategoricalStops<T>& stops)
- {
- ParseResult expr = fromCategoricalStops(stops.stops, property);
- assert(expr);
- return std::move(*expr);
- }
-
- // interpolatable zoom curve
- template <typename T>
- static typename std::enable_if_t<util::Interpolatable<T>::value,
- ParseResult> makeZoomCurve(std::map<double, std::unique_ptr<Expression>> stops) {
- return makeInterpolate<typename ValueConverter<T>::ExpressionType>(valueTypeToExpressionType<T>(),
- makeZoom(),
- std::move(stops),
- ExponentialInterpolator(1.0));
- }
-
- // non-interpolatable zoom curve
- template <typename T>
- static typename std::enable_if_t<!util::Interpolatable<T>::value,
- ParseResult> makeZoomCurve(std::map<double, std::unique_ptr<Expression>> stops) {
- return ParseResult(std::make_unique<Step>(valueTypeToExpressionType<T>(), makeZoom(), std::move(stops)));
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const std::string& property,
- const CompositeExponentialStops<T>& stops)
- {
- std::map<double, std::unique_ptr<Expression>> outerStops;
- for (const std::pair<float, std::map<float, T>>& stop : stops.stops) {
- std::unique_ptr<Expression> get = makeGet(type::Number, property);
- ParseResult innerInterpolate = makeInterpolate<typename ValueConverter<T>::ExpressionType>(valueTypeToExpressionType<T>(),
- std::move(get),
- convertStops(stop.second),
- ExponentialInterpolator(stops.base));
- assert(innerInterpolate);
- outerStops.emplace(stop.first, std::move(*innerInterpolate));
- }
-
- ParseResult zoomCurve = makeZoomCurve<T>(std::move(outerStops));
- assert(zoomCurve);
- return std::move(*zoomCurve);
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const std::string& property,
- const CompositeIntervalStops<T>& stops)
- {
- std::map<double, std::unique_ptr<Expression>> outerStops;
- for (const std::pair<float, std::map<float, T>>& stop : stops.stops) {
- std::unique_ptr<Expression> get = makeGet(type::Number, property);
- ParseResult innerInterpolate(std::make_unique<Step>(valueTypeToExpressionType<T>(),
- std::move(get),
- convertStops(stop.second)));
- assert(innerInterpolate);
- outerStops.emplace(stop.first, std::move(*innerInterpolate));
- }
-
- ParseResult zoomCurve = makeZoomCurve<T>(std::move(outerStops));
- assert(zoomCurve);
- return std::move(*zoomCurve);
- }
-
- template <typename T>
- static std::unique_ptr<Expression> toExpression(const std::string& property,
- const CompositeCategoricalStops<T>& stops)
- {
- std::map<double, std::unique_ptr<Expression>> outerStops;
- for (const std::pair<float, std::map<CategoricalValue, T>>& stop : stops.stops) {
- ParseResult innerInterpolate = fromCategoricalStops(stop.second, property);
- assert(innerInterpolate);
- outerStops.emplace(stop.first, std::move(*innerInterpolate));
- }
-
- ParseResult zoomCurve = makeZoomCurve<T>(std::move(outerStops));
- assert(zoomCurve);
- return std::move(*zoomCurve);
- }
-
-
- static std::unique_ptr<Expression> fromIdentityFunction(type::Type type, const std::string& property)
- {
- std::unique_ptr<Expression> input = type.match(
- [&] (const type::StringType&) {
- return makeGet(type::String, property);
- },
- [&] (const type::NumberType&) {
- return makeGet(type::Number, property);
- },
- [&] (const type::BooleanType&) {
- return makeGet(type::Boolean, property);
- },
- [&] (const type::ColorType&) {
- std::vector<std::unique_ptr<Expression>> args;
- args.push_back(makeGet(type::String, property));
- return std::make_unique<Coercion>(type::Color, std::move(args));
- },
- [&] (const type::Array& arr) {
- std::vector<std::unique_ptr<Expression>> getArgs;
- getArgs.push_back(makeLiteral(property));
- ParsingContext ctx;
- ParseResult get = createCompoundExpression("get", std::move(getArgs), ctx);
- assert(get);
- assert(ctx.getErrors().size() == 0);
- return std::make_unique<ArrayAssertion>(arr, std::move(*get));
- },
- [&] (const auto&) -> std::unique_ptr<Expression> {
- return makeLiteral(Null);
- }
- );
-
- return input;
- }
-};
-
-} // namespace expression
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/exponential_stops.hpp b/include/mbgl/style/function/exponential_stops.hpp
deleted file mode 100644
index b3866c4059..0000000000
--- a/include/mbgl/style/function/exponential_stops.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-#include <mbgl/util/feature.hpp>
-#include <mbgl/util/interpolate.hpp>
-
-#include <map>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class ExponentialStops {
-public:
- using Stops = std::map<float, T>;
-
- Stops stops;
- float base = 1.0f;
-
- ExponentialStops() = default;
- ExponentialStops(Stops stops_, float base_ = 1.0f)
- : stops(std::move(stops_)),
- base(base_) {
- }
-
- optional<T> evaluate(float z) const {
- if (stops.empty()) {
- return {};
- }
-
- auto it = stops.upper_bound(z);
- if (it == stops.end()) {
- return stops.rbegin()->second;
- } else if (it == stops.begin()) {
- return stops.begin()->second;
- } else {
- return util::interpolate(std::prev(it)->second, it->second,
- util::interpolationFactor(base, { std::prev(it)->first, it->first }, z));
- }
- }
-
- optional<T> evaluate(const Value& value) const {
- optional<float> z = numericValue<float>(value);
- if (!z) {
- return {};
- }
- return evaluate(*z);
- }
-
- friend bool operator==(const ExponentialStops& lhs,
- const ExponentialStops& rhs) {
- return lhs.stops == rhs.stops && lhs.base == rhs.base;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/identity_stops.hpp b/include/mbgl/style/function/identity_stops.hpp
deleted file mode 100644
index 741ebbbe0c..0000000000
--- a/include/mbgl/style/function/identity_stops.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/util/feature.hpp>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class IdentityStops {
-public:
- optional<T> evaluate(const Value&) const;
-
- friend bool operator==(const IdentityStops&,
- const IdentityStops&) {
- return true;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/interval_stops.hpp b/include/mbgl/style/function/interval_stops.hpp
deleted file mode 100644
index 45e2dc6f2e..0000000000
--- a/include/mbgl/style/function/interval_stops.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <mbgl/util/feature.hpp>
-
-#include <map>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class IntervalStops {
-public:
- using Stops = std::map<float, T>;
- Stops stops;
-
- IntervalStops() = default;
- IntervalStops(Stops stops_)
- : stops(std::move(stops_)) {
- }
-
- optional<T> evaluate(float z) const {
- if (stops.empty()) {
- return {};
- }
-
- auto it = stops.upper_bound(z);
- if (it == stops.end()) {
- return stops.rbegin()->second;
- } else if (it == stops.begin()) {
- return stops.begin()->second;
- } else {
- return std::prev(it)->second;
- }
- }
-
- optional<T> evaluate(const Value& value) const {
- optional<float> z = numericValue<float>(value);
- if (!z) {
- return {};
- }
- return evaluate(*z);
- }
-
- friend bool operator==(const IntervalStops& lhs,
- const IntervalStops& rhs) {
- return lhs.stops == rhs.stops;
- }
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/function/source_function.hpp b/include/mbgl/style/function/source_function.hpp
deleted file mode 100644
index 5b51d0bf81..0000000000
--- a/include/mbgl/style/function/source_function.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#pragma once
-
-#include <mbgl/style/expression/is_constant.hpp>
-#include <mbgl/style/function/convert.hpp>
-#include <mbgl/style/function/exponential_stops.hpp>
-#include <mbgl/style/function/interval_stops.hpp>
-#include <mbgl/style/function/categorical_stops.hpp>
-#include <mbgl/style/function/identity_stops.hpp>
-#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/variant.hpp>
-
-#include <string>
-
-namespace mbgl {
-namespace style {
-
-template <class T>
-class SourceFunction {
-public:
- using Stops = std::conditional_t<
- util::Interpolatable<T>::value,
- variant<
- ExponentialStops<T>,
- IntervalStops<T>,
- CategoricalStops<T>,
- IdentityStops<T>>,
- variant<
- IntervalStops<T>,
- CategoricalStops<T>,
- IdentityStops<T>>>;
-
- SourceFunction(std::unique_ptr<expression::Expression> expression_)
- : isExpression(true),
- expression(std::move(expression_))
- {
- assert(expression::isZoomConstant(*expression));
- assert(!expression::isFeatureConstant(*expression));
- }
-
- SourceFunction(const std::string& property, const Stops& stops, optional<T> defaultValue_ = {})
- : isExpression(false),
- defaultValue(std::move(defaultValue_)),
- expression(stops.match([&] (const IdentityStops<T>&) {
- return expression::Convert::fromIdentityFunction(expression::valueTypeToExpressionType<T>(), property);
- }, [&] (const auto& s) {
- return expression::Convert::toExpression(property, s);
- }))
- {}
-
- template <class Feature>
- T evaluate(const Feature& feature, T finalDefaultValue) const {
- const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(&feature));
- if (result) {
- const optional<T> typed = expression::fromExpressionValue<T>(*result);
- return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue;
- }
- return defaultValue ? *defaultValue : finalDefaultValue;
- }
-
- std::vector<optional<T>> possibleOutputs() const {
- return expression::fromExpressionValues<T>(expression->possibleOutputs());
- }
-
- friend bool operator==(const SourceFunction& lhs,
- const SourceFunction& rhs) {
- return *lhs.expression == *rhs.expression;
- }
-
- bool useIntegerZoom = false;
- bool isExpression;
-
- const expression::Expression& getExpression() const { return *expression; }
-
-private:
- optional<T> defaultValue;
- std::shared_ptr<expression::Expression> expression;
-};
-
-} // namespace style
-} // namespace mbgl
diff --git a/include/mbgl/style/layers/heatmap_layer.hpp b/include/mbgl/style/layers/heatmap_layer.hpp
index 33d927ad38..4c434b2aff 100644
--- a/include/mbgl/style/layers/heatmap_layer.hpp
+++ b/include/mbgl/style/layers/heatmap_layer.hpp
@@ -2,11 +2,11 @@
#pragma once
+#include <mbgl/style/color_ramp_property_value.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/data_driven_property_value.hpp>
-#include <mbgl/style/heatmap_color_property_value.hpp>
#include <mbgl/util/color.hpp>
@@ -55,9 +55,9 @@ public:
void setHeatmapIntensityTransition(const TransitionOptions&);
TransitionOptions getHeatmapIntensityTransition() const;
- static HeatmapColorPropertyValue getDefaultHeatmapColor();
- HeatmapColorPropertyValue getHeatmapColor() const;
- void setHeatmapColor(HeatmapColorPropertyValue);
+ static ColorRampPropertyValue getDefaultHeatmapColor();
+ ColorRampPropertyValue getHeatmapColor() const;
+ void setHeatmapColor(ColorRampPropertyValue);
void setHeatmapColorTransition(const TransitionOptions&);
TransitionOptions getHeatmapColorTransition() const;
diff --git a/include/mbgl/style/layers/layer.hpp.ejs b/include/mbgl/style/layers/layer.hpp.ejs
new file mode 100644
index 0000000000..e15ff74f17
--- /dev/null
+++ b/include/mbgl/style/layers/layer.hpp.ejs
@@ -0,0 +1,93 @@
+<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Do not edit.
+
+#pragma once
+
+<% if (type === 'heatmap') { -%>
+#include <mbgl/style/color_ramp_property_value.hpp>
+<% } -%>
+#include <mbgl/style/layer.hpp>
+#include <mbgl/style/filter.hpp>
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/data_driven_property_value.hpp>
+
+#include <mbgl/util/color.hpp>
+
+<% if (type === 'line' || type === 'symbol') { -%>
+#include <vector>
+
+<% } -%>
+namespace mbgl {
+namespace style {
+
+class TransitionOptions;
+
+class <%- camelize(type) %>Layer : public Layer {
+public:
+<% if (type === 'background') { -%>
+ <%- camelize(type) %>Layer(const std::string& layerID);
+<% } else { -%>
+ <%- camelize(type) %>Layer(const std::string& layerID, const std::string& sourceID);
+<% } -%>
+ ~<%- camelize(type) %>Layer() final;
+
+<% if (type !== 'background') { -%>
+ // Source
+ const std::string& getSourceID() const;
+<% if (type !== 'raster' && type !== 'hillshade') { -%>
+ const std::string& getSourceLayer() const;
+ void setSourceLayer(const std::string& sourceLayer);
+
+ void setFilter(const Filter&);
+ const Filter& getFilter() const;
+<% } -%>
+
+<% } -%>
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
+<% if (layoutProperties.length) { -%>
+ // Layout properties
+
+<% for (const property of layoutProperties) { -%>
+ static <%- propertyValueType(property) %> getDefault<%- camelize(property.name) %>();
+ <%- propertyValueType(property) %> get<%- camelize(property.name) %>() const;
+ void set<%- camelize(property.name) %>(<%- propertyValueType(property) %>);
+
+<% } -%>
+<% } -%>
+ // Paint properties
+
+<% for (const property of paintProperties) { -%>
+ static <%- propertyValueType(property) %> getDefault<%- camelize(property.name) %>();
+ <%- propertyValueType(property) %> get<%- camelize(property.name) %>() const;
+ void set<%- camelize(property.name) %>(<%- propertyValueType(property) %>);
+ void set<%- camelize(property.name) %>Transition(const TransitionOptions&);
+ TransitionOptions get<%- camelize(property.name) %>Transition() const;
+
+<% } -%>
+ // Private implementation
+
+ class Impl;
+ const Impl& impl() const;
+
+ Mutable<Impl> mutableImpl() const;
+ <%- camelize(type) %>Layer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
+};
+
+template <>
+inline bool Layer::is<<%- camelize(type) %>Layer>() const {
+ return getType() == LayerType::<%- camelize(type) %>;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/layers/raster_layer.hpp b/include/mbgl/style/layers/raster_layer.hpp
index 8111364709..8e7849c27d 100644
--- a/include/mbgl/style/layers/raster_layer.hpp
+++ b/include/mbgl/style/layers/raster_layer.hpp
@@ -67,6 +67,12 @@ public:
void setRasterContrastTransition(const TransitionOptions&);
TransitionOptions getRasterContrastTransition() const;
+ static PropertyValue<RasterResamplingType> getDefaultRasterResampling();
+ PropertyValue<RasterResamplingType> getRasterResampling() const;
+ void setRasterResampling(PropertyValue<RasterResamplingType>);
+ void setRasterResamplingTransition(const TransitionOptions&);
+ TransitionOptions getRasterResamplingTransition() const;
+
static PropertyValue<float> getDefaultRasterFadeDuration();
PropertyValue<float> getRasterFadeDuration() const;
void setRasterFadeDuration(PropertyValue<float>);
diff --git a/include/mbgl/style/light.hpp.ejs b/include/mbgl/style/light.hpp.ejs
new file mode 100644
index 0000000000..adc5b651e3
--- /dev/null
+++ b/include/mbgl/style/light.hpp.ejs
@@ -0,0 +1,40 @@
+<%
+ const properties = locals.properties;
+-%>
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/transition_options.hpp>
+#include <mbgl/style/types.hpp>
+#include <mbgl/util/immutable.hpp>
+
+namespace mbgl {
+namespace style {
+
+class LightObserver;
+
+class Light {
+public:
+ Light();
+ ~Light();
+
+<% for (const property of properties) { -%>
+ static <%- evaluatedType(property) %> getDefault<%- camelize(property.name) %>();
+ <%- propertyValueType(property) %> get<%- camelize(property.name) %>() const;
+ void set<%- camelize(property.name) %>(<%- propertyValueType(property) %>);
+ void set<%- camelize(property.name) %>Transition(const TransitionOptions&);
+ TransitionOptions get<%- camelize(property.name) %>Transition() const;
+
+<% } -%>
+ class Impl;
+ Immutable<Impl> impl;
+ Mutable<Impl> mutableImpl() const;
+
+ LightObserver* observer = nullptr;
+ void setObserver(LightObserver*);
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/property_expression.hpp b/include/mbgl/style/property_expression.hpp
new file mode 100644
index 0000000000..b198de02b2
--- /dev/null
+++ b/include/mbgl/style/property_expression.hpp
@@ -0,0 +1,117 @@
+#pragma once
+
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/expression/value.hpp>
+#include <mbgl/style/expression/is_constant.hpp>
+#include <mbgl/style/expression/interpolate.hpp>
+#include <mbgl/style/expression/step.hpp>
+#include <mbgl/style/expression/find_zoom_curve.hpp>
+#include <mbgl/util/range.hpp>
+
+namespace mbgl {
+namespace style {
+
+template <class T>
+class PropertyExpression {
+public:
+ // Second parameter to be used only for conversions from legacy functions.
+ PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {})
+ : expression(std::move(expression_)),
+ defaultValue(std::move(defaultValue_)),
+ zoomCurve(expression::findZoomCurveChecked(expression.get())) {
+ }
+
+ bool isZoomConstant() const { return expression::isZoomConstant(*expression); }
+ bool isFeatureConstant() const { return expression::isFeatureConstant(*expression); }
+
+ T evaluate(float zoom) const {
+ assert(!expression::isZoomConstant(*expression));
+ assert(expression::isFeatureConstant(*expression));
+ const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr));
+ if (result) {
+ const optional<T> typed = expression::fromExpressionValue<T>(*result);
+ return typed ? *typed : defaultValue ? *defaultValue : T();
+ }
+ return defaultValue ? *defaultValue : T();
+ }
+
+ template <class Feature>
+ T evaluate(const Feature& feature, T finalDefaultValue) const {
+ assert(expression::isZoomConstant(*expression));
+ assert(!expression::isFeatureConstant(*expression));
+ const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(&feature));
+ if (result) {
+ const optional<T> typed = expression::fromExpressionValue<T>(*result);
+ return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue;
+ }
+ return defaultValue ? *defaultValue : finalDefaultValue;
+ }
+
+ template <class Feature>
+ T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const {
+ assert(!expression::isFeatureConstant(*expression));
+ const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext({zoom}, &feature));
+ if (result) {
+ const optional<T> typed = expression::fromExpressionValue<T>(*result);
+ return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue;
+ }
+ return defaultValue ? *defaultValue : finalDefaultValue;
+ }
+
+ float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const {
+ return zoomCurve.match(
+ [](std::nullptr_t) {
+ assert(false);
+ return 0.0f;
+ },
+ [&](const expression::Interpolate* z) {
+ return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue);
+ },
+ [&](const expression::Step*) {
+ return 0.0f;
+ }
+ );
+ }
+
+ Range<float> getCoveringStops(const float lower, const float upper) const {
+ return zoomCurve.match(
+ [](std::nullptr_t) {
+ assert(false);
+ return Range<float>(0.0f, 0.0f);
+ },
+ [&](auto z) {
+ return z->getCoveringStops(lower, upper);
+ }
+ );
+ }
+
+ // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange
+ template <class Feature>
+ Range<T> evaluate(const Range<float>& zoomRange, const Feature& feature, T finalDefaultValue) {
+ return Range<T> {
+ evaluate(zoomRange.min, feature, finalDefaultValue),
+ evaluate(zoomRange.max, feature, finalDefaultValue)
+ };
+ }
+
+ std::vector<optional<T>> possibleOutputs() const {
+ return expression::fromExpressionValues<T>(expression->possibleOutputs());
+ }
+
+ const expression::Expression& getExpression() const { return *expression; }
+
+ bool useIntegerZoom = false;
+
+ friend bool operator==(const PropertyExpression& lhs,
+ const PropertyExpression& rhs) {
+ return *lhs.expression == *rhs.expression;
+ }
+
+private:
+ std::shared_ptr<const expression::Expression> expression;
+ optional<T> defaultValue;
+ variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp
index 02d3a31148..1b0f3d2ab0 100644
--- a/include/mbgl/style/property_value.hpp
+++ b/include/mbgl/style/property_value.hpp
@@ -2,7 +2,7 @@
#include <mbgl/util/variant.hpp>
#include <mbgl/style/undefined.hpp>
-#include <mbgl/style/function/camera_function.hpp>
+#include <mbgl/style/property_expression.hpp>
namespace mbgl {
namespace style {
@@ -10,7 +10,7 @@ namespace style {
template <class T>
class PropertyValue {
private:
- using Value = variant<Undefined, T, CameraFunction<T>>;
+ using Value = variant<Undefined, T, PropertyExpression<T>>;
Value value;
friend bool operator==(const PropertyValue& lhs, const PropertyValue& rhs) {
@@ -22,17 +22,24 @@ private:
}
public:
- PropertyValue() : value() {}
- PropertyValue( T constant) : value(constant) {}
- PropertyValue(CameraFunction<T> function) : value(function) {}
+ PropertyValue()
+ : value() {}
+
+ PropertyValue(T constant)
+ : value(constant) {}
+
+ PropertyValue(PropertyExpression<T> expression)
+ : value(expression) {
+ assert(expression.isFeatureConstant());
+ }
bool isUndefined() const { return value.which() == 0; }
bool isConstant() const { return value.which() == 1; }
- bool isCameraFunction() const { return value.which() == 2; }
+ bool isExpression() const { return value.which() == 2; }
bool isDataDriven() const { return false; }
- const T & asConstant() const { return value.template get< T >(); }
- const CameraFunction<T>& asCameraFunction() const { return value.template get<CameraFunction<T>>(); }
+ const T & asConstant() const { return value.template get< T >(); }
+ const PropertyExpression<T>& asExpression() const { return value.template get<PropertyExpression<T>>(); }
template <typename Evaluator>
auto evaluate(const Evaluator& evaluator, TimePoint = {}) const {
diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp
index 693972a72f..805cff118c 100644
--- a/include/mbgl/style/types.hpp
+++ b/include/mbgl/style/types.hpp
@@ -38,6 +38,11 @@ enum class LineJoinType : uint8_t {
FlipBevel
};
+enum class RasterResamplingType : bool {
+ Linear,
+ Nearest
+};
+
enum class HillshadeIlluminationAnchorType : bool {
Map,
Viewport
@@ -58,9 +63,10 @@ enum class CirclePitchScaleType : bool {
Viewport,
};
-enum class SymbolPlacementType : bool {
+enum class SymbolPlacementType : uint8_t {
Point,
Line,
+ LineCenter
};
enum class AlignmentType : uint8_t {
diff --git a/include/mbgl/tile/tile_id.hpp b/include/mbgl/tile/tile_id.hpp
index 11fb5ce537..dd2fba573d 100644
--- a/include/mbgl/tile/tile_id.hpp
+++ b/include/mbgl/tile/tile_id.hpp
@@ -58,10 +58,11 @@ public:
uint32_t overscaleFactor() const;
OverscaledTileID scaledTo(uint8_t z) const;
UnwrappedTileID toUnwrapped() const;
+ OverscaledTileID unwrapTo(int16_t wrap);
- const uint8_t overscaledZ;
- const int16_t wrap;
- const CanonicalTileID canonical;
+ uint8_t overscaledZ;
+ int16_t wrap;
+ CanonicalTileID canonical;
};
::std::ostream& operator<<(::std::ostream& os, const OverscaledTileID& rhs);
@@ -84,9 +85,10 @@ public:
std::array<UnwrappedTileID, 4> children() const;
OverscaledTileID overscaleTo(uint8_t z) const;
float pixelsToTileUnits(float pixelValue, float zoom) const;
+ UnwrappedTileID unwrapTo(int16_t wrap);
- const int16_t wrap;
- const CanonicalTileID canonical;
+ int16_t wrap;
+ CanonicalTileID canonical;
};
::std::ostream& operator<<(::std::ostream& os, const UnwrappedTileID& rhs);
@@ -191,6 +193,10 @@ inline UnwrappedTileID OverscaledTileID::toUnwrapped() const {
return { wrap, canonical };
}
+inline OverscaledTileID OverscaledTileID::unwrapTo(int16_t newWrap) {
+ return { overscaledZ, newWrap, canonical };
+}
+
inline UnwrappedTileID::UnwrappedTileID(uint8_t z_, int64_t x_, int64_t y_)
: wrap((x_ < 0 ? x_ - (1ll << z_) + 1 : x_) / (1ll << z_)),
canonical(
@@ -215,6 +221,10 @@ inline bool UnwrappedTileID::operator<(const UnwrappedTileID& rhs) const {
return std::tie(wrap, canonical) < std::tie(rhs.wrap, rhs.canonical);
}
+inline UnwrappedTileID UnwrappedTileID::unwrapTo(int16_t newWrap) {
+ return { newWrap, canonical };
+}
+
inline bool UnwrappedTileID::isChildOf(const UnwrappedTileID& parent) const {
return wrap == parent.wrap && canonical.isChildOf(parent.canonical);
}
diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp
index d5e55065c4..7110d9e26b 100644
--- a/include/mbgl/util/constants.hpp
+++ b/include/mbgl/util/constants.hpp
@@ -11,7 +11,7 @@ namespace mbgl {
namespace util {
-constexpr float tileSize = 512;
+constexpr double tileSize = 512;
/*
* The maximum extent of a feature that can be safely stored in the buffer.
diff --git a/include/mbgl/util/event.hpp b/include/mbgl/util/event.hpp
index 5fe0baae3c..15583e956d 100644
--- a/include/mbgl/util/event.hpp
+++ b/include/mbgl/util/event.hpp
@@ -28,6 +28,7 @@ enum class Event : uint8_t {
Android,
Crash,
Glyph,
+ Timing
};
struct EventPermutation {
diff --git a/include/mbgl/util/logging.hpp b/include/mbgl/util/logging.hpp
index d072673e76..03db2d7462 100644
--- a/include/mbgl/util/logging.hpp
+++ b/include/mbgl/util/logging.hpp
@@ -67,8 +67,8 @@ public:
private:
static void record(EventSeverity severity, Event event, const std::string &msg);
- static void record(EventSeverity severity, Event event, const char* format, ...);
- static void record(EventSeverity severity, Event event, int64_t code);
+ static void record(EventSeverity severity, Event event, const char* format = "", ...);
+ static void record(EventSeverity severity, Event event, int64_t code, const char* format = "", ...);
static void record(EventSeverity severity, Event event, int64_t code, const std::string &msg);
// This method is the data sink that must be implemented by each platform we
diff --git a/include/mbgl/util/projection.hpp b/include/mbgl/util/projection.hpp
index 65a84d8dc2..9619a380b4 100644
--- a/include/mbgl/util/projection.hpp
+++ b/include/mbgl/util/projection.hpp
@@ -94,9 +94,10 @@ public:
private:
static Point<double> project_(const LatLng& latLng, double worldSize) {
+ const double latitude = util::clamp(latLng.latitude(), -util::LATITUDE_MAX, util::LATITUDE_MAX);
return Point<double> {
util::LONGITUDE_MAX + latLng.longitude(),
- util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + latLng.latitude() * M_PI / util::DEGREES_MAX))
+ util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + latitude * M_PI / util::DEGREES_MAX))
} * worldSize / util::DEGREES_MAX;
}
};
diff --git a/include/mbgl/util/thread.hpp b/include/mbgl/util/thread.hpp
index 74e722b02d..bc58427349 100644
--- a/include/mbgl/util/thread.hpp
+++ b/include/mbgl/util/thread.hpp
@@ -37,45 +37,55 @@ namespace util {
// - `Object` can use `Timer` and do asynchronous I/O, like wait for sockets events.
//
template<class Object>
-class Thread : public Scheduler {
+class Thread {
public:
template <class... Args>
Thread(const std::string& name, Args&&... args) {
- std::promise<void> running;
- thread = std::thread([&] {
+ std::promise<void> running_;
+ running = running_.get_future();
+
+ auto capturedArgs = std::make_tuple(std::forward<Args>(args)...);
+
+ thread = std::thread([
+ this,
+ name,
+ capturedArgs = std::move(capturedArgs),
+ runningPromise = std::move(running_)
+ ] () mutable {
platform::setCurrentThreadName(name);
platform::makeThreadLowPriority();
util::RunLoop loop_(util::RunLoop::Type::New);
loop = &loop_;
+ EstablishedActor<Object> establishedActor(loop_, object, std::move(capturedArgs));
- object = std::make_unique<Actor<Object>>(*this, std::forward<Args>(args)...);
- running.set_value();
-
+ runningPromise.set_value();
+
loop->run();
+
+ (void) establishedActor;
+
loop = nullptr;
});
-
- running.get_future().get();
}
- ~Thread() override {
+ ~Thread() {
if (paused) {
resume();
}
- std::promise<void> joinable;
+ std::promise<void> stoppable;
+
+ running.wait();
- // Kill the actor, so we don't get more
- // messages posted on this scheduler after
- // we delete the RunLoop.
+ // Invoke a noop task on the run loop to ensure that we're executing
+ // run() before we call stop()
loop->invoke([&] {
- object.reset();
- joinable.set_value();
+ stoppable.set_value();
});
- joinable.get_future().get();
+ stoppable.get_future().get();
loop->stop();
thread.join();
@@ -85,8 +95,8 @@ public:
// can be used to send messages to `Object`. It is safe
// to the non-owning reference to outlive this object
// and be used after the `Thread<>` gets destroyed.
- ActorRef<std::decay_t<Object>> actor() const {
- return object->self();
+ ActorRef<std::decay_t<Object>> actor() {
+ return object.self();
}
// Pauses the `Object` thread. It will prevent the object to wake
@@ -103,6 +113,8 @@ public:
auto pausing = paused->get_future();
+ running.wait();
+
loop->invoke(RunLoop::Priority::High, [this] {
auto resuming = resumed->get_future();
paused->set_value();
@@ -127,13 +139,12 @@ public:
private:
MBGL_STORE_THREAD(tid);
- void schedule(std::weak_ptr<Mailbox> mailbox) override {
- loop->schedule(mailbox);
- }
+ AspiringActor<Object> object;
std::thread thread;
- std::unique_ptr<Actor<Object>> object;
+ std::future<void> running;
+
std::unique_ptr<std::promise<void>> paused;
std::unique_ptr<std::promise<void>> resumed;
diff --git a/include/mbgl/util/unique_any.hpp b/include/mbgl/util/unique_any.hpp
index d488930a03..c7dc8b38ea 100644
--- a/include/mbgl/util/unique_any.hpp
+++ b/include/mbgl/util/unique_any.hpp
@@ -135,15 +135,12 @@ private:
template <typename ValueType>
struct VTableHeap : public VTable {
void move(Storage&& src, Storage& dest) override {
- destroy(dest);
dest.dynamic = src.dynamic;
+ src.dynamic = nullptr;
}
void destroy(Storage& s) override {
- if (s.dynamic) {
- delete reinterpret_cast<ValueType*>(s.dynamic);
- }
- s.dynamic = nullptr;
+ delete reinterpret_cast<ValueType*>(s.dynamic);
}
const std::type_info& type() override {
@@ -154,9 +151,8 @@ private:
template <typename ValueType>
struct VTableStack : public VTable {
void move(Storage&& src, Storage& dest) override {
- auto srcValue = reinterpret_cast<ValueType&&>(src.stack);
- new (static_cast<void*>(&dest.stack)) ValueType(std::move(srcValue));
- srcValue.~ValueType();
+ new (&dest.stack) ValueType(std::move(reinterpret_cast<ValueType&>(src.stack)));
+ destroy(src);
}
void destroy(Storage& s) override {
@@ -178,13 +174,13 @@ private:
template <typename ValueType, typename _Vt>
std::enable_if_t<AllocateOnStack<_Vt>::value>
createStorage(ValueType&& value) {
- new (static_cast<void*>(&storage.stack)) _Vt(std::forward<ValueType>(value));
+ new (&storage.stack) _Vt(std::forward<ValueType>(value));
}
template <typename ValueType, typename _Vt>
std::enable_if_t<!AllocateOnStack<_Vt>::value>
createStorage(ValueType&& value) {
- storage.dynamic = static_cast<void*>(new _Vt(std::forward<ValueType>(value)));
+ storage.dynamic = new _Vt(std::forward<ValueType>(value));
}
template <typename ValueType>
diff --git a/mapbox-gl-native.pro b/mapbox-gl-native.pro
index a05699f4a3..2f499b6ec5 100644
--- a/mapbox-gl-native.pro
+++ b/mapbox-gl-native.pro
@@ -70,6 +70,7 @@ SOURCES += \
platform/qt/src/qmapboxgl_map_observer.cpp \
platform/qt/src/qmapboxgl_map_renderer.cpp \
platform/qt/src/qmapboxgl_renderer_backend.cpp \
+ platform/qt/src/qmapboxgl_scheduler.cpp \
platform/qt/src/qt_geojson.cpp \
platform/qt/src/qt_image.cpp \
platform/qt/src/qt_logging.cpp \
@@ -196,6 +197,7 @@ SOURCES += \
src/mbgl/shaders/preludes.cpp \
src/mbgl/shaders/raster.cpp \
src/mbgl/shaders/shaders.cpp \
+ src/mbgl/shaders/source.cpp \
src/mbgl/shaders/symbol_icon.cpp \
src/mbgl/shaders/symbol_sdf.cpp \
src/mbgl/sprite/sprite_loader.cpp \
@@ -208,6 +210,7 @@ SOURCES += \
src/mbgl/style/conversion/constant.cpp \
src/mbgl/style/conversion/coordinate.cpp \
src/mbgl/style/conversion/filter.cpp \
+ src/mbgl/style/conversion/function.cpp \
src/mbgl/style/conversion/geojson.cpp \
src/mbgl/style/conversion/geojson_options.cpp \
src/mbgl/style/conversion/get_json_type.cpp \
@@ -226,8 +229,11 @@ SOURCES += \
src/mbgl/style/expression/check_subtype.cpp \
src/mbgl/style/expression/coalesce.cpp \
src/mbgl/style/expression/coercion.cpp \
+ src/mbgl/style/expression/collator_expression.cpp \
src/mbgl/style/expression/compound_expression.cpp \
+ src/mbgl/style/expression/dsl.cpp \
src/mbgl/style/expression/equals.cpp \
+ src/mbgl/style/expression/expression.cpp \
src/mbgl/style/expression/find_zoom_curve.cpp \
src/mbgl/style/expression/get_covering_stops.cpp \
src/mbgl/style/expression/interpolate.cpp \
@@ -242,10 +248,6 @@ SOURCES += \
src/mbgl/style/expression/util.cpp \
src/mbgl/style/expression/value.cpp \
src/mbgl/style/filter.cpp \
- src/mbgl/style/filter_evaluator.cpp \
- src/mbgl/style/function/categorical_stops.cpp \
- src/mbgl/style/function/expression.cpp \
- src/mbgl/style/function/identity_stops.cpp \
src/mbgl/style/image.cpp \
src/mbgl/style/image_impl.cpp \
src/mbgl/style/layer.cpp \
@@ -307,6 +309,7 @@ SOURCES += \
src/mbgl/text/glyph_atlas.cpp \
src/mbgl/text/glyph_manager.cpp \
src/mbgl/text/glyph_pbf.cpp \
+ src/mbgl/text/language_tag.cpp \
src/mbgl/text/placement.cpp \
src/mbgl/text/quads.cpp \
src/mbgl/text/shaping.cpp \
@@ -358,8 +361,9 @@ SOURCES += \
src/mbgl/util/url.cpp \
src/mbgl/util/version.cpp \
src/mbgl/util/work_request.cpp \
- src/parsedate/parsedate.c \
+ src/parsedate/parsedate.cpp \
platform/default/asset_file_source.cpp \
+ platform/default/collator.cpp \
platform/default/default_file_source.cpp \
platform/default/file_source_request.cpp \
platform/default/local_file_source.cpp \
@@ -369,7 +373,16 @@ SOURCES += \
platform/default/mbgl/storage/offline_download.cpp \
platform/default/mbgl/util/default_thread_pool.cpp \
platform/default/mbgl/util/shared_thread_pool.cpp \
- platform/default/online_file_source.cpp
+ platform/default/online_file_source.cpp \
+ platform/default/unaccent.cpp \
+ vendor/nunicode/src/libnu/ducet.c \
+ vendor/nunicode/src/libnu/strcoll.c \
+ vendor/nunicode/src/libnu/strings.c \
+ vendor/nunicode/src/libnu/tolower.c \
+ vendor/nunicode/src/libnu/tounaccent.c \
+ vendor/nunicode/src/libnu/toupper.c \
+ vendor/nunicode/src/libnu/utf8.c
+
HEADERS += \
platform/qt/include/qmapbox.hpp \
@@ -382,6 +395,7 @@ HEADERS += \
platform/qt/src/qmapboxgl_p.hpp \
platform/qt/src/qmapboxgl_renderer_backend.hpp \
platform/qt/src/qmapboxgl_renderer_observer.hpp \
+ platform/qt/src/qmapboxgl_scheduler.hpp \
platform/qt/src/qt_conversion.hpp \
platform/qt/src/qt_geojson.hpp \
platform/qt/src/run_loop_impl.hpp \
@@ -390,22 +404,18 @@ HEADERS += \
INCLUDEPATH += \
deps/boost/1.65.1 \
deps/boost/1.65.1/include \
- deps/cheap-ruler/2.5.3 \
- deps/cheap-ruler/2.5.3/include \
deps/earcut/0.12.4 \
deps/earcut/0.12.4/include \
deps/geojson/0.4.2 \
deps/geojson/0.4.2/include \
- deps/geojsonvt/6.3.0 \
- deps/geojsonvt/6.3.0/include \
- deps/geometry/0.9.2 \
- deps/geometry/0.9.2/include \
+ deps/geojsonvt/6.5.1 \
+ deps/geojsonvt/6.5.1/include \
+ deps/geometry/0.9.3 \
+ deps/geometry/0.9.3/include \
deps/kdbush/0.1.1-1 \
deps/kdbush/0.1.1-1/include \
deps/optional/f27e7908 \
deps/optional/f27e7908/include \
- deps/pixelmatch/0.10.0 \
- deps/pixelmatch/0.10.0/include \
deps/polylabel/1.0.3 \
deps/polylabel/1.0.3/include \
deps/protozero/1.5.2 \
@@ -422,15 +432,16 @@ INCLUDEPATH += \
deps/unique_resource/cba309e/include \
deps/variant/1.1.4 \
deps/variant/1.1.4/include \
- deps/vector-tile/1.0.1 \
- deps/vector-tile/1.0.1/include \
+ deps/vector-tile/1.0.2 \
+ deps/vector-tile/1.0.2/include \
deps/wagyu/0.4.3 \
deps/wagyu/0.4.3/include \
include \
platform/default \
platform/qt \
platform/qt/include \
- src
+ src \
+ vendor/nunicode/include
QMAKE_CXXFLAGS += \
- -DMBGL_VERSION_REV=\\\"qt-v1.4.0\\\"
+ -DMBGL_VERSION_REV=\\\"qt-v1.5.0\\\"
diff --git a/platform/default/collator.cpp b/platform/default/collator.cpp
new file mode 100644
index 0000000000..b7f256756e
--- /dev/null
+++ b/platform/default/collator.cpp
@@ -0,0 +1,79 @@
+#include <mbgl/style/expression/collator.hpp>
+#include <mbgl/util/platform.hpp>
+#include <libnu/strcoll.h>
+#include <unaccent.hpp>
+
+/*
+ The default implementation of Collator ignores locale.
+ Case sensitivity and collation order are based on
+ Default Unicode Collation Element Table (DUCET).
+
+ Diacritic-insensitivity is implemented with nunicode's
+ non-standard "unaccent" functionality, which is tailored
+ to European languages.
+
+ It would be possible to implement locale awareness using ICU,
+ but would require bundling locale data.
+*/
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+class Collator::Impl {
+public:
+ Impl(bool caseSensitive_, bool diacriticSensitive_, optional<std::string>)
+ : caseSensitive(caseSensitive_)
+ , diacriticSensitive(diacriticSensitive_)
+ {}
+
+ bool operator==(const Impl& other) const {
+ return caseSensitive == other.caseSensitive &&
+ diacriticSensitive == other.diacriticSensitive;
+ }
+
+ int compare(const std::string& lhs, const std::string& rhs) const {
+ if (caseSensitive && diacriticSensitive) {
+ return nu_strcoll(lhs.c_str(), rhs.c_str(),
+ nu_utf8_read, nu_utf8_read);
+ } else if (!caseSensitive && diacriticSensitive) {
+ return nu_strcasecoll(lhs.c_str(), rhs.c_str(),
+ nu_utf8_read, nu_utf8_read);
+ } else if (caseSensitive && !diacriticSensitive) {
+ return nu_strcoll(platform::unaccent(lhs).c_str(), platform::unaccent(rhs).c_str(),
+ nu_utf8_read, nu_utf8_read);
+ } else {
+ return nu_strcasecoll(platform::unaccent(lhs).c_str(), platform::unaccent(rhs).c_str(),
+ nu_utf8_read, nu_utf8_read);
+ }
+ }
+
+ std::string resolvedLocale() const {
+ return "";
+ }
+private:
+ bool caseSensitive;
+ bool diacriticSensitive;
+};
+
+
+Collator::Collator(bool caseSensitive, bool diacriticSensitive, optional<std::string> locale_)
+ : impl(std::make_shared<Impl>(caseSensitive, diacriticSensitive, std::move(locale_)))
+{}
+
+bool Collator::operator==(const Collator& other) const {
+ return *impl == *(other.impl);
+}
+
+int Collator::compare(const std::string& lhs, const std::string& rhs) const {
+ return impl->compare(lhs, rhs);
+}
+
+std::string Collator::resolvedLocale() const {
+ return impl->resolvedLocale();
+}
+
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index cb602995a4..f070121497 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -11,6 +11,7 @@
#include <mbgl/util/url.hpp>
#include <mbgl/util/thread.hpp>
#include <mbgl/util/work_request.hpp>
+#include <mbgl/util/stopwatch.hpp>
#include <cassert>
@@ -18,15 +19,10 @@ namespace mbgl {
class DefaultFileSource::Impl {
public:
- Impl(ActorRef<Impl> self, std::shared_ptr<FileSource> assetFileSource_, const std::string& cachePath, uint64_t maximumCacheSize)
+ Impl(std::shared_ptr<FileSource> assetFileSource_, std::string cachePath, uint64_t maximumCacheSize)
: assetFileSource(assetFileSource_)
- , localFileSource(std::make_unique<LocalFileSource>()) {
- // Initialize the Database asynchronously so as to not block Actor creation.
- self.invoke(&Impl::initializeOfflineDatabase, cachePath, maximumCacheSize);
- }
-
- void initializeOfflineDatabase(std::string cachePath, uint64_t maximumCacheSize) {
- offlineDatabase = std::make_unique<OfflineDatabase>(cachePath, maximumCacheSize);
+ , localFileSource(std::make_unique<LocalFileSource>())
+ , offlineDatabase(std::make_unique<OfflineDatabase>(cachePath, maximumCacheSize)) {
}
void setAPIBaseURL(const std::string& url) {
@@ -151,8 +147,17 @@ public:
// Get from the online file source
if (resource.hasLoadingMethod(Resource::LoadingMethod::Network)) {
+ MBGL_TIMING_START(watch);
tasks[req] = onlineFileSource.request(resource, [=] (Response onlineResponse) mutable {
this->offlineDatabase->put(resource, onlineResponse);
+ if (resource.kind == Resource::Kind::Tile) {
+ // onlineResponse.data will be null if data not modified
+ MBGL_TIMING_FINISH(watch,
+ " Action: " << "Requesting," <<
+ " URL: " << resource.url.c_str() <<
+ " Size: " << (onlineResponse.data != nullptr ? onlineResponse.data->size() : 0) << "B," <<
+ " Time")
+ }
callback(onlineResponse);
});
}
diff --git a/platform/default/http_file_source.cpp b/platform/default/http_file_source.cpp
index a9c442c2de..9166d92fb7 100644
--- a/platform/default/http_file_source.cpp
+++ b/platform/default/http_file_source.cpp
@@ -13,6 +13,85 @@
#include <curl/curl.h>
+// Dynamically load all cURL functions. Debian-derived systems upgraded the OpenSSL version linked
+// to in https://salsa.debian.org/debian/curl/commit/95c94957bb7e89e36e78b995fed468c42f64d18d
+// They state:
+// Rename libcurl3 to libcurl4, because libcurl exposes an SSL_CTX via
+// CURLOPT_SSL_CTX_FUNCTION, and this object changes incompatibly between
+// openssl 1.0 and openssl 1.1.
+// Since we are not accessing the underlying OpenSSL context, we don't care whether we're linking
+// against libcurl3 or libcurl4; both use the ABI version 4 which hasn't changed since 2006
+// (see https://curl.haxx.se/libcurl/abi.html). In fact, cURL's ABI compatibility is very good as
+// shown on https://abi-laboratory.pro/tracker/timeline/curl/
+// Therefore, we're dynamically loading the cURL symbols we need to avoid linking against versioned
+// symbols.
+#include <dlfcn.h>
+
+namespace curl {
+
+#define CURL_FUNCTIONS \
+ X(global_init) \
+ X(getdate) \
+ X(easy_strerror) \
+ X(easy_init) \
+ X(easy_setopt) \
+ X(easy_cleanup) \
+ X(easy_getinfo) \
+ X(easy_reset) \
+ X(multi_init) \
+ X(multi_add_handle) \
+ X(multi_remove_handle) \
+ X(multi_cleanup) \
+ X(multi_info_read) \
+ X(multi_strerror) \
+ X(multi_socket_action) \
+ X(multi_setopt) \
+ X(share_init) \
+ X(share_cleanup) \
+ X(slist_append) \
+ X(slist_free_all)
+
+#define X(name) static decltype(&curl_ ## name) name = nullptr;
+CURL_FUNCTIONS
+#undef X
+
+static void* handle = nullptr;
+
+static void* load(const char* name) {
+ void* symbol = dlsym(handle, name);
+ if (const char* error = dlerror()) {
+ fprintf(stderr, "Cannot load symbol '%s': %s\n", name, error);
+ dlclose(handle);
+ handle = nullptr;
+ abort();
+ }
+ return symbol;
+}
+
+__attribute__((constructor))
+static void load() {
+ assert(!handle);
+ handle = dlopen("libcurl.so.4", RTLD_LAZY | RTLD_LOCAL);
+ if (!handle) {
+ fprintf(stderr, "Could not open shared library '%s'\n", "libcurl.so.4");
+ abort();
+ }
+
+ #define X(name) name = (decltype(&curl_ ## name))load("curl_" #name);
+ CURL_FUNCTIONS
+ #undef X
+}
+
+__attribute__((constructor))
+static void unload() {
+ if (handle) {
+ dlclose(handle);
+ }
+}
+
+} // namespace curl
+
+
#include <queue>
#include <map>
#include <cassert>
@@ -21,13 +100,13 @@
static void handleError(CURLMcode code) {
if (code != CURLM_OK) {
- throw std::runtime_error(std::string("CURL multi error: ") + curl_multi_strerror(code));
+ throw std::runtime_error(std::string("CURL multi error: ") + curl::multi_strerror(code));
}
}
static void handleError(CURLcode code) {
if (code != CURLE_OK) {
- throw std::runtime_error(std::string("CURL easy error: ") + curl_easy_strerror(code));
+ throw std::runtime_error(std::string("CURL easy error: ") + curl::easy_strerror(code));
}
}
@@ -91,29 +170,29 @@ private:
};
HTTPFileSource::Impl::Impl() {
- if (curl_global_init(CURL_GLOBAL_ALL)) {
+ if (curl::global_init(CURL_GLOBAL_ALL)) {
throw std::runtime_error("Could not init cURL");
}
- share = curl_share_init();
+ share = curl::share_init();
- multi = curl_multi_init();
- handleError(curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, handleSocket));
- handleError(curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, this));
- handleError(curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, startTimeout));
- handleError(curl_multi_setopt(multi, CURLMOPT_TIMERDATA, this));
+ multi = curl::multi_init();
+ handleError(curl::multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, handleSocket));
+ handleError(curl::multi_setopt(multi, CURLMOPT_SOCKETDATA, this));
+ handleError(curl::multi_setopt(multi, CURLMOPT_TIMERFUNCTION, startTimeout));
+ handleError(curl::multi_setopt(multi, CURLMOPT_TIMERDATA, this));
}
HTTPFileSource::Impl::~Impl() {
while (!handles.empty()) {
- curl_easy_cleanup(handles.front());
+ curl::easy_cleanup(handles.front());
handles.pop();
}
- curl_multi_cleanup(multi);
+ curl::multi_cleanup(multi);
multi = nullptr;
- curl_share_cleanup(share);
+ curl::share_cleanup(share);
share = nullptr;
timeout.stop();
@@ -125,12 +204,12 @@ CURL *HTTPFileSource::Impl::getHandle() {
handles.pop();
return handle;
} else {
- return curl_easy_init();
+ return curl::easy_init();
}
}
void HTTPFileSource::Impl::returnHandle(CURL *handle) {
- curl_easy_reset(handle);
+ curl::easy_reset(handle);
handles.push(handle);
}
@@ -138,11 +217,11 @@ void HTTPFileSource::Impl::checkMultiInfo() {
CURLMsg *message = nullptr;
int pending = 0;
- while ((message = curl_multi_info_read(multi, &pending))) {
+ while ((message = curl::multi_info_read(multi, &pending))) {
switch (message->msg) {
case CURLMSG_DONE: {
HTTPRequest *baton = nullptr;
- curl_easy_getinfo(message->easy_handle, CURLINFO_PRIVATE, (char *)&baton);
+ curl::easy_getinfo(message->easy_handle, CURLINFO_PRIVATE, (char *)&baton);
assert(baton);
baton->handleResult(message->data.result);
} break;
@@ -166,7 +245,7 @@ void HTTPFileSource::Impl::perform(curl_socket_t s, util::RunLoop::Event events)
int running_handles = 0;
- curl_multi_socket_action(multi, s, flags, &running_handles);
+ curl::multi_socket_action(multi, s, flags, &running_handles);
checkMultiInfo();
}
@@ -200,9 +279,9 @@ int HTTPFileSource::Impl::handleSocket(CURL * /* handle */, curl_socket_t s, int
void HTTPFileSource::Impl::onTimeout(Impl *context) {
int running_handles;
- CURLMcode error = curl_multi_socket_action(context->multi, CURL_SOCKET_TIMEOUT, 0, &running_handles);
+ CURLMcode error = curl::multi_socket_action(context->multi, CURL_SOCKET_TIMEOUT, 0, &running_handles);
if (error != CURLM_OK) {
- throw std::runtime_error(std::string("CURL multi error: ") + curl_multi_strerror(error));
+ throw std::runtime_error(std::string("CURL multi error: ") + curl::multi_strerror(error));
}
context->checkMultiInfo();
}
@@ -233,45 +312,45 @@ HTTPRequest::HTTPRequest(HTTPFileSource::Impl* context_, Resource resource_, Fil
// getting a 304 response if possible. This avoids redownloading unchanged data.
if (resource.priorEtag) {
const std::string header = std::string("If-None-Match: ") + *resource.priorEtag;
- headers = curl_slist_append(headers, header.c_str());
+ headers = curl::slist_append(headers, header.c_str());
} else if (resource.priorModified) {
const std::string time =
std::string("If-Modified-Since: ") + util::rfc1123(*resource.priorModified);
- headers = curl_slist_append(headers, time.c_str());
+ headers = curl::slist_append(headers, time.c_str());
}
if (headers) {
- curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
+ curl::easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
}
- handleError(curl_easy_setopt(handle, CURLOPT_PRIVATE, this));
- handleError(curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, error));
- handleError(curl_easy_setopt(handle, CURLOPT_CAINFO, "ca-bundle.crt"));
- handleError(curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1));
- handleError(curl_easy_setopt(handle, CURLOPT_URL, resource.url.c_str()));
- handleError(curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeCallback));
- handleError(curl_easy_setopt(handle, CURLOPT_WRITEDATA, this));
- handleError(curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, headerCallback));
- handleError(curl_easy_setopt(handle, CURLOPT_HEADERDATA, this));
+ handleError(curl::easy_setopt(handle, CURLOPT_PRIVATE, this));
+ handleError(curl::easy_setopt(handle, CURLOPT_ERRORBUFFER, error));
+ handleError(curl::easy_setopt(handle, CURLOPT_CAINFO, "ca-bundle.crt"));
+ handleError(curl::easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1));
+ handleError(curl::easy_setopt(handle, CURLOPT_URL, resource.url.c_str()));
+ handleError(curl::easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeCallback));
+ handleError(curl::easy_setopt(handle, CURLOPT_WRITEDATA, this));
+ handleError(curl::easy_setopt(handle, CURLOPT_HEADERFUNCTION, headerCallback));
+ handleError(curl::easy_setopt(handle, CURLOPT_HEADERDATA, this));
#if LIBCURL_VERSION_NUM >= ((7) << 16 | (21) << 8 | 6) // Renamed in 7.21.6
- handleError(curl_easy_setopt(handle, CURLOPT_ACCEPT_ENCODING, "gzip, deflate"));
+ handleError(curl::easy_setopt(handle, CURLOPT_ACCEPT_ENCODING, "gzip, deflate"));
#else
- handleError(curl_easy_setopt(handle, CURLOPT_ENCODING, "gzip, deflate"));
+ handleError(curl::easy_setopt(handle, CURLOPT_ENCODING, "gzip, deflate"));
#endif
- handleError(curl_easy_setopt(handle, CURLOPT_USERAGENT, "MapboxGL/1.0"));
- handleError(curl_easy_setopt(handle, CURLOPT_SHARE, context->share));
+ handleError(curl::easy_setopt(handle, CURLOPT_USERAGENT, "MapboxGL/1.0"));
+ handleError(curl::easy_setopt(handle, CURLOPT_SHARE, context->share));
// Start requesting the information.
- handleError(curl_multi_add_handle(context->multi, handle));
+ handleError(curl::multi_add_handle(context->multi, handle));
}
HTTPRequest::~HTTPRequest() {
- handleError(curl_multi_remove_handle(context->multi, handle));
+ handleError(curl::multi_remove_handle(context->multi, handle));
context->returnHandle(handle);
handle = nullptr;
if (headers) {
- curl_slist_free_all(headers);
+ curl::slist_free_all(headers);
headers = nullptr;
}
}
@@ -320,7 +399,7 @@ size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const
// Always overwrite the modification date; We might already have a value here from the
// Date header, but this one is more accurate.
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
- baton->response->modified = Timestamp{ Seconds(curl_getdate(value.c_str(), nullptr)) };
+ baton->response->modified = Timestamp{ Seconds(curl::getdate(value.c_str(), nullptr)) };
} else if ((begin = headerMatches("etag: ", buffer, length)) != std::string::npos) {
baton->response->etag = std::string(buffer + begin, length - begin - 2); // remove \r\n
} else if ((begin = headerMatches("cache-control: ", buffer, length)) != std::string::npos) {
@@ -330,7 +409,7 @@ size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const
baton->response->mustRevalidate = cc.mustRevalidate;
} else if ((begin = headerMatches("expires: ", buffer, length)) != std::string::npos) {
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
- baton->response->expires = Timestamp{ Seconds(curl_getdate(value.c_str(), nullptr)) };
+ baton->response->expires = Timestamp{ Seconds(curl::getdate(value.c_str(), nullptr)) };
} else if ((begin = headerMatches("retry-after: ", buffer, length)) != std::string::npos) {
baton->retryAfter = std::string(buffer + begin, length - begin - 2); // remove \r\n
} else if ((begin = headerMatches("x-rate-limit-reset: ", buffer, length)) != std::string::npos) {
@@ -357,17 +436,17 @@ void HTTPRequest::handleResult(CURLcode code) {
case CURLE_OPERATION_TIMEDOUT:
response->error = std::make_unique<Error>(
- Error::Reason::Connection, std::string{ curl_easy_strerror(code) } + ": " + error);
+ Error::Reason::Connection, std::string{ curl::easy_strerror(code) } + ": " + error);
break;
default:
response->error = std::make_unique<Error>(
- Error::Reason::Other, std::string{ curl_easy_strerror(code) } + ": " + error);
+ Error::Reason::Other, std::string{ curl::easy_strerror(code) } + ": " + error);
break;
}
} else {
long responseCode = 0;
- curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &responseCode);
+ curl::easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &responseCode);
if (responseCode == 200) {
if (data) {
diff --git a/platform/default/mbgl/map/map_snapshotter.cpp b/platform/default/mbgl/map/map_snapshotter.cpp
index 9341c23cfd..565f72930d 100644
--- a/platform/default/mbgl/map/map_snapshotter.cpp
+++ b/platform/default/mbgl/map/map_snapshotter.cpp
@@ -13,18 +13,21 @@ namespace mbgl {
class MapSnapshotter::Impl {
public:
- Impl(FileSource&,
- Scheduler&,
- const std::string& styleURL,
+ Impl(FileSource*,
+ std::shared_ptr<Scheduler>,
+ const std::pair<bool, std::string> style,
const Size&,
const float pixelRatio,
- const CameraOptions&,
+ const optional<CameraOptions> cameraOptions,
const optional<LatLngBounds> region,
const optional<std::string> programCacheDir);
void setStyleURL(std::string styleURL);
std::string getStyleURL() const;
+ void setStyleJSON(std::string styleJSON);
+ std::string getStyleJSON() const;
+
void setSize(Size);
Size getSize() const;
@@ -37,24 +40,32 @@ public:
void snapshot(ActorRef<MapSnapshotter::Callback>);
private:
+ std::shared_ptr<Scheduler> scheduler;
HeadlessFrontend frontend;
Map map;
};
-MapSnapshotter::Impl::Impl(FileSource& fileSource,
- Scheduler& scheduler,
- const std::string& styleURL,
+MapSnapshotter::Impl::Impl(FileSource* fileSource,
+ std::shared_ptr<Scheduler> scheduler_,
+ const std::pair<bool, std::string> style,
const Size& size,
const float pixelRatio,
- const CameraOptions& cameraOptions,
+ const optional<CameraOptions> cameraOptions,
const optional<LatLngBounds> region,
const optional<std::string> programCacheDir)
- : frontend(size, pixelRatio, fileSource, scheduler, programCacheDir)
- , map(frontend, MapObserver::nullObserver(), size, pixelRatio, fileSource, scheduler, MapMode::Static) {
-
- map.getStyle().loadURL(styleURL);
+ : scheduler(std::move(scheduler_))
+ , frontend(size, pixelRatio, *fileSource, *scheduler, programCacheDir)
+ , map(frontend, MapObserver::nullObserver(), size, pixelRatio, *fileSource, *scheduler, MapMode::Static) {
+
+ if (style.first) {
+ map.getStyle().loadJSON(style.second);
+ } else{
+ map.getStyle().loadURL(style.second);
+ }
- map.jumpTo(cameraOptions);
+ if (cameraOptions) {
+ map.jumpTo(*cameraOptions);
+ }
// Set region, if specified
if (region) {
@@ -76,6 +87,15 @@ void MapSnapshotter::Impl::snapshot(ActorRef<MapSnapshotter::Callback> callback)
return transform.latLngToScreenCoordinate(unwrappedLatLng);
}};
+ // Create lambda that captures the current transform state
+ // and can be used to translate for geographic to screen
+ // coordinates
+ assert (frontend.getTransformState());
+ LatLngForFn latLngForFn { [=, transformState = *frontend.getTransformState()] (const ScreenCoordinate& screenCoordinate) {
+ Transform transform { transformState };
+ return transform.screenCoordinateToLatLng(screenCoordinate);
+ }};
+
// Collect all source attributions
std::vector<std::string> attributions;
for (auto source : map.getStyle().getSources()) {
@@ -91,7 +111,8 @@ void MapSnapshotter::Impl::snapshot(ActorRef<MapSnapshotter::Callback> callback)
error,
error ? PremultipliedImage() : frontend.readStillImage(),
std::move(attributions),
- std::move(pointForFn)
+ std::move(pointForFn),
+ std::move(latLngForFn)
);
});
}
@@ -104,6 +125,14 @@ std::string MapSnapshotter::Impl::getStyleURL() const {
return map.getStyle().getURL();
}
+void MapSnapshotter::Impl::setStyleJSON(std::string styleJSON) {
+ map.getStyle().loadJSON(styleJSON);
+}
+
+std::string MapSnapshotter::Impl::getStyleJSON() const {
+ return map.getStyle().getJSON();
+}
+
void MapSnapshotter::Impl::setSize(Size size) {
map.setSize(size);
frontend.setSize(size);
@@ -132,15 +161,15 @@ LatLngBounds MapSnapshotter::Impl::getRegion() const {
return map.latLngBoundsForCamera(getCameraOptions());
}
-MapSnapshotter::MapSnapshotter(FileSource& fileSource,
- Scheduler& scheduler,
- const std::string& styleURL,
+MapSnapshotter::MapSnapshotter(FileSource* fileSource,
+ std::shared_ptr<Scheduler> scheduler,
+ const std::pair<bool, std::string> style,
const Size& size,
const float pixelRatio,
- const CameraOptions& cameraOptions,
+ const optional<CameraOptions> cameraOptions,
const optional<LatLngBounds> region,
const optional<std::string> programCacheDir)
- : impl(std::make_unique<util::Thread<MapSnapshotter::Impl>>("Map Snapshotter", fileSource, scheduler, styleURL, size, pixelRatio, cameraOptions, region, programCacheDir)) {
+ : impl(std::make_unique<util::Thread<MapSnapshotter::Impl>>("Map Snapshotter", fileSource, std::move(scheduler), style, size, pixelRatio, cameraOptions, region, programCacheDir)) {
}
MapSnapshotter::~MapSnapshotter() = default;
@@ -157,6 +186,14 @@ std::string MapSnapshotter::getStyleURL() const {
return impl->actor().ask(&Impl::getStyleURL).get();
}
+void MapSnapshotter::setStyleJSON(const std::string& styleJSON) {
+ impl->actor().invoke(&Impl::setStyleJSON, styleJSON);
+}
+
+std::string MapSnapshotter::getStyleJSON() const {
+ return impl->actor().ask(&Impl::getStyleJSON).get();
+}
+
void MapSnapshotter::setSize(const Size& size) {
impl->actor().invoke(&Impl::setSize, size);
}
diff --git a/platform/default/mbgl/map/map_snapshotter.hpp b/platform/default/mbgl/map/map_snapshotter.hpp
index 985396e5a3..264f74541d 100644
--- a/platform/default/mbgl/map/map_snapshotter.hpp
+++ b/platform/default/mbgl/map/map_snapshotter.hpp
@@ -25,12 +25,12 @@ class Style;
class MapSnapshotter {
public:
- MapSnapshotter(FileSource& fileSource,
- Scheduler& scheduler,
- const std::string& styleURL,
+ MapSnapshotter(FileSource* fileSource,
+ std::shared_ptr<Scheduler> scheduler,
+ const std::pair<bool, std::string> style,
const Size&,
const float pixelRatio,
- const CameraOptions&,
+ const optional<CameraOptions> cameraOptions,
const optional<LatLngBounds> region,
const optional<std::string> cacheDir = {});
@@ -39,6 +39,9 @@ public:
void setStyleURL(const std::string& styleURL);
std::string getStyleURL() const;
+ void setStyleJSON(const std::string& styleJSON);
+ std::string getStyleJSON() const;
+
void setSize(const Size&);
Size getSize() const;
@@ -49,8 +52,9 @@ public:
LatLngBounds getRegion() const;
using PointForFn = std::function<ScreenCoordinate (const LatLng&)>;
+ using LatLngForFn = std::function<LatLng (const ScreenCoordinate&)>;
using Attributions = std::vector<std::string>;
- using Callback = std::function<void (std::exception_ptr, PremultipliedImage, Attributions, PointForFn)>;
+ using Callback = std::function<void (std::exception_ptr, PremultipliedImage, Attributions, PointForFn, LatLngForFn)>;
void snapshot(ActorRef<Callback>);
private:
diff --git a/platform/default/mbgl/storage/.clang-tidy b/platform/default/mbgl/storage/.clang-tidy
new file mode 100644
index 0000000000..b4ecd26b95
--- /dev/null
+++ b/platform/default/mbgl/storage/.clang-tidy
@@ -0,0 +1,2 @@
+Checks: 'modernize-*,misc-static-assert,llvm-namespace-comment,-clang-analyzer-security.insecureAPI.rand,-clang-analyzer-core.uninitialized.UndefReturn,-clang-analyzer-core.StackAddressEscape,-clang-analyzer-core.CallAndMessage,-clang-diagnostic-unused-command-line-argument,-clang-analyzer-core.uninitialized.*,-clang-analyzer-core.NullDereference,-clang-analyzer-cplusplus.NewDelete,-clang-analyzer-unix.MismatchedDeallocator,-clang-analyzer-unix.cstring.NullArg,-clang-analyzer-cplusplus.NewDeleteLeaks,-clang-analyzer-unix.Malloc,-clang-analyzer-core.NonNullParamChecker'
+HeaderFilterRegex: '\/mbgl\/'
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 4611e69f43..8f7f0965f4 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -6,6 +6,8 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/logging.hpp>
+#include "offline_schema.hpp"
+
#include "sqlite3.hpp"
namespace mbgl {
@@ -27,58 +29,73 @@ OfflineDatabase::~OfflineDatabase() {
}
}
-void OfflineDatabase::connect(int flags) {
- db = std::make_unique<mapbox::sqlite::Database>(path.c_str(), flags);
- db->setBusyTimeout(Milliseconds::max());
- db->exec("PRAGMA foreign_keys = ON");
-}
-
void OfflineDatabase::ensureSchema() {
- if (path != ":memory:") {
- try {
- connect(mapbox::sqlite::ReadWrite);
-
- switch (userVersion()) {
- case 0: break; // cache-only database; ok to delete
- case 1: break; // cache-only database; ok to delete
- case 2: migrateToVersion3(); // fall through
- case 3: // no-op and fall through
- case 4: migrateToVersion5(); // fall through
- case 5: migrateToVersion6(); // fall through
- case 6: return;
- default: break; // downgrade, delete the database
- }
-
+ auto result = mapbox::sqlite::Database::tryOpen(path, mapbox::sqlite::ReadWriteCreate);
+ if (result.is<mapbox::sqlite::Exception>()) {
+ const auto& ex = result.get<mapbox::sqlite::Exception>();
+ if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
+ // Corrupted; blow it away.
removeExisting();
- connect(mapbox::sqlite::ReadWrite | mapbox::sqlite::Create);
- } catch (mapbox::sqlite::Exception& ex) {
- if (ex.code != mapbox::sqlite::ResultCode::CantOpen && ex.code != mapbox::sqlite::ResultCode::NotADB) {
- Log::Error(Event::Database, "Unexpected error connecting to database: %s", ex.what());
- throw;
- }
-
- try {
- if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
- removeExisting();
- }
- connect(mapbox::sqlite::ReadWrite | mapbox::sqlite::Create);
- } catch (...) {
- Log::Error(Event::Database, "Unexpected error creating database: %s", util::toString(std::current_exception()).c_str());
- throw;
- }
+ result = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadWriteCreate);
+ } else {
+ Log::Error(Event::Database, "Unexpected error connecting to database: %s", ex.what());
+ throw ex;
}
}
try {
- #include "offline_schema.cpp.include"
+ assert(result.is<mapbox::sqlite::Database>());
+ db = std::make_unique<mapbox::sqlite::Database>(std::move(result.get<mapbox::sqlite::Database>()));
+ db->setBusyTimeout(Milliseconds::max());
+ db->exec("PRAGMA foreign_keys = ON");
+
+ switch (userVersion()) {
+ case 0:
+ case 1:
+ // Newly created database, or old cache-only database; remove old table if it exists.
+ removeOldCacheTable();
+ break;
+ case 2:
+ migrateToVersion3();
+ // fall through
+ case 3:
+ case 4:
+ migrateToVersion5();
+ // fall through
+ case 5:
+ migrateToVersion6();
+ // fall through
+ case 6:
+ // happy path; we're done
+ return;
+ default:
+ // downgrade, delete the database
+ removeExisting();
+ break;
+ }
+ } catch (const mapbox::sqlite::Exception& ex) {
+ // Unfortunately, SQLITE_NOTADB is not always reported upon opening the database.
+ // Apparently sometimes it is delayed until the first read operation.
+ if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
+ removeExisting();
+ } else {
+ throw;
+ }
+ }
- connect(mapbox::sqlite::ReadWrite | mapbox::sqlite::Create);
+ try {
+ // When downgrading the database, or when the database is corrupt, we've deleted the old database handle,
+ // so we need to reopen it.
+ if (!db) {
+ db = std::make_unique<mapbox::sqlite::Database>(mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadWriteCreate));
+ db->setBusyTimeout(Milliseconds::max());
+ db->exec("PRAGMA foreign_keys = ON");
+ }
- // If you change the schema you must write a migration from the previous version.
db->exec("PRAGMA auto_vacuum = INCREMENTAL");
db->exec("PRAGMA journal_mode = DELETE");
db->exec("PRAGMA synchronous = FULL");
- db->exec(schema);
+ db->exec(offlineDatabaseSchema);
db->exec("PRAGMA user_version = 6");
} catch (...) {
Log::Error(Event::Database, "Unexpected error creating database schema: %s", util::toString(std::current_exception()).c_str());
@@ -93,6 +110,7 @@ int OfflineDatabase::userVersion() {
void OfflineDatabase::removeExisting() {
Log::Warning(Event::Database, "Removing existing incompatible offline database");
+ statements.clear();
db.reset();
try {
@@ -102,6 +120,11 @@ void OfflineDatabase::removeExisting() {
}
}
+void OfflineDatabase::removeOldCacheTable() {
+ db->exec("DROP TABLE IF EXISTS http_cache");
+ db->exec("VACUUM");
+}
+
void OfflineDatabase::migrateToVersion3() {
db->exec("PRAGMA auto_vacuum = INCREMENTAL");
db->exec("VACUUM");
@@ -160,7 +183,10 @@ optional<int64_t> OfflineDatabase::hasInternal(const Resource& resource) {
}
std::pair<bool, uint64_t> OfflineDatabase::put(const Resource& resource, const Response& response) {
- return putInternal(resource, response, true);
+ mapbox::sqlite::Transaction transaction(*db, mapbox::sqlite::Transaction::Immediate);
+ auto result = putInternal(resource, response, true);
+ transaction.commit();
+ return result;
}
std::pair<bool, uint64_t> OfflineDatabase::putInternal(const Resource& resource, const Response& response, bool evict_) {
@@ -179,7 +205,7 @@ std::pair<bool, uint64_t> OfflineDatabase::putInternal(const Resource& resource,
}
if (evict_ && !evict(size)) {
- Log::Debug(Event::Database, "Unable to make space for entry");
+ Log::Info(Event::Database, "Unable to make space for entry");
return { false, 0 };
}
@@ -277,11 +303,6 @@ bool OfflineDatabase::putResource(const Resource& resource,
}
// We can't use REPLACE because it would change the id value.
-
- // Begin an immediate-mode transaction to ensure that two writers do not attempt
- // to INSERT a resource at the same moment.
- mapbox::sqlite::Transaction transaction(*db, mapbox::sqlite::Transaction::Immediate);
-
// clang-format off
mapbox::sqlite::Query updateQuery{ getStatement(
"UPDATE resources "
@@ -314,7 +335,6 @@ bool OfflineDatabase::putResource(const Resource& resource,
updateQuery.run();
if (updateQuery.changes() != 0) {
- transaction.commit();
return false;
}
@@ -341,7 +361,6 @@ bool OfflineDatabase::putResource(const Resource& resource,
}
insertQuery.run();
- transaction.commit();
return true;
}
@@ -469,10 +488,6 @@ bool OfflineDatabase::putTile(const Resource::TileData& tile,
// We can't use REPLACE because it would change the id value.
- // Begin an immediate-mode transaction to ensure that two writers do not attempt
- // to INSERT a resource at the same moment.
- mapbox::sqlite::Transaction transaction(*db, mapbox::sqlite::Transaction::Immediate);
-
// clang-format off
mapbox::sqlite::Query updateQuery{ getStatement(
"UPDATE tiles "
@@ -511,7 +526,6 @@ bool OfflineDatabase::putTile(const Resource::TileData& tile,
updateQuery.run();
if (updateQuery.changes() != 0) {
- transaction.commit();
return false;
}
@@ -541,7 +555,6 @@ bool OfflineDatabase::putTile(const Resource::TileData& tile,
}
insertQuery.run();
- transaction.commit();
return true;
}
@@ -624,6 +637,43 @@ optional<int64_t> OfflineDatabase::hasRegionResource(int64_t regionID, const Res
}
uint64_t OfflineDatabase::putRegionResource(int64_t regionID, const Resource& resource, const Response& response) {
+ mapbox::sqlite::Transaction transaction(*db);
+ auto size = putRegionResourceInternal(regionID, resource, response);
+ transaction.commit();
+ return size;
+}
+
+void OfflineDatabase::putRegionResources(int64_t regionID, const std::list<std::tuple<Resource, Response>>& resources, OfflineRegionStatus& status) {
+ mapbox::sqlite::Transaction transaction(*db);
+
+ for (const auto& elem : resources) {
+ const auto& resource = std::get<0>(elem);
+ const auto& response = std::get<1>(elem);
+
+ try {
+ uint64_t resourceSize = putRegionResourceInternal(regionID, resource, response);
+ status.completedResourceCount++;
+ status.completedResourceSize += resourceSize;
+ if (resource.kind == Resource::Kind::Tile) {
+ status.completedTileCount += 1;
+ status.completedTileSize += resourceSize;
+ }
+ } catch (const MapboxTileLimitExceededException&) {
+ // Commit the rest of the batch and retrow
+ transaction.commit();
+ throw;
+ }
+ }
+
+ // Commit the completed batch
+ transaction.commit();
+}
+
+uint64_t OfflineDatabase::putRegionResourceInternal(int64_t regionID, const Resource& resource, const Response& response) {
+ if (exceedsOfflineMapboxTileCountLimit(resource)) {
+ throw MapboxTileLimitExceededException();
+ }
+
uint64_t size = putInternal(resource, response, false).second;
bool previouslyUnused = markUsed(regionID, resource);
@@ -894,4 +944,10 @@ uint64_t OfflineDatabase::getOfflineMapboxTileCount() {
return *offlineMapboxTileCount;
}
+bool OfflineDatabase::exceedsOfflineMapboxTileCountLimit(const Resource& resource) {
+ return resource.kind == Resource::Kind::Tile
+ && util::mapbox::isMapboxURL(resource.url)
+ && offlineMapboxTileCountLimitExceeded();
+}
+
} // namespace mbgl
diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp
index 9673ad8212..38eb3783ba 100644
--- a/platform/default/mbgl/storage/offline_database.hpp
+++ b/platform/default/mbgl/storage/offline_database.hpp
@@ -2,6 +2,7 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/offline.hpp>
+#include <mbgl/util/exception.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/constants.hpp>
@@ -10,6 +11,7 @@
#include <unordered_map>
#include <memory>
#include <string>
+#include <list>
namespace mapbox {
namespace sqlite {
@@ -24,6 +26,10 @@ namespace mbgl {
class Response;
class TileID;
+struct MapboxTileLimitExceededException : util::Exception {
+ MapboxTileLimitExceededException() : util::Exception("Mapbox tile limit exceeded") {}
+};
+
class OfflineDatabase : private util::noncopyable {
public:
// Limits affect ambient caching (put) only; resources required by offline
@@ -49,6 +55,7 @@ public:
optional<std::pair<Response, uint64_t>> getRegionResource(int64_t regionID, const Resource&);
optional<int64_t> hasRegionResource(int64_t regionID, const Resource&);
uint64_t putRegionResource(int64_t regionID, const Resource&, const Response&);
+ void putRegionResources(int64_t regionID, const std::list<std::tuple<Resource, Response>>&, OfflineRegionStatus&);
OfflineRegionDefinition getRegionDefinition(int64_t regionID);
OfflineRegionStatus getRegionCompletedStatus(int64_t regionID);
@@ -57,12 +64,13 @@ public:
uint64_t getOfflineMapboxTileCountLimit();
bool offlineMapboxTileCountLimitExceeded();
uint64_t getOfflineMapboxTileCount();
+ bool exceedsOfflineMapboxTileCountLimit(const Resource&);
private:
- void connect(int flags);
int userVersion();
void ensureSchema();
void removeExisting();
+ void removeOldCacheTable();
void migrateToVersion3();
void migrateToVersion5();
void migrateToVersion6();
@@ -79,6 +87,8 @@ private:
bool putResource(const Resource&, const Response&,
const std::string&, bool compressed);
+ uint64_t putRegionResourceInternal(int64_t regionID, const Resource&, const Response&);
+
optional<std::pair<Response, uint64_t>> getInternal(const Resource&);
optional<int64_t> hasInternal(const Resource&);
std::pair<bool, uint64_t> putInternal(const Resource&, const Response&, bool evict);
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index ba504c1f9b..4da51db655 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -330,7 +330,8 @@ void OfflineDownload::ensureResource(const Resource& resource,
return;
}
- if (checkTileCountLimit(resource)) {
+ if (offlineDatabase.exceedsOfflineMapboxTileCountLimit(resource)) {
+ onMapboxTileCountLimitExceeded();
return;
}
@@ -347,17 +348,24 @@ void OfflineDownload::ensureResource(const Resource& resource,
callback(onlineResponse);
}
- status.completedResourceCount++;
- uint64_t resourceSize = offlineDatabase.putRegionResource(id, resource, onlineResponse);
- status.completedResourceSize += resourceSize;
- if (resource.kind == Resource::Kind::Tile) {
- status.completedTileCount += 1;
- status.completedTileSize += resourceSize;
- }
+ // Queue up for batched insertion
+ buffer.emplace_back(resource, onlineResponse);
- observer->statusChanged(status);
+ // Flush buffer periodically
+ if (buffer.size() == 64 || resourcesRemaining.size() == 0) {
+ try {
+ offlineDatabase.putRegionResources(id, buffer, status);
+ } catch (const MapboxTileLimitExceededException&) {
+ onMapboxTileCountLimitExceeded();
+ return;
+ }
- if (checkTileCountLimit(resource)) {
+ buffer.clear();
+ observer->statusChanged(status);
+ }
+
+ if (offlineDatabase.exceedsOfflineMapboxTileCountLimit(resource)) {
+ onMapboxTileCountLimitExceeded();
return;
}
@@ -366,15 +374,9 @@ void OfflineDownload::ensureResource(const Resource& resource,
});
}
-bool OfflineDownload::checkTileCountLimit(const Resource& resource) {
- if (resource.kind == Resource::Kind::Tile && util::mapbox::isMapboxURL(resource.url) &&
- offlineDatabase.offlineMapboxTileCountLimitExceeded()) {
- observer->mapboxTileCountLimitExceeded(offlineDatabase.getOfflineMapboxTileCountLimit());
- setState(OfflineRegionDownloadState::Inactive);
- return true;
- }
-
- return false;
+void OfflineDownload::onMapboxTileCountLimitExceeded() {
+ observer->mapboxTileCountLimitExceeded(offlineDatabase.getOfflineMapboxTileCountLimit());
+ setState(OfflineRegionDownloadState::Inactive);
}
} // namespace mbgl
diff --git a/platform/default/mbgl/storage/offline_download.hpp b/platform/default/mbgl/storage/offline_download.hpp
index 437f221c11..cffac1665b 100644
--- a/platform/default/mbgl/storage/offline_download.hpp
+++ b/platform/default/mbgl/storage/offline_download.hpp
@@ -46,7 +46,8 @@ private:
* is deactivated, all in progress requests are cancelled.
*/
void ensureResource(const Resource&, std::function<void (Response)> = {});
- bool checkTileCountLimit(const Resource& resource);
+
+ void onMapboxTileCountLimitExceeded();
int64_t id;
OfflineRegionDefinition definition;
@@ -58,6 +59,7 @@ private:
std::list<std::unique_ptr<AsyncRequest>> requests;
std::unordered_set<std::string> requiredSourceURLs;
std::deque<Resource> resourcesRemaining;
+ std::list<std::tuple<Resource, Response>> buffer;
void queueResource(Resource);
void queueTiles(style::SourceType, uint16_t tileSize, const Tileset&);
diff --git a/platform/default/mbgl/storage/offline_schema.cpp.include b/platform/default/mbgl/storage/offline_schema.hpp
index 41af81e55b..e177d0dbd3 100644
--- a/platform/default/mbgl/storage/offline_schema.cpp.include
+++ b/platform/default/mbgl/storage/offline_schema.hpp
@@ -1,5 +1,11 @@
-/* THIS IS A GENERATED FILE; EDIT offline_schema.sql INSTEAD */
-static const char * schema =
+#pragma once
+
+// THIS IS A GENERATED FILE; EDIT offline_schema.sql INSTEAD
+// To regenerate, run `node platform/default/mbgl/storage/offline_schema.js`
+
+namespace mbgl {
+
+static constexpr const char* offlineDatabaseSchema =
"CREATE TABLE resources (\n"
" id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n"
" url TEXT NOT NULL,\n"
@@ -53,3 +59,5 @@ static const char * schema =
"CREATE INDEX region_tiles_tile_id\n"
"ON region_tiles (tile_id);\n"
;
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/storage/offline_schema.js b/platform/default/mbgl/storage/offline_schema.js
new file mode 100644
index 0000000000..fdb7dc6405
--- /dev/null
+++ b/platform/default/mbgl/storage/offline_schema.js
@@ -0,0 +1,21 @@
+var fs = require('fs');
+fs.writeFileSync('platform/default/mbgl/storage/offline_schema.hpp', `#pragma once
+
+// THIS IS A GENERATED FILE; EDIT offline_schema.sql INSTEAD
+// To regenerate, run \`node platform/default/mbgl/storage/offline_schema.js\`
+
+namespace mbgl {
+
+static constexpr const char* offlineDatabaseSchema =
+${fs.readFileSync('platform/default/mbgl/storage/offline_schema.sql', 'utf8')
+ .replace(/ *--.*/g, '')
+ .split('\n')
+ .filter(a => a)
+ .map(line => '"' + line + '\\n"')
+ .join('\n')
+}
+;
+
+} // namespace mbgl
+`);
+
diff --git a/platform/default/mbgl/storage/offline_schema.sql b/platform/default/mbgl/storage/offline_schema.sql
new file mode 100644
index 0000000000..722b0e0451
--- /dev/null
+++ b/platform/default/mbgl/storage/offline_schema.sql
@@ -0,0 +1,64 @@
+CREATE TABLE resources ( -- Generic table for style, source, sprite, and glyph resources.
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ url TEXT NOT NULL,
+ kind INTEGER NOT NULL,
+ expires INTEGER,
+ modified INTEGER,
+ etag TEXT,
+ data BLOB,
+ compressed INTEGER NOT NULL DEFAULT 0,
+ accessed INTEGER NOT NULL,
+ must_revalidate INTEGER NOT NULL DEFAULT 0,
+ UNIQUE (url)
+);
+
+CREATE TABLE tiles (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ url_template TEXT NOT NULL,
+ pixel_ratio INTEGER NOT NULL,
+ z INTEGER NOT NULL,
+ x INTEGER NOT NULL,
+ y INTEGER NOT NULL,
+ expires INTEGER,
+ modified INTEGER,
+ etag TEXT,
+ data BLOB,
+ compressed INTEGER NOT NULL DEFAULT 0,
+ accessed INTEGER NOT NULL,
+ must_revalidate INTEGER NOT NULL DEFAULT 0,
+ UNIQUE (url_template, pixel_ratio, z, x, y)
+);
+
+CREATE TABLE regions (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ definition TEXT NOT NULL, -- JSON formatted definition of region. Regions may be of variant types:
+ -- e.g. bbox and zoom range, route path, flyTo parameters, etc. Note that
+ -- the set of tiles required for a region may span multiple sources.
+ description BLOB -- User provided data in user-defined format
+);
+
+CREATE TABLE region_resources (
+ region_id INTEGER NOT NULL REFERENCES regions(id) ON DELETE CASCADE,
+ resource_id INTEGER NOT NULL REFERENCES resources(id),
+ UNIQUE (region_id, resource_id)
+);
+
+CREATE TABLE region_tiles (
+ region_id INTEGER NOT NULL REFERENCES regions(id) ON DELETE CASCADE,
+ tile_id INTEGER NOT NULL REFERENCES tiles(id),
+ UNIQUE (region_id, tile_id)
+);
+
+-- Indexes for efficient eviction queries
+
+CREATE INDEX resources_accessed
+ON resources (accessed);
+
+CREATE INDEX tiles_accessed
+ON tiles (accessed);
+
+CREATE INDEX region_resources_resource_id
+ON region_resources (resource_id);
+
+CREATE INDEX region_tiles_tile_id
+ON region_tiles (tile_id);
diff --git a/platform/default/sqlite3.cpp b/platform/default/sqlite3.cpp
index 8f9c34191f..2e76f6eec4 100644
--- a/platform/default/sqlite3.cpp
+++ b/platform/default/sqlite3.cpp
@@ -14,27 +14,23 @@ namespace sqlite {
class DatabaseImpl {
public:
- DatabaseImpl(const char* filename, int flags)
+ DatabaseImpl(sqlite3* db_)
+ : db(db_)
{
- const int error = sqlite3_open_v2(filename, &db, flags, nullptr);
- if (error != SQLITE_OK) {
- const auto message = sqlite3_errmsg(db);
- db = nullptr;
- throw Exception { error, message };
- }
}
~DatabaseImpl()
{
- if (!db) return;
-
const int error = sqlite3_close(db);
if (error != SQLITE_OK) {
mbgl::Log::Error(mbgl::Event::Database, "%s (Code %i)", sqlite3_errmsg(db), error);
}
}
- sqlite3* db = nullptr;
+ void setBusyTimeout(std::chrono::milliseconds timeout);
+ void exec(const std::string& sql);
+
+ sqlite3* db;
};
class StatementImpl {
@@ -69,84 +65,8 @@ public:
template <typename T>
using optional = std::experimental::optional<T>;
-static const char* codeToString(const int err) {
- switch (err) {
- case SQLITE_OK: return "SQLITE_OK";
- case SQLITE_ERROR: return "SQLITE_ERROR";
- case SQLITE_INTERNAL: return "SQLITE_INTERNAL";
- case SQLITE_PERM: return "SQLITE_PERM";
- case SQLITE_ABORT: return "SQLITE_ABORT";
- case SQLITE_BUSY: return "SQLITE_BUSY";
- case SQLITE_LOCKED: return "SQLITE_LOCKED";
- case SQLITE_NOMEM: return "SQLITE_NOMEM";
- case SQLITE_READONLY: return "SQLITE_READONLY";
- case SQLITE_INTERRUPT: return "SQLITE_INTERRUPT";
- case SQLITE_IOERR: return "SQLITE_IOERR";
- case SQLITE_CORRUPT: return "SQLITE_CORRUPT";
- case SQLITE_NOTFOUND: return "SQLITE_NOTFOUND";
- case SQLITE_FULL: return "SQLITE_FULL";
- case SQLITE_CANTOPEN: return "SQLITE_CANTOPEN";
- case SQLITE_PROTOCOL: return "SQLITE_PROTOCOL";
- case SQLITE_EMPTY: return "SQLITE_EMPTY";
- case SQLITE_SCHEMA: return "SQLITE_SCHEMA";
- case SQLITE_TOOBIG: return "SQLITE_TOOBIG";
- case SQLITE_CONSTRAINT: return "SQLITE_CONSTRAINT";
- case SQLITE_MISMATCH: return "SQLITE_MISMATCH";
- case SQLITE_MISUSE: return "SQLITE_MISUSE";
- case SQLITE_NOLFS: return "SQLITE_NOLFS";
- case SQLITE_AUTH: return "SQLITE_AUTH";
- case SQLITE_FORMAT: return "SQLITE_FORMAT";
- case SQLITE_RANGE: return "SQLITE_RANGE";
- case SQLITE_NOTADB: return "SQLITE_NOTADB";
- case SQLITE_NOTICE: return "SQLITE_NOTICE";
- case SQLITE_WARNING: return "SQLITE_WARNING";
- case SQLITE_ROW: return "SQLITE_ROW";
- case SQLITE_DONE: return "SQLITE_DONE";
- default: return "<unknown>";
- }
-}
-
static void errorLogCallback(void *, const int err, const char *msg) {
- auto severity = mbgl::EventSeverity::Info;
-
- switch (err) {
- case SQLITE_ERROR: // Generic error
- case SQLITE_INTERNAL: // Internal logic error in SQLite
- case SQLITE_PERM: // Access permission denied
- case SQLITE_ABORT: // Callback routine requested an abort
- case SQLITE_BUSY: // The database file is locked
- case SQLITE_LOCKED: // A table in the database is locked
- case SQLITE_NOMEM: // A malloc() failed
- case SQLITE_READONLY: // Attempt to write a readonly database
- case SQLITE_INTERRUPT: // Operation terminated by sqlite3_interrupt(
- case SQLITE_IOERR: // Some kind of disk I/O error occurred
- case SQLITE_CORRUPT: // The database disk image is malformed
- case SQLITE_NOTFOUND: // Unknown opcode in sqlite3_file_control()
- case SQLITE_FULL: // Insertion failed because database is full
- case SQLITE_CANTOPEN: // Unable to open the database file
- case SQLITE_PROTOCOL: // Database lock protocol error
- case SQLITE_EMPTY: // Internal use only
- case SQLITE_SCHEMA: // The database schema changed
- case SQLITE_TOOBIG: // String or BLOB exceeds size limit
- case SQLITE_CONSTRAINT: // Abort due to constraint violation
- case SQLITE_MISMATCH: // Data type mismatch
- case SQLITE_MISUSE: // Library used incorrectly
- case SQLITE_NOLFS: // Uses OS features not supported on host
- case SQLITE_AUTH: // Authorization denied
- case SQLITE_FORMAT: // Not used
- case SQLITE_RANGE: // 2nd parameter to sqlite3_bind out of range
- case SQLITE_NOTADB: // File opened that is not a database file
- severity = mbgl::EventSeverity::Error;
- break;
- case SQLITE_WARNING: // Warnings from sqlite3_log()
- severity = mbgl::EventSeverity::Warning;
- break;
- case SQLITE_NOTICE: // Notifications from sqlite3_log()
- default:
- break;
- }
-
- mbgl::Log::Record(severity, mbgl::Event::Database, "%s (%s)", msg, codeToString(err));
+ mbgl::Log::Record(mbgl::EventSeverity::Info, mbgl::Event::Database, err, "%s", msg);
}
const static bool sqliteVersionCheck __attribute__((unused)) = []() {
@@ -164,11 +84,29 @@ const static bool sqliteVersionCheck __attribute__((unused)) = []() {
return true;
}();
-Database::Database(const std::string &filename, int flags)
- : impl(std::make_unique<DatabaseImpl>(filename.c_str(), flags))
-{
+mapbox::util::variant<Database, Exception> Database::tryOpen(const std::string &filename, int flags) {
+ sqlite3* db = nullptr;
+ const int error = sqlite3_open_v2(filename.c_str(), &db, flags, nullptr);
+ if (error != SQLITE_OK) {
+ const auto message = sqlite3_errmsg(db);
+ return Exception { error, message };
+ }
+ return Database(std::make_unique<DatabaseImpl>(db));
+}
+
+Database Database::open(const std::string &filename, int flags) {
+ auto result = tryOpen(filename, flags);
+ if (result.is<Exception>()) {
+ throw result.get<Exception>();
+ } else {
+ return std::move(result.get<Database>());
+ }
}
+Database::Database(std::unique_ptr<DatabaseImpl> impl_)
+ : impl(std::move(impl_))
+{}
+
Database::Database(Database &&other)
: impl(std::move(other.impl)) {}
@@ -181,23 +119,31 @@ Database::~Database() = default;
void Database::setBusyTimeout(std::chrono::milliseconds timeout) {
assert(impl);
- const int err = sqlite3_busy_timeout(impl->db,
+ impl->setBusyTimeout(timeout);
+}
+
+void DatabaseImpl::setBusyTimeout(std::chrono::milliseconds timeout) {
+ const int err = sqlite3_busy_timeout(db,
int(std::min<std::chrono::milliseconds::rep>(timeout.count(), std::numeric_limits<int>::max())));
if (err != SQLITE_OK) {
- throw Exception { err, sqlite3_errmsg(impl->db) };
+ throw Exception { err, sqlite3_errmsg(db) };
}
}
void Database::exec(const std::string &sql) {
assert(impl);
+ impl->exec(sql);
+}
+
+void DatabaseImpl::exec(const std::string& sql) {
char *msg = nullptr;
- const int err = sqlite3_exec(impl->db, sql.c_str(), nullptr, nullptr, &msg);
+ const int err = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &msg);
if (msg) {
const std::string message = msg;
sqlite3_free(msg);
throw Exception { err, message };
} else if (err != SQLITE_OK) {
- throw Exception { err, sqlite3_errmsg(impl->db) };
+ throw Exception { err, sqlite3_errmsg(db) };
}
}
@@ -470,16 +416,16 @@ uint64_t Query::changes() const {
}
Transaction::Transaction(Database& db_, Mode mode)
- : db(db_) {
+ : dbImpl(*db_.impl) {
switch (mode) {
case Deferred:
- db.exec("BEGIN DEFERRED TRANSACTION");
+ dbImpl.exec("BEGIN DEFERRED TRANSACTION");
break;
case Immediate:
- db.exec("BEGIN IMMEDIATE TRANSACTION");
+ dbImpl.exec("BEGIN IMMEDIATE TRANSACTION");
break;
case Exclusive:
- db.exec("BEGIN EXCLUSIVE TRANSACTION");
+ dbImpl.exec("BEGIN EXCLUSIVE TRANSACTION");
break;
}
}
@@ -496,12 +442,12 @@ Transaction::~Transaction() {
void Transaction::commit() {
needRollback = false;
- db.exec("COMMIT TRANSACTION");
+ dbImpl.exec("COMMIT TRANSACTION");
}
void Transaction::rollback() {
needRollback = false;
- db.exec("ROLLBACK TRANSACTION");
+ dbImpl.exec("ROLLBACK TRANSACTION");
}
} // namespace sqlite
diff --git a/platform/default/sqlite3.hpp b/platform/default/sqlite3.hpp
index 20d09b550c..612e92acc6 100644
--- a/platform/default/sqlite3.hpp
+++ b/platform/default/sqlite3.hpp
@@ -5,18 +5,14 @@
#include <stdexcept>
#include <chrono>
#include <memory>
+#include <mapbox/variant.hpp>
namespace mapbox {
namespace sqlite {
enum OpenFlag : int {
- ReadOnly = 0x00000001,
- ReadWrite = 0x00000002,
- Create = 0x00000004,
- NoMutex = 0x00008000,
- FullMutex = 0x00010000,
- SharedCache = 0x00020000,
- PrivateCache = 0x00040000,
+ ReadOnly = 0b001,
+ ReadWriteCreate = 0b110,
};
enum class ResultCode : int {
@@ -68,14 +64,18 @@ class DatabaseImpl;
class Statement;
class StatementImpl;
class Query;
+class Transaction;
class Database {
private:
+ Database(std::unique_ptr<DatabaseImpl>);
Database(const Database &) = delete;
Database &operator=(const Database &) = delete;
public:
- Database(const std::string &filename, int flags = 0);
+ static mapbox::util::variant<Database, Exception> tryOpen(const std::string &filename, int flags = 0);
+ static Database open(const std::string &filename, int flags = 0);
+
Database(Database &&);
~Database();
Database &operator=(Database &&);
@@ -87,6 +87,7 @@ private:
std::unique_ptr<DatabaseImpl> impl;
friend class Statement;
+ friend class Transaction;
};
// A Statement object represents a prepared statement that can be run repeatedly run with a Query object.
@@ -169,7 +170,7 @@ public:
void rollback();
private:
- Database& db;
+ DatabaseImpl& dbImpl;
bool needRollback = true;
};
diff --git a/platform/default/string_stdlib.cpp b/platform/default/string_stdlib.cpp
index 2642e88aff..103444df1c 100644
--- a/platform/default/string_stdlib.cpp
+++ b/platform/default/string_stdlib.cpp
@@ -1,8 +1,5 @@
#include <mbgl/util/platform.hpp>
-#define NU_WITH_TOUPPER
-#define NU_WITH_TOLOWER
-#define NU_WITH_UTF8_WRITER
-#include <libnu/libnu.h>
+#include <libnu/casemap.h>
#include <cstring>
#include <sstream>
diff --git a/platform/default/unaccent.cpp b/platform/default/unaccent.cpp
new file mode 100644
index 0000000000..faefb4b4cd
--- /dev/null
+++ b/platform/default/unaccent.cpp
@@ -0,0 +1,43 @@
+#include <mbgl/util/platform.hpp>
+#include <libnu/unaccent.h>
+#include <unaccent.hpp>
+
+#include <cstring>
+#include <sstream>
+
+namespace mbgl { namespace platform {
+
+std::string unaccent(const std::string& str)
+{
+ std::stringstream output;
+ char const *itr = str.c_str(), *nitr;
+ char const *end = itr + str.length();
+ char lo[5] = { 0 };
+
+ for (; itr < end; itr = nitr)
+ {
+ uint32_t code_point = 0;
+ char const* buf = nullptr;
+
+ nitr = _nu_tounaccent(itr, end, nu_utf8_read, &code_point, &buf, nullptr);
+ if (buf != nullptr)
+ {
+ do
+ {
+ buf = NU_CASEMAP_DECODING_FUNCTION(buf, &code_point);
+ if (code_point == 0) break;
+ output.write(lo, nu_utf8_write(code_point, lo) - lo);
+ }
+ while (code_point != 0);
+ }
+ else
+ {
+ output.write(itr, nitr - itr);
+ }
+ }
+
+ return output.str();
+}
+
+} // namespace platform
+} // namespace mbgl
diff --git a/platform/default/unaccent.hpp b/platform/default/unaccent.hpp
new file mode 100644
index 0000000000..85ac37a7de
--- /dev/null
+++ b/platform/default/unaccent.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <string>
+
+namespace mbgl {
+namespace platform {
+
+// Non-locale-aware diacritic folding based on nunicode
+// Used as a fallback when locale-aware comparisons aren't available
+std::string unaccent(const std::string &string);
+
+} // namespace platform
+} // namespace mbgl
diff --git a/platform/qt/include/qmapboxgl.hpp b/platform/qt/include/qmapboxgl.hpp
index 79eb672d1f..a699b77cec 100644
--- a/platform/qt/include/qmapboxgl.hpp
+++ b/platform/qt/include/qmapboxgl.hpp
@@ -236,8 +236,10 @@ public:
bool layerExists(const QString &id);
void removeLayer(const QString &id);
- void setFilter(const QString &layer, const QVariant &filter);
+ QList<QString> layerIds() const;
+ void setFilter(const QString &layer, const QVariant &filter);
+ QVariant getFilter(const QString &layer) const;
// When rendering on a different thread,
// should be called on the render thread.
void createRenderer();
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index 8c3355dc09..09479581bb 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -55,6 +55,10 @@
#include <QString>
#include <QStringList>
#include <QThreadStorage>
+#include <QVariant>
+#include <QVariantList>
+#include <QVariantMap>
+#include <QColor>
#include <memory>
@@ -703,7 +707,7 @@ double QMapboxGL::scale() const
void QMapboxGL::setScale(double scale_, const QPointF &center)
{
- d_ptr->mapObj->setZoom(mbgl::util::log2(scale_), mbgl::ScreenCoordinate { center.x(), center.y() });
+ d_ptr->mapObj->setZoom(::log2(scale_), mbgl::ScreenCoordinate { center.x(), center.y() });
}
/*!
@@ -1111,7 +1115,7 @@ void QMapboxGL::moveBy(const QPointF &offset)
can be used for implementing a pinch gesture.
*/
void QMapboxGL::scaleBy(double scale_, const QPointF &center) {
- d_ptr->mapObj->setZoom(d_ptr->mapObj->getZoom() + mbgl::util::log2(scale_), mbgl::ScreenCoordinate { center.x(), center.y() });
+ d_ptr->mapObj->setZoom(d_ptr->mapObj->getZoom() + ::log2(scale_), mbgl::ScreenCoordinate { center.x(), center.y() });
}
/*!
@@ -1466,6 +1470,23 @@ void QMapboxGL::removeLayer(const QString& id)
}
/*!
+ List of all existing layer ids from the current style.
+*/
+QList<QString> QMapboxGL::layerIds() const
+{
+ const auto &layers = d_ptr->mapObj->getStyle().getLayers();
+
+ QList<QString> layerIds;
+ layerIds.reserve(layers.size());
+
+ for (const mbgl::style::Layer *layer : layers) {
+ layerIds.append(QString::fromStdString(layer->getID()));
+ }
+
+ return layerIds;
+}
+
+/*!
Adds the \a image with the identifier \a id that can be used
later by a symbol layer.
@@ -1492,7 +1513,7 @@ void QMapboxGL::removeImage(const QString &id)
/*!
Adds a \a filter to a style \a layer using the format described in the \l
- {https://www.mapbox.com/mapbox-gl-style-spec/#types-filter}{Mapbox style specification}.
+ {https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter}{Mapbox style specification}.
Given a layer \c marker from an arbitrary GeoJSON source containing features of type \b
"Point" and \b "LineString", this example shows how to make sure the layer will only tag
@@ -1500,14 +1521,14 @@ void QMapboxGL::removeImage(const QString &id)
\code
QVariantList filterExpression;
- filterExpression.append("==");
- filterExpression.append("$type");
- filterExpression.append("Point");
+ filterExpression.push_back(QLatin1String("=="));
+ filterExpression.push_back(QLatin1String("$type"));
+ filterExpression.push_back(QLatin1String("Point"));
QVariantList filter;
- filter.append(filterExpression);
+ filter.push_back(filterExpression);
- map->setFilter("marker", filter);
+ map->setFilter(QLatin1String("marker"), filter);
\endcode
*/
void QMapboxGL::setFilter(const QString& layer, const QVariant& filter)
@@ -1555,6 +1576,77 @@ void QMapboxGL::setFilter(const QString& layer, const QVariant& filter)
qWarning() << "Layer doesn't support filters";
}
+QVariant QVariantFromValue(const mbgl::Value &value) {
+ return value.match(
+ [](const mbgl::NullValue) {
+ return QVariant();
+ }, [](const bool value_) {
+ return QVariant(value_);
+ }, [](const float value_) {
+ return QVariant(value_);
+ }, [](const int64_t value_) {
+ return QVariant(static_cast<qlonglong>(value_));
+ }, [](const double value_) {
+ return QVariant(value_);
+ }, [](const std::string &value_) {
+ return QVariant(value_.c_str());
+ }, [](const mbgl::Color &value_) {
+ return QColor(value_.r, value_.g, value_.b, value_.a);
+ }, [&](const std::vector<mbgl::Value> &vector) {
+ QVariantList list;
+ list.reserve(vector.size());
+ for (const auto &value_ : vector) {
+ list.push_back(QVariantFromValue(value_));
+ }
+ return list;
+ }, [&](const std::unordered_map<std::string, mbgl::Value> &map) {
+ QVariantMap varMap;
+ for (auto &item : map) {
+ varMap.insert(item.first.c_str(), QVariantFromValue(item.second));
+ }
+ return varMap;
+ }, [](const auto &) {
+ return QVariant();
+ });
+}
+
+/*!
+ Returns the current \a expression-based filter value applied to a style
+ \layer, if any.
+
+ Filter value types are described in the {https://www.mapbox.com/mapbox-gl-js/style-spec/#types}{Mapbox style specification}.
+*/
+QVariant QMapboxGL::getFilter(const QString &layer) const {
+ using namespace mbgl::style;
+ using namespace mbgl::style::conversion;
+
+ Layer* layer_ = d_ptr->mapObj->getStyle().getLayer(layer.toStdString());
+ if (!layer_) {
+ qWarning() << "Layer not found:" << layer;
+ return QVariant();
+ }
+
+ Filter filter_;
+
+ if (layer_->is<FillLayer>()) {
+ filter_ = layer_->as<FillLayer>()->getFilter();
+ } else if (layer_->is<LineLayer>()) {
+ filter_ = layer_->as<LineLayer>()->getFilter();
+ } else if (layer_->is<SymbolLayer>()) {
+ filter_ = layer_->as<SymbolLayer>()->getFilter();
+ } else if (layer_->is<CircleLayer>()) {
+ filter_ = layer_->as<CircleLayer>()->getFilter();
+ } else if (layer_->is<FillExtrusionLayer>()) {
+ filter_ = layer_->as<FillExtrusionLayer>()->getFilter();
+ } else {
+ qWarning() << "Layer doesn't support filters";
+ return QVariant();
+ }
+
+ auto serialized = filter_.serialize();
+ return QVariantFromValue(serialized);
+}
+
/*!
Creates the infrastructure needed for rendering the map. It
should be called before any call to render().
diff --git a/platform/qt/src/qmapboxgl_map_renderer.cpp b/platform/qt/src/qmapboxgl_map_renderer.cpp
index 7a9d1f6f78..acc4194498 100644
--- a/platform/qt/src/qmapboxgl_map_renderer.cpp
+++ b/platform/qt/src/qmapboxgl_map_renderer.cpp
@@ -1,12 +1,47 @@
#include "qmapboxgl_map_renderer.hpp"
+#include "qmapboxgl_scheduler.hpp"
+#include <QThreadStorage>
#include <QtGlobal>
+static bool needsToForceScheduler() {
+ static QThreadStorage<bool> force;
+
+ if (!force.hasLocalData()) {
+ force.setLocalData(mbgl::Scheduler::GetCurrent() == nullptr);
+ }
+
+ return force.localData();
+};
+
+static auto *getScheduler() {
+ static QThreadStorage<std::shared_ptr<QMapboxGLScheduler>> scheduler;
+
+ if (!scheduler.hasLocalData()) {
+ scheduler.setLocalData(std::make_shared<QMapboxGLScheduler>());
+ }
+
+ return scheduler.localData().get();
+};
+
QMapboxGLMapRenderer::QMapboxGLMapRenderer(qreal pixelRatio,
mbgl::DefaultFileSource &fs, mbgl::ThreadPool &tp, QMapboxGLSettings::GLContextMode mode)
: m_renderer(std::make_unique<mbgl::Renderer>(m_backend, pixelRatio, fs, tp, static_cast<mbgl::GLContextMode>(mode)))
- , m_threadWithScheduler(Scheduler::GetCurrent() != nullptr)
+ , m_forceScheduler(needsToForceScheduler())
{
+ // If we don't have a Scheduler on this thread, which
+ // is usually the case for render threads, use a shared
+ // dummy scheduler that needs to be explicitly forced to
+ // process events.
+ if (m_forceScheduler) {
+ auto scheduler = getScheduler();
+
+ if (mbgl::Scheduler::GetCurrent() == nullptr) {
+ mbgl::Scheduler::SetCurrent(scheduler);
+ }
+
+ connect(scheduler, SIGNAL(needsProcessing()), this, SIGNAL(needsRendering()));
+ }
}
QMapboxGLMapRenderer::~QMapboxGLMapRenderer()
@@ -14,16 +49,6 @@ QMapboxGLMapRenderer::~QMapboxGLMapRenderer()
MBGL_VERIFY_THREAD(tid);
}
-void QMapboxGLMapRenderer::schedule(std::weak_ptr<mbgl::Mailbox> mailbox)
-{
- std::lock_guard<std::mutex> lock(m_taskQueueMutex);
- m_taskQueue.push(mailbox);
-
- // Need to force the main thread to wake
- // up this thread and process the events.
- emit needsRendering();
-}
-
void QMapboxGLMapRenderer::updateParameters(std::shared_ptr<mbgl::UpdateParameters> newParameters)
{
std::lock_guard<std::mutex> lock(m_updateMutex);
@@ -57,26 +82,10 @@ void QMapboxGLMapRenderer::render()
// The OpenGL implementation automatically enables the OpenGL context for us.
mbgl::BackendScope scope(m_backend, mbgl::BackendScope::ScopeType::Implicit);
- // If we don't have a Scheduler on this thread, which
- // is usually the case for render threads, use this
- // object as scheduler.
- if (!m_threadWithScheduler) {
- Scheduler::SetCurrent(this);
- }
-
m_renderer->render(*params);
- if (!m_threadWithScheduler) {
- std::queue<std::weak_ptr<mbgl::Mailbox>> taskQueue;
- {
- std::unique_lock<std::mutex> lock(m_taskQueueMutex);
- std::swap(taskQueue, m_taskQueue);
- }
-
- while (!taskQueue.empty()) {
- mbgl::Mailbox::maybeReceive(taskQueue.front());
- taskQueue.pop();
- }
+ if (m_forceScheduler) {
+ getScheduler()->processEvents();
}
}
diff --git a/platform/qt/src/qmapboxgl_map_renderer.hpp b/platform/qt/src/qmapboxgl_map_renderer.hpp
index adba11de51..0b17542e2f 100644
--- a/platform/qt/src/qmapboxgl_map_renderer.hpp
+++ b/platform/qt/src/qmapboxgl_map_renderer.hpp
@@ -14,7 +14,6 @@
#include <memory>
#include <mutex>
-#include <queue>
namespace mbgl {
class Renderer;
@@ -23,7 +22,7 @@ class UpdateParameters;
class QMapboxGLRendererBackend;
-class QMapboxGLMapRenderer : public QObject, public mbgl::Scheduler
+class QMapboxGLMapRenderer : public QObject
{
Q_OBJECT
@@ -32,9 +31,6 @@ public:
mbgl::ThreadPool &, QMapboxGLSettings::GLContextMode);
virtual ~QMapboxGLMapRenderer();
- // mbgl::Scheduler implementation.
- void schedule(std::weak_ptr<mbgl::Mailbox> scheduled) final;
-
void render();
void updateFramebuffer(quint32 fbo, const mbgl::Size &size);
void setObserver(std::shared_ptr<mbgl::RendererObserver>);
@@ -56,8 +52,5 @@ private:
QMapboxGLRendererBackend m_backend;
std::unique_ptr<mbgl::Renderer> m_renderer;
- std::mutex m_taskQueueMutex;
- std::queue<std::weak_ptr<mbgl::Mailbox>> m_taskQueue;
-
- bool m_threadWithScheduler;
+ bool m_forceScheduler;
};
diff --git a/platform/qt/src/qmapboxgl_scheduler.cpp b/platform/qt/src/qmapboxgl_scheduler.cpp
new file mode 100644
index 0000000000..e2d39703ee
--- /dev/null
+++ b/platform/qt/src/qmapboxgl_scheduler.cpp
@@ -0,0 +1,38 @@
+#include "qmapboxgl_scheduler.hpp"
+
+#include <mbgl/util/util.hpp>
+
+#include <cassert>
+
+QMapboxGLScheduler::QMapboxGLScheduler()
+{
+}
+
+QMapboxGLScheduler::~QMapboxGLScheduler()
+{
+ MBGL_VERIFY_THREAD(tid);
+}
+
+void QMapboxGLScheduler::schedule(std::weak_ptr<mbgl::Mailbox> mailbox)
+{
+ std::lock_guard<std::mutex> lock(m_taskQueueMutex);
+ m_taskQueue.push(mailbox);
+
+ // Need to force the main thread to wake
+ // up this thread and process the events.
+ emit needsProcessing();
+}
+
+void QMapboxGLScheduler::processEvents()
+{
+ std::queue<std::weak_ptr<mbgl::Mailbox>> taskQueue;
+ {
+ std::unique_lock<std::mutex> lock(m_taskQueueMutex);
+ std::swap(taskQueue, m_taskQueue);
+ }
+
+ while (!taskQueue.empty()) {
+ mbgl::Mailbox::maybeReceive(taskQueue.front());
+ taskQueue.pop();
+ }
+}
diff --git a/platform/qt/src/qmapboxgl_scheduler.hpp b/platform/qt/src/qmapboxgl_scheduler.hpp
new file mode 100644
index 0000000000..68636d0d11
--- /dev/null
+++ b/platform/qt/src/qmapboxgl_scheduler.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <mbgl/actor/mailbox.hpp>
+#include <mbgl/actor/scheduler.hpp>
+#include <mbgl/util/util.hpp>
+
+#include <QObject>
+
+#include <memory>
+#include <mutex>
+#include <queue>
+
+class QMapboxGLScheduler : public QObject, public mbgl::Scheduler
+{
+ Q_OBJECT
+
+public:
+ QMapboxGLScheduler();
+ virtual ~QMapboxGLScheduler();
+
+ // mbgl::Scheduler implementation.
+ void schedule(std::weak_ptr<mbgl::Mailbox> scheduled) final;
+
+ void processEvents();
+
+signals:
+ void needsProcessing();
+
+private:
+ MBGL_STORE_THREAD(tid);
+
+ std::mutex m_taskQueueMutex;
+ std::queue<std::weak_ptr<mbgl::Mailbox>> m_taskQueue;
+};
diff --git a/platform/qt/src/qt_geojson.cpp b/platform/qt/src/qt_geojson.cpp
index 80377de64d..9d0a3e96eb 100644
--- a/platform/qt/src/qt_geojson.cpp
+++ b/platform/qt/src/qt_geojson.cpp
@@ -72,10 +72,8 @@ mbgl::Value asMapboxGLPropertyValue(const QVariant &value) {
auto valueMap = [](const QVariantMap &map) {
std::unordered_map<std::string, mbgl::Value> mbglMap;
mbglMap.reserve(map.size());
- auto it = map.constBegin();
- while (it != map.constEnd()) {
+ for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
mbglMap.emplace(std::make_pair(it.key().toStdString(), asMapboxGLPropertyValue(it.value())));
- ++it;
}
return mbglMap;
};
@@ -132,8 +130,7 @@ mbgl::FeatureIdentifier asMapboxGLFeatureIdentifier(const QVariant &id) {
mbgl::Feature asMapboxGLFeature(const QMapbox::Feature &feature) {
mbgl::PropertyMap properties;
properties.reserve(feature.properties.size());
- auto it = feature.properties.constBegin();
- while (it != feature.properties.constEnd()) {
+ for (auto it = feature.properties.constBegin(); it != feature.properties.constEnd(); ++it) {
properties.emplace(std::make_pair(it.key().toStdString(), asMapboxGLPropertyValue(it.value())));
}
diff --git a/platform/qt/src/sqlite3.cpp b/platform/qt/src/sqlite3.cpp
index 4bcaea0e31..2ca09fd3ad 100644
--- a/platform/qt/src/sqlite3.cpp
+++ b/platform/qt/src/sqlite3.cpp
@@ -52,15 +52,6 @@ void checkDatabaseError(const QSqlDatabase &db) {
}
}
-void checkDatabaseOpenError(const QSqlDatabase &db) {
- // Assume every error when opening the data as CANTOPEN. Qt
- // always returns -1 for `nativeErrorCode()` on database errors.
- QSqlError lastError = db.lastError();
- if (lastError.type() != QSqlError::NoError) {
- throw Exception { ResultCode::CantOpen, "Error opening the database." };
- }
-}
-
namespace {
QString incrementCounter() {
static QAtomicInt count = 0;
@@ -70,32 +61,9 @@ namespace {
class DatabaseImpl {
public:
- DatabaseImpl(const char* filename, int flags)
- : connectionName(QString::number(uint64_t(QThread::currentThread())) + incrementCounter())
+ DatabaseImpl(QString connectionName_)
+ : connectionName(std::move(connectionName_))
{
- if (!QSqlDatabase::drivers().contains("QSQLITE")) {
- throw Exception { ResultCode::CantOpen, "SQLite driver not found." };
- }
-
- assert(!QSqlDatabase::contains(connectionName));
- auto db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
-
- QString connectOptions = db.connectOptions();
- if (flags & OpenFlag::ReadOnly) {
- if (!connectOptions.isEmpty()) connectOptions.append(';');
- connectOptions.append("QSQLITE_OPEN_READONLY");
- }
- if (flags & OpenFlag::SharedCache) {
- if (!connectOptions.isEmpty()) connectOptions.append(';');
- connectOptions.append("QSQLITE_ENABLE_SHARED_CACHE");
- }
-
- db.setConnectOptions(connectOptions);
- db.setDatabaseName(QString(filename));
-
- if (!db.open()) {
- checkDatabaseOpenError(db);
- }
}
~DatabaseImpl() {
@@ -104,6 +72,9 @@ public:
checkDatabaseError(db);
}
+ void setBusyTimeout(std::chrono::milliseconds timeout);
+ void exec(const std::string& sql);
+
QString connectionName;
};
@@ -127,12 +98,47 @@ public:
template <typename T>
using optional = std::experimental::optional<T>;
+mapbox::util::variant<Database, Exception> Database::tryOpen(const std::string &filename, int flags) {
+ if (!QSqlDatabase::drivers().contains("QSQLITE")) {
+ return Exception { ResultCode::CantOpen, "SQLite driver not found." };
+ }
-Database::Database(const std::string& file, int flags)
- : impl(std::make_unique<DatabaseImpl>(file.c_str(), flags)) {
- assert(impl);
+ QString connectionName = QString::number(uint64_t(QThread::currentThread())) + incrementCounter();
+
+ assert(!QSqlDatabase::contains(connectionName));
+ auto db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
+
+ QString connectOptions = db.connectOptions();
+ if (flags & OpenFlag::ReadOnly) {
+ if (!connectOptions.isEmpty()) connectOptions.append(';');
+ connectOptions.append("QSQLITE_OPEN_READONLY");
+ }
+
+ db.setConnectOptions(connectOptions);
+ db.setDatabaseName(QString(filename.c_str()));
+
+ if (!db.open()) {
+ // Assume every error when opening the data as CANTOPEN. Qt
+ // always returns -1 for `nativeErrorCode()` on database errors.
+ return Exception { ResultCode::CantOpen, "Error opening the database." };
+ }
+
+ return Database(std::make_unique<DatabaseImpl>(connectionName));
}
+Database Database::open(const std::string &filename, int flags) {
+ auto result = tryOpen(filename, flags);
+ if (result.is<Exception>()) {
+ throw result.get<Exception>();
+ } else {
+ return std::move(result.get<Database>());
+ }
+}
+
+Database::Database(std::unique_ptr<DatabaseImpl> impl_)
+ : impl(std::move(impl_))
+{}
+
Database::Database(Database &&other)
: impl(std::move(other.impl)) {
assert(impl);
@@ -149,12 +155,15 @@ Database::~Database() {
void Database::setBusyTimeout(std::chrono::milliseconds timeout) {
assert(impl);
+ impl->setBusyTimeout(timeout);
+}
+void DatabaseImpl::setBusyTimeout(std::chrono::milliseconds timeout) {
// std::chrono::milliseconds.count() is a long and Qt will cast
// internally to int, so we need to make sure the limits apply.
std::string timeoutStr = mbgl::util::toString(timeout.count() & INT_MAX);
- auto db = QSqlDatabase::database(impl->connectionName);
+ auto db = QSqlDatabase::database(connectionName);
QString connectOptions = db.connectOptions();
if (connectOptions.isEmpty()) {
if (!connectOptions.isEmpty()) connectOptions.append(';');
@@ -165,19 +174,25 @@ void Database::setBusyTimeout(std::chrono::milliseconds timeout) {
}
db.setConnectOptions(connectOptions);
if (!db.open()) {
- checkDatabaseOpenError(db);
+ // Assume every error when opening the data as CANTOPEN. Qt
+ // always returns -1 for `nativeErrorCode()` on database errors.
+ throw Exception { ResultCode::CantOpen, "Error opening the database." };
}
}
void Database::exec(const std::string &sql) {
assert(impl);
+ impl->exec(sql);
+}
+
+void DatabaseImpl::exec(const std::string& sql) {
QStringList statements = QString::fromStdString(sql).split(';', QString::SkipEmptyParts);
statements.removeAll("\n");
for (QString statement : statements) {
if (!statement.endsWith(';')) {
statement.append(';');
}
- QSqlQuery query(QSqlDatabase::database(impl->connectionName));
+ QSqlQuery query(QSqlDatabase::database(connectionName));
query.prepare(statement);
if (!query.exec()) {
@@ -424,16 +439,16 @@ uint64_t Query::changes() const {
}
Transaction::Transaction(Database& db_, Mode mode)
- : db(db_) {
+ : dbImpl(*db_.impl) {
switch (mode) {
case Deferred:
- db.exec("BEGIN DEFERRED TRANSACTION");
+ dbImpl.exec("BEGIN DEFERRED TRANSACTION");
break;
case Immediate:
- db.exec("BEGIN IMMEDIATE TRANSACTION");
+ dbImpl.exec("BEGIN IMMEDIATE TRANSACTION");
break;
case Exclusive:
- db.exec("BEGIN EXCLUSIVE TRANSACTION");
+ dbImpl.exec("BEGIN EXCLUSIVE TRANSACTION");
break;
}
}
@@ -450,12 +465,12 @@ Transaction::~Transaction() {
void Transaction::commit() {
needRollback = false;
- db.exec("COMMIT TRANSACTION");
+ dbImpl.exec("COMMIT TRANSACTION");
}
void Transaction::rollback() {
needRollback = false;
- db.exec("ROLLBACK TRANSACTION");
+ dbImpl.exec("ROLLBACK TRANSACTION");
}
} // namespace sqlite
diff --git a/qt_attribution.json b/qt_attribution.json
index 7ca84ae92b..d56b716a33 100644
--- a/qt_attribution.json
+++ b/qt_attribution.json
@@ -256,5 +256,18 @@
"LicenseId": "MIT",
"License": "MIT License",
"Copyright": "Copyright (c) 2010-2015, Angus Johnson, 2016 Mapbox"
+ },
+ {
+ "Id": "mapboxgl-nunicode",
+ "Name": "nunicode",
+ "QDocModule": "qtlocation",
+ "QtUsage": "Used in the Mapbox GL plugin of Qt Location.",
+
+ "Path": "vendor/nunicode",
+ "Description": "nunicode is i18n library implementing Unicode 11.0.",
+ "Homepage": "https://bitbucket.org/alekseyt/nunicode.git",
+ "LicenseId": "MIT",
+ "License": "MIT License",
+ "Copyright": "Copyright (c) 2013 Aleksey Tulinov <aleksey.tulinov@gmail.com>"
}
]
diff --git a/src/csscolorparser/csscolorparser.cpp b/src/csscolorparser/csscolorparser.cpp
index 4d1c6a3d65..106dae6cef 100644
--- a/src/csscolorparser/csscolorparser.cpp
+++ b/src/csscolorparser/csscolorparser.cpp
@@ -185,7 +185,6 @@ optional<Color> parse(const std::string& css_str) {
// Convert to lowercase.
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
-
for (const auto& namedColor : namedColors) {
if (str == namedColor.name) {
return { namedColor.color };
@@ -262,8 +261,9 @@ optional<Color> parse(const std::string& css_str) {
}
float h = parseFloat(params[0]) / 360.0f;
- while (h < 0.0f) h++;
- while (h > 1.0f) h--;
+ float i;
+ // Normalize the hue to [0..1[
+ h = std::modf(h, &i);
// NOTE(deanm): According to the CSS spec s/l should only be
// percentages, but we don't bother and let float or percentage.
diff --git a/src/mbgl/actor/mailbox.cpp b/src/mbgl/actor/mailbox.cpp
index 373c24275f..8ee8dca114 100644
--- a/src/mbgl/actor/mailbox.cpp
+++ b/src/mbgl/actor/mailbox.cpp
@@ -6,8 +6,30 @@
namespace mbgl {
+Mailbox::Mailbox() {
+}
+
Mailbox::Mailbox(Scheduler& scheduler_)
- : scheduler(scheduler_) {
+ : scheduler(&scheduler_) {
+}
+
+void Mailbox::open(Scheduler& scheduler_) {
+ assert(!scheduler);
+
+ // As with close(), block until neither receive() nor push() are in progress, and acquire the two
+ // mutexes in the same order.
+ std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
+ std::lock_guard<std::mutex> pushingLock(pushingMutex);
+
+ scheduler = &scheduler_;
+
+ if (closed) {
+ return;
+ }
+
+ if (!queue.empty()) {
+ (*scheduler)->schedule(shared_from_this());
+ }
}
void Mailbox::close() {
@@ -22,6 +44,9 @@ void Mailbox::close() {
closed = true;
}
+bool Mailbox::isOpen() const { return bool(scheduler); }
+
+
void Mailbox::push(std::unique_ptr<Message> message) {
std::lock_guard<std::mutex> pushingLock(pushingMutex);
@@ -32,13 +57,15 @@ void Mailbox::push(std::unique_ptr<Message> message) {
std::lock_guard<std::mutex> queueLock(queueMutex);
bool wasEmpty = queue.empty();
queue.push(std::move(message));
- if (wasEmpty) {
- scheduler.schedule(shared_from_this());
+ if (wasEmpty && scheduler) {
+ (*scheduler)->schedule(shared_from_this());
}
}
void Mailbox::receive() {
std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex);
+
+ assert(scheduler);
if (closed) {
return;
@@ -58,7 +85,7 @@ void Mailbox::receive() {
(*message)();
if (!wasEmpty) {
- scheduler.schedule(shared_from_this());
+ (*scheduler)->schedule(shared_from_this());
}
}
diff --git a/src/mbgl/algorithm/covered_by_children.hpp b/src/mbgl/algorithm/covered_by_children.hpp
index ad2f1dd5dd..fe5af3f3db 100644
--- a/src/mbgl/algorithm/covered_by_children.hpp
+++ b/src/mbgl/algorithm/covered_by_children.hpp
@@ -8,15 +8,23 @@ namespace algorithm {
template <typename Iterator>
bool coveredByChildren(const UnwrappedTileID& id, Iterator it, const Iterator& end) {
for (const auto& child : id.children()) {
- it = std::lower_bound(it, end, child, [](auto& a, auto& b) { return std::get<0>(a) < b; });
+ it = std::lower_bound(it, end, child, [](const auto& a, const auto& b) { return std::get<0>(a) < b; });
+
+ // Child is not present, neither its grandchildren.
if (it == end) {
return false;
- } else if (std::get<0>(*it) != child) {
- return coveredByChildren(child, it, end);
+ }
+
+ // Child is not present, but its grandchildren are.
+ if (std::get<0>(*it) != child) {
+ // This child is not covered by its grandchildren.
+ if (!coveredByChildren(child, it, end)) {
+ return false;
+ }
}
}
- // We looked at all four immediate children and verified that they're covered.
+ // We looked at all four children (recursively) and verified that they're covered.
return true;
}
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index b94b0a1bce..41eedf17dc 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -8,6 +8,7 @@
#include <mbgl/style/style_impl.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
+#include <mbgl/style/expression/dsl.hpp>
#include <mbgl/storage/file_source.hpp>
#include <boost/function_output_iterator.hpp>
@@ -160,8 +161,9 @@ void AnnotationManager::updateStyle() {
std::unique_ptr<SymbolLayer> layer = std::make_unique<SymbolLayer>(PointLayerID, SourceID);
+ using namespace expression::dsl;
layer->setSourceLayer(PointLayerID);
- layer->setIconImage({SourceID + ".{sprite}"});
+ layer->setIconImage(PropertyExpression<std::string>(concat(vec(literal(SourceID + "."), toString(get("sprite"))))));
layer->setIconAllowOverlap(true);
layer->setIconIgnorePlacement(true);
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index fdd9558d0b..651e3b9c56 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -7,7 +7,6 @@
#include <mbgl/util/math.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/style/filter.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mapbox/geometry/envelope.hpp>
@@ -78,11 +77,12 @@ void FeatureIndex::query(
}
}
-std::unordered_map<std::string, std::vector<Feature>> FeatureIndex::lookupSymbolFeatures(const std::vector<IndexedSubfeature>& symbolFeatures,
- const RenderedQueryOptions& queryOptions,
- const std::vector<const RenderLayer*>& layers,
- const OverscaledTileID& tileID,
- const std::shared_ptr<std::vector<size_t>>& featureSortOrder) const {
+std::unordered_map<std::string, std::vector<Feature>>
+FeatureIndex::lookupSymbolFeatures(const std::vector<IndexedSubfeature>& symbolFeatures,
+ const RenderedQueryOptions& queryOptions,
+ const std::vector<const RenderLayer*>& layers,
+ const OverscaledTileID& tileID,
+ const std::shared_ptr<std::vector<size_t>>& featureSortOrder) const {
std::unordered_map<std::string, std::vector<Feature>> result;
if (!tileData) {
return result;
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index 71a855b943..1129bd0b20 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -41,6 +41,10 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
const uint8_t dashheight = 2 * n + 1;
const uint8_t offset = 128;
+ if (dasharray.size() < 2) {
+ return LinePatternPos();
+ }
+
if (nextRow + dashheight > image.size.height) {
Log::Warning(Event::OpenGL, "line atlas bitmap overflow");
return LinePatternPos();
@@ -73,6 +77,9 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
while (right < x / stretch) {
left = right;
+ if (partIndex >= dasharray.size()) {
+ return LinePatternPos();
+ }
right = right + dasharray[partIndex];
if (oddLength && partIndex == dasharray.size() - 1) {
diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp
index bb5b2ddc34..b2d05fe665 100644
--- a/src/mbgl/gl/attribute.cpp
+++ b/src/mbgl/gl/attribute.cpp
@@ -1,14 +1,20 @@
#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/context.hpp>
#include <mbgl/gl/gl.hpp>
namespace mbgl {
namespace gl {
-void bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) {
- if (location >= MAX_ATTRIBUTES) {
- throw gl::Error("too many vertex attributes");
+void bindAttributeLocation(Context& context, ProgramID id, AttributeLocation location, const char* name) {
+ // We're using sequentially numberered attribute locations starting with 0. Therefore we can use
+ // the location as a proxy for the number of attributes.
+ if (location >= context.maximumVertexBindingCount) {
+ // Don't bind the location on this hardware since it exceeds the limit (otherwise we'd get
+ // an OpenGL error). This means we'll see rendering errors, and possibly slow rendering due
+ // to unbound attributes.
+ } else {
+ MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name));
}
- MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name));
}
std::set<std::string> getActiveAttributes(ProgramID id) {
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
index fa6c2ddeab..3763f0a583 100644
--- a/src/mbgl/gl/attribute.hpp
+++ b/src/mbgl/gl/attribute.hpp
@@ -17,8 +17,6 @@
namespace mbgl {
namespace gl {
-static constexpr std::size_t MAX_ATTRIBUTES = 8;
-
template <class> struct DataTypeOf;
template <> struct DataTypeOf< int8_t> : std::integral_constant<DataType, DataType::Byte> {};
template <> struct DataTypeOf<uint8_t> : std::integral_constant<DataType, DataType::UnsignedByte> {};
@@ -45,7 +43,7 @@ public:
}
};
-using AttributeBindingArray = std::array<optional<AttributeBinding>, MAX_ATTRIBUTES>;
+using AttributeBindingArray = std::vector<optional<AttributeBinding>>;
/*
gl::Attribute<T,N> manages the binding of a vertex buffer to a GL program attribute.
@@ -214,7 +212,8 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = {
} // namespace detail
-void bindAttributeLocation(ProgramID, AttributeLocation, const char * name);
+class Context;
+void bindAttributeLocation(Context&, ProgramID, AttributeLocation, const char * name);
std::set<std::string> getActiveAttributes(ProgramID);
template <class... As>
@@ -231,13 +230,13 @@ public:
using Vertex = detail::Vertex<typename As::Type...>;
- static Locations bindLocations(const ProgramID& id) {
+ static Locations bindLocations(Context& context, const ProgramID& id) {
std::set<std::string> activeAttributes = getActiveAttributes(id);
AttributeLocation location = 0;
auto maybeBindLocation = [&](const char* name) -> optional<AttributeLocation> {
if (activeAttributes.count(name)) {
- bindAttributeLocation(id, location, name);
+ bindAttributeLocation(context, id, location, name);
return location++;
} else {
return {};
@@ -277,6 +276,7 @@ public:
static AttributeBindingArray toBindingArray(const Locations& locations, const Bindings& bindings) {
AttributeBindingArray result;
+ result.resize(sizeof...(As));
auto maybeAddBinding = [&] (const optional<AttributeLocation>& location,
const optional<AttributeBinding>& binding) {
@@ -289,6 +289,12 @@ public:
return result;
}
+
+ static uint32_t activeBindingCount(const Bindings& bindings) {
+ uint32_t result = 0;
+ util::ignore({ ((result += bool(bindings.template get<As>())), 0)... });
+ return result;
+ }
};
namespace detail {
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index ba44adb42b..4afbe5af1e 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -94,7 +94,13 @@ static_assert(underlying_type(BufferUsage::DynamicDraw) == GL_DYNAMIC_DRAW, "Ope
static_assert(std::is_same<BinaryProgramFormat, GLenum>::value, "OpenGL type mismatch");
-Context::Context() = default;
+Context::Context()
+ : maximumVertexBindingCount([] {
+ GLint value;
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value));
+ return value;
+ }()) {
+}
Context::~Context() {
if (cleanupOnDestruction) {
@@ -281,7 +287,7 @@ UniqueTexture Context::createTexture() {
bool Context::supportsVertexArrays() const {
static bool blacklisted = []() {
- const std::string renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ const std::string renderer = reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_RENDERER)));
Log::Info(Event::General, "GPU Identifier: %s", renderer.c_str());
@@ -312,7 +318,7 @@ bool Context::supportsProgramBinaries() const {
// https://chromium.googlesource.com/chromium/src/gpu/+/master/config/gpu_driver_bug_list.json#2316
// Blacklist Vivante GC4000 due to bugs when linking loaded programs:
// https://github.com/mapbox/mapbox-gl-native/issues/10704
- const std::string renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ const std::string renderer = reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_RENDERER)));
if (renderer.find("Adreno (TM) 3") != std::string::npos
|| renderer.find("Adreno (TM) 4") != std::string::npos
|| renderer.find("Adreno (TM) 5") != std::string::npos
@@ -351,7 +357,7 @@ VertexArray Context::createVertexArray() {
VertexArrayID id = 0;
MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id));
UniqueVertexArray vao(std::move(id), { this });
- return { UniqueVertexArrayState(new VertexArrayState(std::move(vao), *this), VertexArrayStateDeleter { true })};
+ return { UniqueVertexArrayState(new VertexArrayState(std::move(vao)), VertexArrayStateDeleter { true })};
} else {
// On GL implementations which do not support vertex arrays, attribute bindings are global state.
// So return a VertexArray which shares our global state tracking and whose deleter is a no-op.
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 67624288e2..c8181d7e80 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -36,10 +36,12 @@ class Debugging;
class ProgramBinary;
} // namespace extension
-class Context : private util::noncopyable {
+class Context {
public:
Context();
~Context();
+ Context(const Context&) = delete;
+ Context& operator=(const Context& other) = delete;
void initializeExtensions(const std::function<gl::ProcAddress(const char*)>&);
@@ -226,7 +228,7 @@ public:
State<value::BindVertexBuffer> vertexBuffer;
State<value::BindVertexArray, const Context&> bindVertexArray { *this };
- VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }), *this };
+ VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }) };
State<value::PixelStorePack> pixelStorePack;
State<value::PixelStoreUnpack> pixelStoreUnpack;
@@ -239,6 +241,8 @@ public:
#endif // MBGL_USE_GLES2
bool supportsHalfFloatTextures = false;
+ const uint32_t maximumVertexBindingCount;
+ static constexpr const uint32_t minimumRequiredVertexBindingCount = 8;
private:
State<value::StencilFunc> stencilFunc;
diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp
index af02ad3d54..f33501cd11 100644
--- a/src/mbgl/gl/program.hpp
+++ b/src/mbgl/gl/program.hpp
@@ -35,7 +35,7 @@ public:
context.createProgram(context.createShader(ShaderType::Vertex, vertexSource),
context.createShader(ShaderType::Fragment, fragmentSource))),
uniformsState((context.linkProgram(program), Uniforms::bindLocations(program))),
- attributeLocations(Attributes::bindLocations(program)) {
+ attributeLocations(Attributes::bindLocations(context, program)) {
// Re-link program after manually binding only active attributes in Attributes::bindLocations
context.linkProgram(program);
diff --git a/src/mbgl/gl/vertex_array.cpp b/src/mbgl/gl/vertex_array.cpp
index 68a500ac45..d552a8292e 100644
--- a/src/mbgl/gl/vertex_array.cpp
+++ b/src/mbgl/gl/vertex_array.cpp
@@ -9,7 +9,11 @@ void VertexArray::bind(Context& context, BufferID indexBuffer, const AttributeBi
context.bindVertexArray = state->vertexArray;
state->indexBuffer = indexBuffer;
- for (AttributeLocation location = 0; location < MAX_ATTRIBUTES; ++location) {
+ state->bindings.reserve(bindings.size());
+ for (AttributeLocation location = 0; location < bindings.size(); ++location) {
+ if (state->bindings.size() <= location) {
+ state->bindings.emplace_back(context, AttributeLocation(location));
+ }
state->bindings[location] = bindings[location];
}
}
diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp
index 46c67017bb..604754f672 100644
--- a/src/mbgl/gl/vertex_array.hpp
+++ b/src/mbgl/gl/vertex_array.hpp
@@ -15,9 +15,8 @@ class Context;
class VertexArrayState {
public:
- VertexArrayState(UniqueVertexArray vertexArray_, Context& context)
- : vertexArray(std::move(vertexArray_)),
- bindings(makeBindings(context, std::make_index_sequence<MAX_ATTRIBUTES>())) {
+ VertexArrayState(UniqueVertexArray vertexArray_)
+ : vertexArray(std::move(vertexArray_)) {
}
void setDirty() {
@@ -31,13 +30,7 @@ public:
State<value::BindElementBuffer> indexBuffer;
using AttributeState = State<value::VertexAttribute, Context&, AttributeLocation>;
- std::array<AttributeState, MAX_ATTRIBUTES> bindings;
-
-private:
- template <std::size_t... I>
- std::array<AttributeState, MAX_ATTRIBUTES> makeBindings(Context& context, std::index_sequence<I...>) {
- return {{ AttributeState { context, I }... }};
- }
+ std::vector<AttributeState> bindings;
};
class VertexArrayStateDeleter {
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index 7dfa8edf43..a9b4b929ec 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -11,7 +11,6 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
optional<PositionedIcon> shapedIcon,
const SymbolLayoutProperties::Evaluated& layout,
const float layoutTextSize,
- const uint32_t index_,
const float textBoxScale,
const float textPadding,
const SymbolPlacementType textPlacement,
@@ -21,19 +20,20 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
const std::array<float, 2> iconOffset_,
const GlyphPositionMap& positions,
const IndexedSubfeature& indexedFeature,
- const std::size_t featureIndex_,
+ const std::size_t layoutFeatureIndex_,
+ const std::size_t dataFeatureIndex_,
const std::u16string& key_,
const float overscaling) :
anchor(anchor_),
line(line_),
- index(index_),
hasText(false),
hasIcon(shapedIcon),
// Create the collision features that will be used to check whether this symbol instance can be placed
textCollisionFeature(line_, anchor, shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature, overscaling),
iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature),
- featureIndex(featureIndex_),
+ layoutFeatureIndex(layoutFeatureIndex_),
+ dataFeatureIndex(dataFeatureIndex_),
textOffset(textOffset_),
iconOffset(iconOffset_),
key(key_) {
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 827a5dbbdb..ae79311790 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -19,7 +19,6 @@ public:
optional<PositionedIcon> shapedIcon,
const style::SymbolLayoutProperties::Evaluated&,
const float layoutTextSize,
- const uint32_t index,
const float textBoxScale,
const float textPadding,
style::SymbolPlacementType textPlacement,
@@ -29,13 +28,13 @@ public:
const std::array<float, 2> iconOffset,
const GlyphPositionMap&,
const IndexedSubfeature&,
- const std::size_t featureIndex,
+ const std::size_t layoutFeatureIndex,
+ const std::size_t dataFeatureIndex,
const std::u16string& key,
const float overscaling);
Anchor anchor;
GeometryCoordinates line;
- uint32_t index;
bool hasText;
bool hasIcon;
SymbolQuads horizontalGlyphQuads;
@@ -44,7 +43,8 @@ public:
CollisionFeature textCollisionFeature;
CollisionFeature iconCollisionFeature;
WritingModeType writingModes;
- std::size_t featureIndex;
+ std::size_t layoutFeatureIndex; // Index into the set of features included at layout time
+ std::size_t dataFeatureIndex; // Index into the underlying tile data feature set
std::array<float, 2> textOffset;
std::array<float, 2> iconOffset;
std::u16string key;
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index b2f6fd450f..41469f293d 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -2,7 +2,6 @@
#include <mbgl/layout/merge_lines.hpp>
#include <mbgl/layout/clip_lines.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/image_atlas.hpp>
@@ -11,7 +10,6 @@
#include <mbgl/text/shaping.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/utf.hpp>
-#include <mbgl/util/token.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
@@ -59,7 +57,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom));
if (layout.get<IconRotationAlignment>() == AlignmentType::Auto) {
- if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ if (layout.get<SymbolPlacement>() != SymbolPlacementType::Point) {
layout.get<IconRotationAlignment>() = AlignmentType::Map;
} else {
layout.get<IconRotationAlignment>() = AlignmentType::Viewport;
@@ -67,7 +65,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
}
if (layout.get<TextRotationAlignment>() == AlignmentType::Auto) {
- if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ if (layout.get<SymbolPlacement>() != SymbolPlacementType::Point) {
layout.get<TextRotationAlignment>() = AlignmentType::Map;
} else {
layout.get<TextRotationAlignment>() = AlignmentType::Viewport;
@@ -107,31 +105,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
ft.index = i;
- auto getValue = [&ft](const std::string& key) -> std::string {
- auto value = ft.getValue(key);
- if (!value)
- return std::string();
- if (value->is<std::string>())
- return value->get<std::string>();
- if (value->is<bool>())
- return value->get<bool>() ? "true" : "false";
- if (value->is<int64_t>())
- return util::toString(value->get<int64_t>());
- if (value->is<uint64_t>())
- return util::toString(value->get<uint64_t>());
- if (value->is<double>())
- return util::toString(value->get<double>());
- return "null";
- };
-
if (hasText) {
std::string u8string = layout.evaluate<TextField>(zoom, ft);
- if (layout.get<TextField>().isConstant() && !leader.layout.get<TextField>().isExpression()) {
- u8string = util::replaceTokens(u8string, getValue);
- }
-
- auto textTransform = layout.evaluate<TextTransform>(zoom, ft);
+ auto textTransform = layout.evaluate<TextTransform>(zoom, ft);
if (textTransform == TextTransformType::Uppercase) {
u8string = platform::uppercase(u8string);
} else if (textTransform == TextTransformType::Lowercase) {
@@ -140,7 +117,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
ft.text = applyArabicShaping(util::utf8_to_utf16::convert(u8string));
const bool canVerticalizeText = layout.get<TextRotationAlignment>() == AlignmentType::Map
- && layout.get<SymbolPlacement>() == SymbolPlacementType::Line
+ && layout.get<SymbolPlacement>() != SymbolPlacementType::Point
&& util::i18n::allowsVerticalWritingMode(*ft.text);
FontStack fontStack = layout.evaluate<TextFont>(zoom, ft);
@@ -158,11 +135,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
}
if (hasIcon) {
- std::string icon = layout.evaluate<IconImage>(zoom, ft);
- if (layout.get<IconImage>().isConstant() && !leader.layout.get<IconImage>().isExpression()) {
- icon = util::replaceTokens(icon, getValue);
- }
- ft.icon = icon;
+ ft.icon = layout.evaluate<IconImage>(zoom, ft);
imageDependencies.insert(*ft.icon);
}
@@ -183,7 +156,7 @@ bool SymbolLayout::hasSymbolInstances() const {
void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions,
const ImageMap& imageMap, const ImagePositions& imagePositions) {
const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map &&
- layout.get<SymbolPlacement>() == SymbolPlacementType::Line;
+ layout.get<SymbolPlacement>() != SymbolPlacementType::Point;
for (auto it = features.begin(); it != features.end(); ++it) {
auto& feature = *it;
@@ -208,7 +181,7 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph
const float oneEm = 24.0f;
const Shaping result = getShaping(
/* string */ text,
- /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ?
+ /* maxWidth: ems */ layout.get<SymbolPlacement>() == SymbolPlacementType::Point ?
layout.evaluate<TextMaxWidth>(zoom, feature) * oneEm : 0,
/* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm,
/* anchor */ layout.evaluate<TextAnchor>(zoom, feature),
@@ -261,7 +234,7 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph
compareText.clear();
}
-void SymbolLayout::addFeature(const std::size_t index,
+void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const SymbolFeature& feature,
const std::pair<Shaping, Shaping>& shapedTextOrientations,
optional<PositionedIcon> shapedIcon,
@@ -285,6 +258,10 @@ void SymbolLayout::addFeature(const std::size_t index,
const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize;
const float iconBoxScale = tilePixelRatio * layoutIconSize;
const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>();
+ // CJL: I'm not sure why SymbolPlacementType::Line -> avoidEdges = false. It seems redundant since
+ // getAnchors will already avoid generating anchors outside the tile bounds.
+ // However, SymbolPlacementType::LineCenter allows anchors outside tile boundaries, so its behavior
+ // here should match SymbolPlacement::Point
const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line;
const float textPadding = layout.get<TextPadding>() * tilePixelRatio;
const float iconPadding = layout.get<IconPadding>() * tilePixelRatio;
@@ -318,10 +295,9 @@ void SymbolLayout::addFeature(const std::size_t index,
if (mode == MapMode::Tile || withinPlus0) {
symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon,
layout.evaluate(zoom, feature), layoutTextSize,
- symbolInstances.size(),
textBoxScale, textPadding, textPlacement, textOffset,
iconBoxScale, iconPadding, iconOffset,
- glyphPositionMap, indexedFeature, index, feature.text.value_or(std::u16string()), overscaling);
+ glyphPositionMap, indexedFeature, layoutFeatureIndex, feature.index, feature.text.value_or(std::u16string()), overscaling);
}
};
@@ -347,6 +323,24 @@ void SymbolLayout::addFeature(const std::size_t index,
}
}
}
+ } else if (layout.get<SymbolPlacement>() == SymbolPlacementType::LineCenter) {
+ // No clipping, multiple lines per feature are allowed
+ // "lines" with only one point are ignored as in clipLines
+ for (const auto& line : feature.geometry) {
+ if (line.size() > 1) {
+ optional<Anchor> anchor = getCenterAnchor(line,
+ textMaxAngle,
+ (shapedTextOrientations.second ?: shapedTextOrientations.first).left,
+ (shapedTextOrientations.second ?: shapedTextOrientations.first).right,
+ (shapedIcon ? shapedIcon->left() : 0),
+ (shapedIcon ? shapedIcon->right() : 0),
+ glyphSize,
+ textMaxBoxScale);
+ if (anchor) {
+ addSymbolInstance(line, *anchor);
+ }
+ }
+ }
} else if (type == FeatureType::Polygon) {
for (const auto& polygon : classifyRings(feature.geometry)) {
Polygon<double> poly;
@@ -427,7 +421,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes)
const bool hasText = symbolInstance.hasText;
const bool hasIcon = symbolInstance.hasIcon;
- const auto& feature = features.at(symbolInstance.featureIndex);
+ const auto& feature = features.at(symbolInstance.layoutFeatureIndex);
// Insert final placement into collision tree and add glyphs/icons to buffers
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index d81544eed5..c177299485 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -364,13 +364,13 @@ void Map::setLatLngZoom(const LatLng& latLng, double zoom, const EdgeInsets& pad
impl->onUpdate();
}
-CameraOptions Map::cameraForLatLngBounds(const LatLngBounds& bounds, const EdgeInsets& padding, optional<double> bearing) const {
+CameraOptions Map::cameraForLatLngBounds(const LatLngBounds& bounds, const EdgeInsets& padding, optional<double> bearing, optional<double> pitch) const {
return cameraForLatLngs({
bounds.northwest(),
bounds.southwest(),
bounds.southeast(),
bounds.northeast(),
- }, padding, bearing);
+ }, padding, bearing, pitch);
}
CameraOptions cameraForLatLngs(const std::vector<LatLng>& latLngs, const Transform& transform, const EdgeInsets& padding) {
@@ -402,7 +402,7 @@ CameraOptions cameraForLatLngs(const std::vector<LatLng>& latLngs, const Transfo
scaleY -= (padding.top() + padding.bottom()) / height;
minScale = util::min(scaleX, scaleY);
}
- double zoom = transform.getZoom() + util::log2(minScale);
+ double zoom = transform.getZoom() + ::log2(minScale);
zoom = util::clamp(zoom, transform.getState().getMinZoom(), transform.getState().getMaxZoom());
// Calculate the center point of a virtual bounds that is extended in all directions by padding.
@@ -426,26 +426,37 @@ CameraOptions cameraForLatLngs(const std::vector<LatLng>& latLngs, const Transfo
return options;
}
-CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, const EdgeInsets& padding, optional<double> bearing) const {
- if(bearing) {
- double angle = -*bearing * util::DEG2RAD; // Convert to radians
- Transform transform(impl->transform.getState());
- transform.setAngle(angle);
- CameraOptions options = mbgl::cameraForLatLngs(latLngs, transform, padding);
- options.angle = angle;
- return options;
- } else {
+CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, const EdgeInsets& padding, optional<double> bearing, optional<double> pitch) const {
+
+ if (!bearing && !pitch) {
return mbgl::cameraForLatLngs(latLngs, impl->transform, padding);
}
+
+ Transform transform(impl->transform.getState());
+
+ if (bearing) {
+ double angle = -*bearing * util::DEG2RAD; // Convert to radians
+ transform.setAngle(angle);
+ }
+ if (pitch) {
+ double pitchAsRadian = *pitch * util::DEG2RAD; // Convert to radians
+ transform.setPitch(pitchAsRadian);
+ }
+
+ CameraOptions options = mbgl::cameraForLatLngs(latLngs, transform, padding);
+ options.angle = transform.getAngle();
+ options.pitch = transform.getPitch();
+
+ return options;
}
-CameraOptions Map::cameraForGeometry(const Geometry<double>& geometry, const EdgeInsets& padding, optional<double> bearing) const {
+CameraOptions Map::cameraForGeometry(const Geometry<double>& geometry, const EdgeInsets& padding, optional<double> bearing, optional<double> pitch) const {
std::vector<LatLng> latLngs;
forEachPoint(geometry, [&](const Point<double>& pt) {
latLngs.push_back({ pt.y, pt.x });
});
- return cameraForLatLngs(latLngs, padding, bearing);
+ return cameraForLatLngs(latLngs, padding, bearing, pitch);
}
LatLngBounds Map::latLngBoundsForCamera(const CameraOptions& camera) const {
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 105adf0400..da8e243d91 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -594,13 +594,10 @@ void Transform::startTransition(const CameraOptions& camera,
animation.transitionFrameFn(t);
}
observer.onCameraIsChanging();
+ return false;
} else {
- transitionFinishFn();
- transitionFinishFn = nullptr;
-
- // This callback gets destroyed here,
- // we can only return after this point.
- transitionFrameFn = nullptr;
+ // Indicate that we need to terminate this transition
+ return true;
}
};
@@ -615,7 +612,14 @@ void Transform::startTransition(const CameraOptions& camera,
};
if (!isAnimated) {
- transitionFrameFn(Clock::now());
+ auto update = std::move(transitionFrameFn);
+ auto finish = std::move(transitionFinishFn);
+
+ transitionFrameFn = nullptr;
+ transitionFinishFn = nullptr;
+
+ update(Clock::now());
+ finish();
}
}
@@ -624,8 +628,43 @@ bool Transform::inTransition() const {
}
void Transform::updateTransitions(const TimePoint& now) {
- if (transitionFrameFn) {
- transitionFrameFn(now);
+
+ // Use a temporary function to ensure that the transitionFrameFn lambda is
+ // called only once per update.
+
+ // This addresses the symptoms of https://github.com/mapbox/mapbox-gl-native/issues/11180
+ // where setting a shape source to nil (or similar) in the `onCameraIsChanging`
+ // observer function causes `Map::Impl::onUpdate()` to be called which
+ // in turn calls this function (before the current iteration has completed),
+ // leading to an infinite loop. See https://github.com/mapbox/mapbox-gl-native/issues/5833
+ // for a similar, related, issue.
+ //
+ // By temporarily nulling the `transitionFrameFn` (and then restoring it
+ // after the temporary has been called) we stop this recursion.
+ //
+ // It's important to note that the scope of this change is stop the above
+ // crashes. It doesn't address any potential deeper issue (for example
+ // user error, how often and when transition callbacks are called).
+
+ auto transition = std::move(transitionFrameFn);
+ transitionFrameFn = nullptr;
+
+ if (transition && transition(now)) {
+ // If the transition indicates that it is complete, then we should call
+ // the finish lambda (going via a temporary as above)
+ auto finish = std::move(transitionFinishFn);
+
+ transitionFinishFn = nullptr;
+ transitionFrameFn = nullptr;
+
+ if (finish) {
+ finish();
+ }
+ } else if (!transitionFrameFn) {
+ // We have to check `transitionFrameFn` is nil here, since a new transition
+ // may have been triggered in a user callback (from the transition call
+ // above)
+ transitionFrameFn = std::move(transition);
}
}
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index d429c57661..bff44a2dcd 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -165,7 +165,7 @@ private:
TimePoint transitionStart;
Duration transitionDuration;
- std::function<void(const TimePoint)> transitionFrameFn;
+ std::function<bool(const TimePoint)> transitionFrameFn;
std::function<void()> transitionFinishFn;
};
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index a85b251fb4..948954570f 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -270,7 +270,7 @@ double TransformState::zoomScale(double zoom) const {
}
double TransformState::scaleZoom(double s) const {
- return util::log2(s);
+ return ::log2(s);
}
ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng) const {
@@ -280,7 +280,7 @@ ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng)
mat4 mat = coordinatePointMatrix(getZoom());
vec4 p;
- Point<double> pt = Projection::project(latLng, scale) / double(util::tileSize);
+ Point<double> pt = Projection::project(latLng, scale) / util::tileSize;
vec4 c = {{ pt.x, pt.y, 0, 1 }};
matrix::transformMat4(p, c, mat);
return { p[0] / p[3], size.height - p[1] / p[3] };
@@ -427,7 +427,7 @@ float TransformState::maxPitchScaleFactor() const {
}
auto latLng = screenCoordinateToLatLng({ 0, static_cast<float>(getSize().height) });
mat4 mat = coordinatePointMatrix(getZoom());
- Point<double> pt = Projection::project(latLng, scale) / double(util::tileSize);
+ Point<double> pt = Projection::project(latLng, scale) / util::tileSize;
vec4 p = {{ pt.x, pt.y, 0, 1 }};
vec4 topPoint;
matrix::transformMat4(topPoint, p, mat);
diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp
index bcdb270b9c..4d5de05337 100644
--- a/src/mbgl/programs/program.hpp
+++ b/src/mbgl/programs/program.hpp
@@ -46,26 +46,38 @@ public:
Shaders::fragmentSource)) {
}
+ static typename AllUniforms::Values computeAllUniformValues(
+ const UniformValues& uniformValues,
+ const PaintPropertyBinders& paintPropertyBinders,
+ const typename PaintProperties::PossiblyEvaluated& currentProperties,
+ float currentZoom) {
+ return uniformValues
+ .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties));
+ }
+
+ static typename Attributes::Bindings computeAllAttributeBindings(
+ const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer,
+ const PaintPropertyBinders& paintPropertyBinders,
+ const typename PaintProperties::PossiblyEvaluated& currentProperties) {
+ return LayoutAttributes::bindings(layoutVertexBuffer)
+ .concat(paintPropertyBinders.attributeBindings(currentProperties));
+ }
+
+ static uint32_t activeBindingCount(const typename Attributes::Bindings& allAttributeBindings) {
+ return Attributes::activeBindingCount(allAttributeBindings);
+ }
+
template <class DrawMode>
void draw(gl::Context& context,
DrawMode drawMode,
gl::DepthMode depthMode,
gl::StencilMode stencilMode,
gl::ColorMode colorMode,
- const UniformValues& uniformValues,
- const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer,
const gl::IndexBuffer<DrawMode>& indexBuffer,
const SegmentVector<Attributes>& segments,
- const PaintPropertyBinders& paintPropertyBinders,
- const typename PaintProperties::PossiblyEvaluated& currentProperties,
- float currentZoom,
+ const typename AllUniforms::Values& allUniformValues,
+ const typename Attributes::Bindings& allAttributeBindings,
const std::string& layerID) {
- typename AllUniforms::Values allUniformValues = uniformValues
- .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties));
-
- typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer)
- .concat(paintPropertyBinders.attributeBindings(currentProperties));
-
for (auto& segment : segments) {
auto vertexArrayIt = segment.vertexArrays.find(layerID);
diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp
index 84a7a53f1d..07d07ff0dd 100644
--- a/src/mbgl/programs/symbol_program.cpp
+++ b/src/mbgl/programs/symbol_program.cpp
@@ -17,14 +17,20 @@ std::unique_ptr<SymbolSizeBinder> SymbolSizeBinder::create(const float tileZoom,
const style::DataDrivenPropertyValue<float>& sizeProperty,
const float defaultValue) {
return sizeProperty.match(
- [&] (const style::CompositeFunction<float>& function) -> std::unique_ptr<SymbolSizeBinder> {
- return std::make_unique<CompositeFunctionSymbolSizeBinder>(tileZoom, function, defaultValue);
- },
- [&] (const style::SourceFunction<float>& function) {
- return std::make_unique<SourceFunctionSymbolSizeBinder>(tileZoom, function, defaultValue);
+ [&] (const Undefined& value) -> std::unique_ptr<SymbolSizeBinder> {
+ return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, value, defaultValue);
},
- [&] (const auto& value) -> std::unique_ptr<SymbolSizeBinder> {
+ [&] (float value) -> std::unique_ptr<SymbolSizeBinder> {
return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, value, defaultValue);
+ },
+ [&] (const style::PropertyExpression<float>& expression) -> std::unique_ptr<SymbolSizeBinder> {
+ if (expression.isFeatureConstant()) {
+ return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, expression, defaultValue);
+ } else if (expression.isZoomConstant()) {
+ return std::make_unique<SourceFunctionSymbolSizeBinder>(tileZoom, expression, defaultValue);
+ } else {
+ return std::make_unique<CompositeFunctionSymbolSizeBinder>(tileZoom, expression, defaultValue);
+ }
}
);
}
@@ -88,7 +94,6 @@ Values makeValues(const bool isText,
uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() },
uniforms::u_pitch::Value{ state.getPitch() },
uniforms::u_pitch_with_map::Value{ pitchWithMap },
- uniforms::u_max_camera_distance::Value{ values.maxCameraDistance },
uniforms::u_rotate_symbol::Value{ rotateInShader },
uniforms::u_aspect_ratio::Value{ state.getSize().aspectRatio() },
std::forward<Args>(args)...
diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp
index 9b5037ed9f..653fce9d4c 100644
--- a/src/mbgl/programs/symbol_program.hpp
+++ b/src/mbgl/programs/symbol_program.hpp
@@ -41,7 +41,6 @@ MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_zoom_constant);
MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_feature_constant);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_size_t);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_size);
-MBGL_DEFINE_UNIFORM_SCALAR(float, u_max_camera_distance);
MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_symbol);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio);
} // namespace uniforms
@@ -143,13 +142,13 @@ public:
ConstantSymbolSizeBinder(const float /*tileZoom*/, const style::Undefined&, const float defaultValue)
: layoutSize(defaultValue) {}
- ConstantSymbolSizeBinder(const float tileZoom, const style::CameraFunction<float>& function_, const float /*defaultValue*/)
- : layoutSize(function_.evaluate(tileZoom + 1)),
- function(function_) {
- const Range<float> zoomLevels = function_.getCoveringStops(tileZoom, tileZoom + 1);
+ ConstantSymbolSizeBinder(const float tileZoom, const style::PropertyExpression<float>& expression_, const float /*defaultValue*/)
+ : layoutSize(expression_.evaluate(tileZoom + 1)),
+ expression(expression_) {
+ const Range<float> zoomLevels = expression_.getCoveringStops(tileZoom, tileZoom + 1);
coveringRanges = std::make_tuple(
zoomLevels,
- Range<float> { function_.evaluate(zoomLevels.min), function_.evaluate(zoomLevels.max) }
+ Range<float> { expression_.evaluate(zoomLevels.min), expression_.evaluate(zoomLevels.max) }
);
}
@@ -157,7 +156,7 @@ public:
ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override {
float size = layoutSize;
- bool isZoomConstant = !(coveringRanges || function);
+ bool isZoomConstant = !(coveringRanges || expression);
if (coveringRanges) {
// Even though we could get the exact value of the camera function
// at z = currentZoom, we intentionally do not: instead, we interpolate
@@ -167,12 +166,12 @@ public:
const Range<float>& zoomLevels = std::get<0>(*coveringRanges);
const Range<float>& sizeLevels = std::get<1>(*coveringRanges);
float t = util::clamp(
- function->interpolationFactor(zoomLevels, currentZoom),
+ expression->interpolationFactor(zoomLevels, currentZoom),
0.0f, 1.0f
);
size = sizeLevels.min + t * (sizeLevels.max - sizeLevels.min);
- } else if (function) {
- size = function->evaluate(currentZoom);
+ } else if (expression) {
+ size = expression->evaluate(currentZoom);
}
const float unused = 0.0f;
@@ -181,7 +180,7 @@ public:
float layoutSize;
optional<std::tuple<Range<float>, Range<float>>> coveringRanges;
- optional<style::CameraFunction<float>> function;
+ optional<style::PropertyExpression<float>> expression;
};
class SourceFunctionSymbolSizeBinder final : public SymbolSizeBinder {
@@ -190,13 +189,13 @@ public:
using VertexVector = gl::VertexVector<Vertex>;
using VertexBuffer = gl::VertexBuffer<Vertex>;
- SourceFunctionSymbolSizeBinder(const float /*tileZoom*/, const style::SourceFunction<float>& function_, const float defaultValue_)
- : function(function_),
+ SourceFunctionSymbolSizeBinder(const float /*tileZoom*/, style::PropertyExpression<float> expression_, const float defaultValue_)
+ : expression(std::move(expression_)),
defaultValue(defaultValue_) {
}
Range<float> getVertexSizeData(const GeometryTileFeature& feature) override {
- const float size = function.evaluate(feature, defaultValue);
+ const float size = expression.evaluate(feature, defaultValue);
return { size, size };
};
@@ -205,30 +204,30 @@ public:
return { true, false, unused, unused, unused };
}
- style::SourceFunction<float> function;
+ style::PropertyExpression<float> expression;
const float defaultValue;
};
class CompositeFunctionSymbolSizeBinder final : public SymbolSizeBinder {
public:
- CompositeFunctionSymbolSizeBinder(const float tileZoom, const style::CompositeFunction<float>& function_, const float defaultValue_)
- : function(function_),
+ CompositeFunctionSymbolSizeBinder(const float tileZoom, style::PropertyExpression<float> expression_, const float defaultValue_)
+ : expression(std::move(expression_)),
defaultValue(defaultValue_),
layoutZoom(tileZoom + 1),
- coveringZoomStops(function.getCoveringStops(tileZoom, tileZoom + 1))
+ coveringZoomStops(expression.getCoveringStops(tileZoom, tileZoom + 1))
{}
Range<float> getVertexSizeData(const GeometryTileFeature& feature) override {
return {
- function.evaluate(coveringZoomStops.min, feature, defaultValue),
- function.evaluate(coveringZoomStops.max, feature, defaultValue)
+ expression.evaluate(coveringZoomStops.min, feature, defaultValue),
+ expression.evaluate(coveringZoomStops.max, feature, defaultValue)
};
};
ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override {
float sizeInterpolationT = util::clamp(
- function.interpolationFactor(coveringZoomStops, currentZoom),
+ expression.interpolationFactor(coveringZoomStops, currentZoom),
0.0f, 1.0f
);
@@ -236,7 +235,7 @@ public:
return { false, false, sizeInterpolationT, unused, unused };
}
- style::CompositeFunction<float> function;
+ style::PropertyExpression<float> expression;
const float defaultValue;
float layoutZoom;
Range<float> coveringZoomStops;
@@ -278,35 +277,45 @@ public:
Shaders::fragmentSource)) {
}
+ static typename AllUniforms::Values computeAllUniformValues(
+ const UniformValues& uniformValues,
+ const SymbolSizeBinder& symbolSizeBinder,
+ const PaintPropertyBinders& paintPropertyBinders,
+ const typename PaintProperties::PossiblyEvaluated& currentProperties,
+ float currentZoom) {
+ return uniformValues.concat(symbolSizeBinder.uniformValues(currentZoom))
+ .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties));
+ }
+
+ static typename Attributes::Bindings computeAllAttributeBindings(
+ const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer,
+ const gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>& dynamicLayoutVertexBuffer,
+ const gl::VertexBuffer<SymbolOpacityAttributes::Vertex>& opacityVertexBuffer,
+ const PaintPropertyBinders& paintPropertyBinders,
+ const typename PaintProperties::PossiblyEvaluated& currentProperties) {
+ assert(layoutVertexBuffer.vertexCount == dynamicLayoutVertexBuffer.vertexCount &&
+ layoutVertexBuffer.vertexCount == opacityVertexBuffer.vertexCount);
+ return LayoutAttributes::bindings(layoutVertexBuffer)
+ .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer))
+ .concat(SymbolOpacityAttributes::bindings(opacityVertexBuffer))
+ .concat(paintPropertyBinders.attributeBindings(currentProperties));
+ }
+
+ static uint32_t activeBindingCount(const typename Attributes::Bindings& allAttributeBindings) {
+ return Attributes::activeBindingCount(allAttributeBindings);
+ }
+
template <class DrawMode>
void draw(gl::Context& context,
DrawMode drawMode,
gl::DepthMode depthMode,
gl::StencilMode stencilMode,
gl::ColorMode colorMode,
- const UniformValues& uniformValues,
- const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer,
- const gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>& dynamicLayoutVertexBuffer,
- const gl::VertexBuffer<SymbolOpacityAttributes::Vertex>& opacityVertexBuffer,
- const SymbolSizeBinder& symbolSizeBinder,
const gl::IndexBuffer<DrawMode>& indexBuffer,
const SegmentVector<Attributes>& segments,
- const PaintPropertyBinders& paintPropertyBinders,
- const typename PaintProperties::PossiblyEvaluated& currentProperties,
- float currentZoom,
+ const typename AllUniforms::Values& allUniformValues,
+ const typename Attributes::Bindings& allAttributeBindings,
const std::string& layerID) {
- typename AllUniforms::Values allUniformValues = uniformValues
- .concat(symbolSizeBinder.uniformValues(currentZoom))
- .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties));
-
- typename Attributes::Bindings allAttributeBindings = LayoutAttributes::bindings(layoutVertexBuffer)
- .concat(SymbolDynamicLayoutAttributes::bindings(dynamicLayoutVertexBuffer))
- .concat(SymbolOpacityAttributes::bindings(opacityVertexBuffer))
- .concat(paintPropertyBinders.attributeBindings(currentProperties));
-
- assert(layoutVertexBuffer.vertexCount == dynamicLayoutVertexBuffer.vertexCount &&
- layoutVertexBuffer.vertexCount == opacityVertexBuffer.vertexCount);
-
for (auto& segment : segments) {
auto vertexArrayIt = segment.vertexArrays.find(layerID);
@@ -346,7 +355,6 @@ class SymbolIconProgram : public SymbolProgram<
uniforms::u_camera_to_center_distance,
uniforms::u_pitch,
uniforms::u_pitch_with_map,
- uniforms::u_max_camera_distance,
uniforms::u_rotate_symbol,
uniforms::u_aspect_ratio>,
style::IconPaintProperties>
@@ -386,7 +394,6 @@ class SymbolSDFProgram : public SymbolProgram<
uniforms::u_camera_to_center_distance,
uniforms::u_pitch,
uniforms::u_pitch_with_map,
- uniforms::u_max_camera_distance,
uniforms::u_rotate_symbol,
uniforms::u_aspect_ratio,
uniforms::u_gamma_scale,
@@ -408,8 +415,7 @@ public:
uniforms::u_is_text,
uniforms::u_camera_to_center_distance,
uniforms::u_pitch,
- uniforms::u_pitch_with_map,
- uniforms::u_max_camera_distance,
+ uniforms::u_pitch_with_map,
uniforms::u_rotate_symbol,
uniforms::u_aspect_ratio,
uniforms::u_gamma_scale,
diff --git a/src/mbgl/renderer/backend_scope.cpp b/src/mbgl/renderer/backend_scope.cpp
index fafeaabb39..ad430961aa 100644
--- a/src/mbgl/renderer/backend_scope.cpp
+++ b/src/mbgl/renderer/backend_scope.cpp
@@ -4,12 +4,20 @@
#include <cassert>
-namespace mbgl {
+namespace {
+
+mbgl::util::ThreadLocal<mbgl::BackendScope>& currentScope() {
+ static mbgl::util::ThreadLocal<mbgl::BackendScope> backendScope;
+
+ return backendScope;
+}
+
+} // namespace
-static util::ThreadLocal<BackendScope> currentScope;
+namespace mbgl {
BackendScope::BackendScope(RendererBackend& backend_, ScopeType scopeType_)
- : priorScope(currentScope.get()),
+ : priorScope(currentScope().get()),
nextScope(nullptr),
backend(backend_),
scopeType(scopeType_) {
@@ -21,7 +29,7 @@ BackendScope::BackendScope(RendererBackend& backend_, ScopeType scopeType_)
activate();
- currentScope.set(this);
+ currentScope().set(this);
}
BackendScope::~BackendScope() {
@@ -30,11 +38,11 @@ BackendScope::~BackendScope() {
if (priorScope) {
priorScope->activate();
- currentScope.set(priorScope);
+ currentScope().set(priorScope);
assert(priorScope->nextScope == this);
priorScope->nextScope = nullptr;
} else {
- currentScope.set(nullptr);
+ currentScope().set(nullptr);
}
}
@@ -60,7 +68,7 @@ void BackendScope::deactivate() {
}
bool BackendScope::exists() {
- return currentScope.get();
+ return currentScope().get();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index 9af511a03e..f48593ae49 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/style/layer_type.hpp>
#include <atomic>
@@ -15,9 +16,27 @@ class RenderLayer;
class Bucket : private util::noncopyable {
public:
- Bucket() = default;
+ Bucket(style::LayerType layerType_)
+ : layerType(layerType_) {
+ }
+
virtual ~Bucket() = default;
+ // Check whether this bucket is of the given subtype.
+ template <class T>
+ bool is() const;
+
+ // Dynamically cast this bucket to the given subtype.
+ template <class T>
+ T* as() {
+ return is<T>() ? reinterpret_cast<T*>(this) : nullptr;
+ }
+
+ template <class T>
+ const T* as() const {
+ return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
+ }
+
// Feature geometries are also used to populate the feature index.
// Obtaining these is a costly operation, so we do it only once, and
// pass-by-const-ref the geometries as a second parameter.
@@ -39,6 +58,7 @@ public:
}
protected:
+ style::LayerType layerType;
std::atomic<bool> uploaded { false };
};
diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp
index c442b661de..d07c1f8dbe 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.cpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.cpp
@@ -11,7 +11,8 @@ namespace mbgl {
using namespace style;
CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers)
- : mode(parameters.mode) {
+ : Bucket(LayerType::Circle),
+ mode(parameters.mode) {
for (const auto& layer : layers) {
paintPropertyBinders.emplace(
std::piecewise_construct,
diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp
index 78b6351bcb..3c5f96fb15 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.hpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.hpp
@@ -37,4 +37,9 @@ public:
const MapMode mode;
};
+template <>
+inline bool Bucket::is<CircleBucket>() const {
+ return layerType == style::LayerType::Circle;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp
index 110db887a1..14be98c3af 100644
--- a/src/mbgl/renderer/buckets/fill_bucket.cpp
+++ b/src/mbgl/renderer/buckets/fill_bucket.cpp
@@ -27,7 +27,8 @@ using namespace style;
struct GeometryTooLongException : std::exception {};
-FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) {
+FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers)
+ : Bucket(LayerType::Fill) {
for (const auto& layer : layers) {
paintPropertyBinders.emplace(
std::piecewise_construct,
diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp
index a50e1971f5..20b65da39c 100644
--- a/src/mbgl/renderer/buckets/fill_bucket.hpp
+++ b/src/mbgl/renderer/buckets/fill_bucket.hpp
@@ -39,4 +39,9 @@ public:
std::map<std::string, FillProgram::PaintPropertyBinders> paintPropertyBinders;
};
+template <>
+inline bool Bucket::is<FillBucket>() const {
+ return layerType == style::LayerType::Fill;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp
index 5e2c937091..c6dba38db1 100644
--- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp
+++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp
@@ -34,7 +34,8 @@ using namespace style;
struct GeometryTooLongException : std::exception {};
-FillExtrusionBucket::FillExtrusionBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) {
+FillExtrusionBucket::FillExtrusionBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers)
+ : Bucket(LayerType::FillExtrusion) {
for (const auto& layer : layers) {
paintPropertyBinders.emplace(std::piecewise_construct,
std::forward_as_tuple(layer->getID()),
@@ -84,7 +85,7 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature,
if (nVertices == 0)
continue;
- auto edgeDistance = 0;
+ std::size_t edgeDistance = 0;
for (uint32_t i = 0; i < nVertices; i++) {
const auto& p1 = ring[i];
@@ -102,7 +103,7 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature,
const Point<double> perp = util::unit(util::perp(d1 - d2));
const auto dist = util::dist<int16_t>(d1, d2);
- if (dist > std::numeric_limits<int16_t>::max()) {
+ if (edgeDistance + dist > std::numeric_limits<int16_t>::max()) {
edgeDistance = 0;
}
diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp
index d57265ab16..ed98e01292 100644
--- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp
+++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp
@@ -34,4 +34,9 @@ public:
std::unordered_map<std::string, FillExtrusionProgram::PaintPropertyBinders> paintPropertyBinders;
};
+template <>
+inline bool Bucket::is<FillExtrusionBucket>() const {
+ return layerType == style::LayerType::FillExtrusion;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.cpp b/src/mbgl/renderer/buckets/heatmap_bucket.cpp
index a185e04ad2..eff0c60280 100644
--- a/src/mbgl/renderer/buckets/heatmap_bucket.cpp
+++ b/src/mbgl/renderer/buckets/heatmap_bucket.cpp
@@ -11,7 +11,8 @@ namespace mbgl {
using namespace style;
HeatmapBucket::HeatmapBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers)
- : mode(parameters.mode) {
+ : Bucket(LayerType::Heatmap),
+ mode(parameters.mode) {
for (const auto& layer : layers) {
paintPropertyBinders.emplace(
std::piecewise_construct,
diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.hpp b/src/mbgl/renderer/buckets/heatmap_bucket.hpp
index 3b9f1edb81..86b6f10296 100644
--- a/src/mbgl/renderer/buckets/heatmap_bucket.hpp
+++ b/src/mbgl/renderer/buckets/heatmap_bucket.hpp
@@ -37,4 +37,9 @@ public:
const MapMode mode;
};
+template <>
+inline bool Bucket::is<HeatmapBucket>() const {
+ return layerType == style::LayerType::Heatmap;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.cpp b/src/mbgl/renderer/buckets/hillshade_bucket.cpp
index 00b9536894..3ca217a840 100644
--- a/src/mbgl/renderer/buckets/hillshade_bucket.cpp
+++ b/src/mbgl/renderer/buckets/hillshade_bucket.cpp
@@ -8,10 +8,14 @@ namespace mbgl {
using namespace style;
-HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::DEMEncoding encoding): demdata(image_, encoding) {
+HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::DEMEncoding encoding)
+ : Bucket(LayerType::Hillshade),
+ demdata(image_, encoding) {
}
-HillshadeBucket::HillshadeBucket(DEMData&& demdata_) : demdata(std::move(demdata_)) {
+HillshadeBucket::HillshadeBucket(DEMData&& demdata_)
+ : Bucket(LayerType::Hillshade),
+ demdata(std::move(demdata_)) {
}
const DEMData& HillshadeBucket::getDEMData() const {
diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.hpp b/src/mbgl/renderer/buckets/hillshade_bucket.hpp
index 5335f7ceda..c9e435c661 100644
--- a/src/mbgl/renderer/buckets/hillshade_bucket.hpp
+++ b/src/mbgl/renderer/buckets/hillshade_bucket.hpp
@@ -56,4 +56,9 @@ private:
bool prepared = false;
};
+template <>
+inline bool Bucket::is<HillshadeBucket>() const {
+ return layerType == style::LayerType::Hillshade;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp
index a96518df38..a10551a7d2 100644
--- a/src/mbgl/renderer/buckets/line_bucket.cpp
+++ b/src/mbgl/renderer/buckets/line_bucket.cpp
@@ -14,7 +14,8 @@ using namespace style;
LineBucket::LineBucket(const BucketParameters& parameters,
const std::vector<const RenderLayer*>& layers,
const style::LineLayoutProperties::Unevaluated& layout_)
- : layout(layout_.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ))),
+ : Bucket(LayerType::Line),
+ layout(layout_.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ))),
overscaling(parameters.tileID.overscaleFactor()),
zoom(parameters.tileID.overscaledZ) {
for (const auto& layer : layers) {
diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp
index 4fb77c377e..8fe7184941 100644
--- a/src/mbgl/renderer/buckets/line_bucket.hpp
+++ b/src/mbgl/renderer/buckets/line_bucket.hpp
@@ -64,4 +64,9 @@ private:
float getLineWidth(const RenderLineLayer& layer) const;
};
+template <>
+inline bool Bucket::is<LineBucket>() const {
+ return layerType == style::LayerType::Line;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/raster_bucket.cpp b/src/mbgl/renderer/buckets/raster_bucket.cpp
index a66dd42d74..45cf351d8e 100644
--- a/src/mbgl/renderer/buckets/raster_bucket.cpp
+++ b/src/mbgl/renderer/buckets/raster_bucket.cpp
@@ -7,12 +7,14 @@ namespace mbgl {
using namespace style;
-RasterBucket::RasterBucket(PremultipliedImage&& image_) {
- image = std::make_shared<PremultipliedImage>(std::move(image_));
+RasterBucket::RasterBucket(PremultipliedImage&& image_)
+ : Bucket(LayerType::Raster),
+ image(std::make_shared<PremultipliedImage>(std::move(image_))) {
}
-RasterBucket::RasterBucket(std::shared_ptr<PremultipliedImage> image_): image(image_) {
-
+RasterBucket::RasterBucket(std::shared_ptr<PremultipliedImage> image_)
+ : Bucket(LayerType::Raster),
+ image(image_) {
}
void RasterBucket::upload(gl::Context& context) {
diff --git a/src/mbgl/renderer/buckets/raster_bucket.hpp b/src/mbgl/renderer/buckets/raster_bucket.hpp
index 3800eadec8..84b618a83d 100644
--- a/src/mbgl/renderer/buckets/raster_bucket.hpp
+++ b/src/mbgl/renderer/buckets/raster_bucket.hpp
@@ -38,4 +38,9 @@ public:
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
};
+template <>
+inline bool Bucket::is<RasterBucket>() const {
+ return layerType == style::LayerType::Raster;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index 4fe03eb453..0a1530ae74 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -20,7 +20,8 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo
bool sortFeaturesByY_,
const std::string bucketName_,
const std::vector<SymbolInstance>&& symbolInstances_)
- : layout(std::move(layout_)),
+ : Bucket(LayerType::Symbol),
+ layout(std::move(layout_)),
sdfIcons(sdfIcons_),
iconsNeedLinear(iconsNeedLinear_ || iconSize.isDataDriven() || !iconSize.isZoomConstant()),
sortFeaturesByY(sortFeaturesByY_),
@@ -192,11 +193,11 @@ void SymbolBucket::sortFeatures(const float angle) {
std::sort(symbolInstanceIndexes.begin(), symbolInstanceIndexes.end(), [sin, cos, this](size_t &aIndex, size_t &bIndex) {
const SymbolInstance& a = symbolInstances[aIndex];
const SymbolInstance& b = symbolInstances[bIndex];
- const int32_t aRotated = sin * a.anchor.point.x + cos * a.anchor.point.y;
- const int32_t bRotated = sin * b.anchor.point.x + cos * b.anchor.point.y;
+ const int32_t aRotated = static_cast<int32_t>(std::lround(sin * a.anchor.point.x + cos * a.anchor.point.y));
+ const int32_t bRotated = static_cast<int32_t>(std::lround(sin * b.anchor.point.x + cos * b.anchor.point.y));
return aRotated != bRotated ?
aRotated < bRotated :
- a.index > b.index;
+ a.dataFeatureIndex > b.dataFeatureIndex;
});
text.triangles.clear();
@@ -207,7 +208,7 @@ void SymbolBucket::sortFeatures(const float angle) {
for (auto i : symbolInstanceIndexes) {
const SymbolInstance& symbolInstance = symbolInstances[i];
- featureSortOrder->push_back(symbolInstance.featureIndex);
+ featureSortOrder->push_back(symbolInstance.dataFeatureIndex);
if (symbolInstance.placedTextIndex) {
addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedTextIndex]);
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index e4aaf5ba30..4f01cf4e1c 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -138,4 +138,9 @@ public:
std::shared_ptr<std::vector<size_t>> featureSortOrder;
};
+template <>
+inline bool Bucket::is<SymbolBucket>() const {
+ return layerType == style::LayerType::Symbol;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.cpp b/src/mbgl/renderer/cross_faded_property_evaluator.cpp
index 4dff9dbf12..9a7af8636c 100644
--- a/src/mbgl/renderer/cross_faded_property_evaluator.cpp
+++ b/src/mbgl/renderer/cross_faded_property_evaluator.cpp
@@ -16,10 +16,10 @@ Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const T& constant) const {
}
template <typename T>
-Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::CameraFunction<T>& function) const {
- return calculate(function.evaluate(parameters.z - 1.0f),
- function.evaluate(parameters.z),
- function.evaluate(parameters.z + 1.0f));
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::PropertyExpression<T>& expression) const {
+ return calculate(expression.evaluate(parameters.z - 1.0f),
+ expression.evaluate(parameters.z),
+ expression.evaluate(parameters.z + 1.0f));
}
template <typename T>
diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.hpp b/src/mbgl/renderer/cross_faded_property_evaluator.hpp
index 40ecba5d93..1d17c5eb2f 100644
--- a/src/mbgl/renderer/cross_faded_property_evaluator.hpp
+++ b/src/mbgl/renderer/cross_faded_property_evaluator.hpp
@@ -27,7 +27,7 @@ public:
Faded<T> operator()(const style::Undefined&) const;
Faded<T> operator()(const T& constant) const;
- Faded<T> operator()(const style::CameraFunction<T>&) const;
+ Faded<T> operator()(const style::PropertyExpression<T>&) const;
private:
Faded<T> calculate(const T& min, const T& mid, const T& max) const;
diff --git a/src/mbgl/renderer/data_driven_property_evaluator.hpp b/src/mbgl/renderer/data_driven_property_evaluator.hpp
index 79ecd0d495..f9452cc572 100644
--- a/src/mbgl/renderer/data_driven_property_evaluator.hpp
+++ b/src/mbgl/renderer/data_driven_property_evaluator.hpp
@@ -23,21 +23,18 @@ public:
return ResultType(constant);
}
- ResultType operator()(const style::CameraFunction<T>& function) const {
- if (!parameters.useIntegerZoom) {
- return ResultType(function.evaluate(parameters.z));
+ ResultType operator()(const style::PropertyExpression<T>& expression) const {
+ if (!expression.isFeatureConstant()) {
+ auto returnExpression = expression;
+ returnExpression.useIntegerZoom = parameters.useIntegerZoom;
+ return ResultType(returnExpression);
+ } else if (!parameters.useIntegerZoom) {
+ return ResultType(expression.evaluate(parameters.z));
} else {
- return ResultType(function.evaluate(floor(parameters.z)));
+ return ResultType(expression.evaluate(floor(parameters.z)));
}
}
- template <class Function>
- ResultType operator()(const Function& function) const {
- auto returnFunction = function;
- returnFunction.useIntegerZoom = parameters.useIntegerZoom;
- return ResultType(returnFunction);
- }
-
private:
const PropertyEvaluationParameters& parameters;
T defaultValue;
diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp
index 44c3fffb6c..2dc5fe7339 100644
--- a/src/mbgl/renderer/layers/render_background_layer.cpp
+++ b/src/mbgl/renderer/layers/render_background_layer.cpp
@@ -50,6 +50,35 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) {
const Properties<>::PossiblyEvaluated properties;
const BackgroundProgram::PaintPropertyBinders paintAttributeData(properties, 0);
+ auto draw = [&](auto& program, auto&& uniformValues) {
+ const auto allUniformValues = program.computeAllUniformValues(
+ std::move(uniformValues),
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = program.computeAllAttributeBindings(
+ parameters.staticData.tileVertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ checkRenderability(parameters, program.activeBindingCount(allAttributeBindings));
+
+ program.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.tileTriangleSegments,
+ allUniformValues,
+ allAttributeBindings,
+ getID()
+ );
+ };
+
if (!evaluated.get<BackgroundPattern>().to.empty()) {
optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().from);
optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().to);
@@ -60,12 +89,8 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) {
parameters.imageManager.bind(parameters.context, 0);
for (const auto& tileID : util::tileCover(parameters.state, parameters.state.getIntegerZoom())) {
- parameters.programs.backgroundPattern.draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
+ draw(
+ parameters.programs.backgroundPattern,
BackgroundPatternUniforms::values(
parameters.matrixForTile(tileID),
evaluated.get<BackgroundOpacity>(),
@@ -75,36 +100,18 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) {
evaluated.get<BackgroundPattern>(),
tileID,
parameters.state
- ),
- parameters.staticData.tileVertexBuffer,
- parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.tileTriangleSegments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
- getID()
+ )
);
}
} else {
for (const auto& tileID : util::tileCover(parameters.state, parameters.state.getIntegerZoom())) {
- parameters.programs.background.draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
+ draw(
+ parameters.programs.background,
BackgroundProgram::UniformValues {
uniforms::u_matrix::Value{ parameters.matrixForTile(tileID) },
uniforms::u_color::Value{ evaluated.get<BackgroundColor>() },
uniforms::u_opacity::Value{ evaluated.get<BackgroundOpacity>() },
- },
- parameters.staticData.tileVertexBuffer,
- parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.tileTriangleSegments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
- getID()
+ }
);
}
}
diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp
index 56fccfe071..ce63ada770 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.cpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -56,17 +56,17 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) {
const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<CircleBucket*>(tile.tile.getBucket(*baseImpl)));
- CircleBucket& bucket = *reinterpret_cast<CircleBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<CircleBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ CircleBucket& bucket = *bucket_;
- parameters.programs.circle.get(evaluated).draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
- parameters.mapMode != MapMode::Continuous
- ? parameters.stencilModeForClipping(tile.clip)
- : gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
+
+ auto& programInstance = parameters.programs.circle.get(evaluated);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
CircleProgram::UniformValues {
uniforms::u_matrix::Value{
tile.translatedMatrix(evaluated.get<CircleTranslate>(),
@@ -82,12 +82,30 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) {
uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() },
uniforms::u_pitch_with_map::Value{ pitchWithMap }
},
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
*bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ parameters.mapMode != MapMode::Continuous
+ ? parameters.stencilModeForClipping(tile.clip)
+ : gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
*bucket.indexBuffer,
bucket.segments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
}
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
index 871464223c..2f720284fc 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
@@ -68,24 +68,55 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
parameters.context.setStencilMode(gl::StencilMode::disabled());
parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {});
+ auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues) {
+ const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ std::move(uniformValues),
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *tileBucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeFor3D(gl::DepthMode::ReadWrite),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ *tileBucket.indexBuffer,
+ tileBucket.triangleSegments,
+ allUniformValues,
+ allAttributeBindings,
+ getID());
+ };
+
if (evaluated.get<FillExtrusionPattern>().from.empty()) {
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)));
- FillExtrusionBucket& bucket =
- *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl));
-
- parameters.programs.fillExtrusion.get(evaluated).draw(
- parameters.context, gl::Triangles(),
- parameters.depthModeFor3D(gl::DepthMode::ReadWrite),
- gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ FillExtrusionBucket& bucket = *bucket_;
+
+ draw(
+ parameters.programs.fillExtrusion.get(evaluated),
+ bucket,
FillExtrusionUniforms::values(
tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
evaluated.get<FillExtrusionTranslateAnchor>(),
parameters.state),
- parameters.state, parameters.evaluatedLight),
- *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments,
- bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(),
- getID());
+ parameters.state,
+ parameters.evaluatedLight
+ )
+ );
}
} else {
optional<ImagePosition> imagePosA =
@@ -100,14 +131,15 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
parameters.imageManager.bind(parameters.context, 0);
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)));
- FillExtrusionBucket& bucket =
- *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl));
-
- parameters.programs.fillExtrusionPattern.get(evaluated).draw(
- parameters.context, gl::Triangles(),
- parameters.depthModeFor3D(gl::DepthMode::ReadWrite),
- gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ FillExtrusionBucket& bucket = *bucket_;
+
+ draw(
+ parameters.programs.fillExtrusionPattern.get(evaluated),
+ bucket,
FillExtrusionPatternUniforms::values(
tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
evaluated.get<FillExtrusionTranslateAnchor>(),
@@ -115,10 +147,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB,
evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state,
-std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f,
- parameters.evaluatedLight),
- *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments,
- bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(),
- getID());
+ parameters.evaluatedLight
+ )
+ );
}
}
@@ -131,19 +162,39 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
const Properties<>::PossiblyEvaluated properties;
+ const ExtrusionTextureProgram::PaintPropertyBinders paintAttributeData{ properties, 0 };
+
+ auto& programInstance = parameters.programs.extrusionTexture;
- parameters.programs.extrusionTexture.draw(
- parameters.context, gl::Triangles(), gl::DepthMode::disabled(),
- gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ const auto allUniformValues = programInstance.computeAllUniformValues(
ExtrusionTextureProgram::UniformValues{
uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size },
uniforms::u_image::Value{ 0 },
- uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } },
+ uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() }
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
parameters.staticData.extrusionTextureVertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ gl::DepthMode::disabled(),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
parameters.staticData.quadTriangleIndexBuffer,
parameters.staticData.extrusionTextureSegments,
- ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties,
- parameters.state.getZoom(), getID());
+ allUniformValues,
+ allAttributeBindings,
+ getID());
}
}
diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp
index efd3f4215c..f03eb66c88 100644
--- a/src/mbgl/renderer/layers/render_fill_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_layer.cpp
@@ -61,20 +61,22 @@ bool RenderFillLayer::hasTransition() const {
void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
if (evaluated.get<FillPattern>().from.empty()) {
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<FillBucket*>(tile.tile.getBucket(*baseImpl)));
- FillBucket& bucket = *reinterpret_cast<FillBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ FillBucket& bucket = *bucket_;
auto draw = [&] (auto& program,
const auto& drawMode,
const auto& depthMode,
const auto& indexBuffer,
const auto& segments) {
- program.get(evaluated).draw(
- parameters.context,
- drawMode,
- depthMode,
- parameters.stencilModeForClipping(tile.clip),
- parameters.colorModeForRenderPass(),
+ auto& programInstance = program.get(evaluated);
+
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
FillProgram::UniformValues {
uniforms::u_matrix::Value{
tile.translatedMatrix(evaluated.get<FillTranslate>(),
@@ -83,12 +85,28 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
},
uniforms::u_world::Value{ parameters.context.viewport.getCurrentValue().size },
},
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
*bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ drawMode,
+ depthMode,
+ parameters.stencilModeForClipping(tile.clip),
+ parameters.colorModeForRenderPass(),
indexBuffer,
segments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
};
@@ -131,20 +149,22 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
parameters.imageManager.bind(parameters.context, 0);
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<FillBucket*>(tile.tile.getBucket(*baseImpl)));
- FillBucket& bucket = *reinterpret_cast<FillBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ FillBucket& bucket = *bucket_;
auto draw = [&] (auto& program,
const auto& drawMode,
const auto& depthMode,
const auto& indexBuffer,
const auto& segments) {
- program.get(evaluated).draw(
- parameters.context,
- drawMode,
- depthMode,
- parameters.stencilModeForClipping(tile.clip),
- parameters.colorModeForRenderPass(),
+ auto& programInstance = program.get(evaluated);
+
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
FillPatternUniforms::values(
tile.translatedMatrix(evaluated.get<FillTranslate>(),
evaluated.get<FillTranslateAnchor>(),
@@ -157,12 +177,28 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
tile.id,
parameters.state
),
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
*bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ drawMode,
+ depthMode,
+ parameters.stencilModeForClipping(tile.clip),
+ parameters.colorModeForRenderPass(),
indexBuffer,
segments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
};
diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
index 72c60446aa..c9ca477cbb 100644
--- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp
+++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
@@ -83,8 +83,11 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) {
parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {});
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<HeatmapBucket*>(tile.tile.getBucket(*baseImpl)));
- HeatmapBucket& bucket = *reinterpret_cast<HeatmapBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<HeatmapBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ HeatmapBucket& bucket = *bucket_;
const auto extrudeScale = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
@@ -92,23 +95,38 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) {
? parameters.stencilModeForClipping(tile.clip)
: gl::StencilMode::disabled();
- parameters.programs.heatmap.get(evaluated).draw(
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
+
+ auto& programInstance = parameters.programs.heatmap.get(evaluated);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ HeatmapProgram::UniformValues {
+ uniforms::u_intensity::Value{ evaluated.get<style::HeatmapIntensity>() },
+ uniforms::u_matrix::Value{ tile.matrix },
+ uniforms::heatmap::u_extrude_scale::Value{ extrudeScale }
+ },
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
parameters.context,
gl::Triangles(),
parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
stencilMode,
gl::ColorMode::additive(),
- HeatmapProgram::UniformValues {
- uniforms::u_intensity::Value{evaluated.get<style::HeatmapIntensity>()},
- uniforms::u_matrix::Value{tile.matrix},
- uniforms::heatmap::u_extrude_scale::Value{extrudeScale}
- },
- *bucket.vertexBuffer,
*bucket.indexBuffer,
bucket.segments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
}
@@ -123,20 +141,41 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) {
matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
const Properties<>::PossiblyEvaluated properties;
+ const HeatmapTextureProgram::PaintPropertyBinders paintAttributeData{ properties, 0 };
+
+ auto& programInstance = parameters.programs.heatmapTexture;
- parameters.programs.heatmapTexture.draw(
- parameters.context, gl::Triangles(), gl::DepthMode::disabled(),
- gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ const auto allUniformValues = programInstance.computeAllUniformValues(
HeatmapTextureProgram::UniformValues{
uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size },
uniforms::u_image::Value{ 0 },
uniforms::u_color_ramp::Value{ 1 },
- uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() } },
+ uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() }
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
parameters.staticData.extrusionTextureVertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ gl::DepthMode::disabled(),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
parameters.staticData.quadTriangleIndexBuffer,
parameters.staticData.extrusionTextureSegments,
- HeatmapTextureProgram::PaintPropertyBinders{ properties, 0 }, properties,
- parameters.state.getZoom(), getID());
+ allUniformValues,
+ allAttributeBindings,
+ getID()
+ );
}
}
diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
index bcfd4ffe99..25eef98fcf 100644
--- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp
+++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
@@ -69,12 +69,11 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src
const auto& indexBuffer,
const auto& segments,
const UnwrappedTileID& id) {
- parameters.programs.hillshade.draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
+ auto& programInstance = parameters.programs.hillshade;
+
+ const HillshadeProgram::PaintPropertyBinders paintAttributeData{ evaluated, 0 };
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
HillshadeProgram::UniformValues {
uniforms::u_matrix::Value{ matrix },
uniforms::u_image::Value{ 0 },
@@ -84,12 +83,28 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src
uniforms::u_light::Value{ getLight(parameters) },
uniforms::u_latrange::Value{ getLatRange(id) },
},
+ paintAttributeData,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
vertexBuffer,
+ paintAttributeData,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
indexBuffer,
segments,
- HillshadeProgram::PaintPropertyBinders { evaluated, 0 },
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
};
@@ -99,8 +114,12 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src
matrix::translate(mat, mat, 0, -util::EXTENT, 0);
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<HillshadeBucket*>(tile.tile.getBucket(*baseImpl)));
- HillshadeBucket& bucket = *reinterpret_cast<HillshadeBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<HillshadeBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ HillshadeBucket& bucket = *bucket_;
+
if (!bucket.hasData()){
continue;
}
@@ -112,13 +131,11 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src
parameters.context.bindTexture(*bucket.dem, 0, gl::TextureFilter::Nearest, gl::TextureMipMap::No, gl::TextureWrap::Clamp, gl::TextureWrap::Clamp);
const Properties<>::PossiblyEvaluated properties;
+ const HillshadePrepareProgram::PaintPropertyBinders paintAttributeData{ properties, 0 };
- parameters.programs.hillshadePrepare.draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
+ auto& programInstance = parameters.programs.hillshadePrepare;
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
HillshadePrepareProgram::UniformValues {
uniforms::u_matrix::Value { mat },
uniforms::u_dimension::Value { {{uint16_t(tilesize * 2), uint16_t(tilesize * 2) }} },
@@ -126,12 +143,28 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src
uniforms::u_maxzoom::Value{ float(maxzoom) },
uniforms::u_image::Value{ 0 }
},
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
parameters.staticData.rasterVertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
parameters.staticData.quadTriangleIndexBuffer,
parameters.staticData.rasterSegments,
- HillshadePrepareProgram::PaintPropertyBinders { properties, 0 },
- properties,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
bucket.texture = std::move(view.getTexture());
diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp
index 02f61af0fa..4b6ea35e67 100644
--- a/src/mbgl/renderer/layers/render_line_layer.cpp
+++ b/src/mbgl/renderer/layers/render_line_layer.cpp
@@ -58,23 +58,41 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) {
}
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<LineBucket*>(tile.tile.getBucket(*baseImpl)));
- LineBucket& bucket = *reinterpret_cast<LineBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<LineBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ LineBucket& bucket = *bucket_;
auto draw = [&] (auto& program, auto&& uniformValues) {
- program.get(evaluated).draw(
+ auto& programInstance = program.get(evaluated);
+
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ std::move(uniformValues),
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
parameters.context,
gl::Triangles(),
parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
parameters.stencilModeForClipping(tile.clip),
parameters.colorModeForRenderPass(),
- std::move(uniformValues),
- *bucket.vertexBuffer,
*bucket.indexBuffer,
bucket.segments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
};
diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp
index b41b2ac560..e2524697b5 100644
--- a/src/mbgl/renderer/layers/render_raster_layer.cpp
+++ b/src/mbgl/renderer/layers/render_raster_layer.cpp
@@ -73,16 +73,15 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source
if (parameters.pass != RenderPass::Translucent)
return;
+ RasterProgram::PaintPropertyBinders paintAttributeData{ evaluated, 0 };
+
auto draw = [&] (const mat4& matrix,
const auto& vertexBuffer,
const auto& indexBuffer,
const auto& segments) {
- parameters.programs.raster.draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
+ auto& programInstance = parameters.programs.raster;
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
RasterProgram::UniformValues {
uniforms::u_matrix::Value{ matrix },
uniforms::u_image0::Value{ 0 },
@@ -98,23 +97,41 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source
uniforms::u_scale_parent::Value{ 1.0f },
uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} },
},
+ paintAttributeData,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
vertexBuffer,
+ paintAttributeData,
+ evaluated
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
indexBuffer,
segments,
- RasterProgram::PaintPropertyBinders { evaluated, 0 },
- evaluated,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
};
+ const gl::TextureFilter filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest ? gl::TextureFilter::Nearest : gl::TextureFilter::Linear;
+
if (RenderImageSource* imageSource = source->as<RenderImageSource>()) {
if (imageSource->isEnabled() && imageSource->isLoaded() && !imageSource->bucket->needsUpload()) {
RasterBucket& bucket = *imageSource->bucket;
assert(bucket.texture);
- parameters.context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
- parameters.context.bindTexture(*bucket.texture, 1, gl::TextureFilter::Linear);
+ parameters.context.bindTexture(*bucket.texture, 0, filter);
+ parameters.context.bindTexture(*bucket.texture, 1, filter);
for (auto matrix_ : imageSource->matrices) {
draw(matrix_,
@@ -125,15 +142,18 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source
}
} else {
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<RasterBucket*>(tile.tile.getBucket(*baseImpl)));
- RasterBucket& bucket = *reinterpret_cast<RasterBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<RasterBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ RasterBucket& bucket = *bucket_;
if (!bucket.hasData())
continue;
assert(bucket.texture);
- parameters.context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
- parameters.context.bindTexture(*bucket.texture, 1, gl::TextureFilter::Linear);
+ parameters.context.bindTexture(*bucket.texture, 0, filter);
+ parameters.context.bindTexture(*bucket.texture, 1, filter);
if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
// Draw only the parts of the tile that aren't drawn by another tile in the layer.
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index 9e493003c0..63fcb6cfd5 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -75,8 +75,11 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
}
for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<SymbolBucket*>(tile.tile.getBucket(*baseImpl)));
- SymbolBucket& bucket = *reinterpret_cast<SymbolBucket*>(tile.tile.getBucket(*baseImpl));
+ auto bucket_ = tile.tile.getBucket<SymbolBucket>(*baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ SymbolBucket& bucket = *bucket_;
const auto& layout = bucket.layout;
@@ -88,7 +91,26 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
const auto& binders,
const auto& paintProperties)
{
- program.get(paintProperties).draw(
+ auto& programInstance = program.get(paintProperties);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ std::move(uniformValues),
+ *symbolSizeBinder,
+ binders,
+ paintProperties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *buffers.vertexBuffer,
+ *buffers.dynamicVertexBuffer,
+ *buffers.opacityVertexBuffer,
+ binders,
+ paintProperties
+ );
+
+ checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
parameters.context,
gl::Triangles(),
values_.pitchAlignment == AlignmentType::Map
@@ -96,16 +118,10 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
: gl::DepthMode::disabled(),
gl::StencilMode::disabled(),
parameters.colorModeForRenderPass(),
- std::move(uniformValues),
- *buffers.vertexBuffer,
- *buffers.dynamicVertexBuffer,
- *buffers.opacityVertexBuffer,
- *symbolSizeBinder,
*buffers.indexBuffer,
buffers.segments,
- binders,
- paintProperties,
- parameters.state.getZoom(),
+ allUniformValues,
+ allAttributeBindings,
getID()
);
};
@@ -117,7 +133,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
auto values = iconPropertyValues(layout);
auto paintPropertyValues = iconPaintProperties();
- const bool alongLine = layout.get<SymbolPlacement>() == SymbolPlacementType::Line &&
+ const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point &&
layout.get<IconRotationAlignment>() == AlignmentType::Map;
if (alongLine) {
@@ -178,7 +194,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
auto values = textPropertyValues(layout);
auto paintPropertyValues = textPaintProperties();
- const bool alongLine = layout.get<SymbolPlacement>() == SymbolPlacementType::Line &&
+ const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point &&
layout.get<TextRotationAlignment>() == AlignmentType::Map;
if (alongLine) {
@@ -221,7 +237,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
static const CollisionBoxProgram::PaintPropertyBinders paintAttributeData(properties, 0);
auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
- auto scale = std::pow(2.0f, float(parameters.state.getZoom() - tile.tile.id.overscaledZ));
+ const float scale = std::pow(2, parameters.state.getZoom() - tile.tile.id.overscaledZ);
std::array<float,2> extrudeScale =
{{
parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
@@ -254,7 +270,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) {
static const CollisionBoxProgram::PaintPropertyBinders paintAttributeData(properties, 0);
auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
- auto scale = std::pow(2.0f, float(parameters.state.getZoom() - tile.tile.id.overscaledZ));
+ const float scale = std::pow(2, parameters.state.getZoom() - tile.tile.id.overscaledZ);
std::array<float,2> extrudeScale =
{{
parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
@@ -322,24 +338,11 @@ style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::S
evaluated.get<style::IconTranslateAnchor>(),
evaluated.get<style::IconHaloColor>().constantOr(Color::black()).a > 0 &&
evaluated.get<style::IconHaloWidth>().constantOr(1),
- evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0,
- 10.0f
+ evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0
};
}
style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const {
- // We hide line labels with viewport alignment as they move into the distance
- // because the approximations we use for drawing their glyphs get progressively worse
- // The "1.5" here means we start hiding them when the distance from the label
- // to the camera is 50% greater than the distance from the center of the map
- // to the camera. Depending on viewport properties, you might expect this to filter
- // the top third of the screen at pitch 60, and do almost nothing at pitch 45
- // "10" is effectively infinite at any pitch we support
- const bool limitMaxDistance =
- layout_.get<style::SymbolPlacement>() == style::SymbolPlacementType::Line
- && layout_.get<style::TextRotationAlignment>() == style::AlignmentType::Map
- && layout_.get<style::TextPitchAlignment>() == style::AlignmentType::Viewport;
-
return style::SymbolPropertyValues {
layout_.get<style::TextPitchAlignment>(),
layout_.get<style::TextRotationAlignment>(),
@@ -348,8 +351,7 @@ style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::S
evaluated.get<style::TextTranslateAnchor>(),
evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0 &&
evaluated.get<style::TextHaloWidth>().constantOr(1),
- evaluated.get<style::TextColor>().constantOr(Color::black()).a > 0,
- limitMaxDistance ? 1.5f : 10.0f
+ evaluated.get<style::TextColor>().constantOr(Color::black()).a > 0
};
}
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp
index 83709b5122..5b73b30294 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp
@@ -48,8 +48,6 @@ public:
bool hasHalo;
bool hasFill;
-
- float maxCameraDistance; // 1.5 for road labels, or 10 (essentially infinite) for everything else
};
} // namespace style
diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp
index 3a49882f12..aade672ae7 100644
--- a/src/mbgl/renderer/paint_property_binder.hpp
+++ b/src/mbgl/renderer/paint_property_binder.hpp
@@ -130,13 +130,13 @@ public:
using Attribute = ZoomInterpolatedAttributeType<A>;
using AttributeBinding = typename Attribute::Binding;
- SourceFunctionPaintPropertyBinder(style::SourceFunction<T> function_, T defaultValue_)
- : function(std::move(function_)),
+ SourceFunctionPaintPropertyBinder(style::PropertyExpression<T> expression_, T defaultValue_)
+ : expression(std::move(expression_)),
defaultValue(std::move(defaultValue_)) {
}
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
- auto evaluated = function.evaluate(feature, defaultValue);
+ auto evaluated = expression.evaluate(feature, defaultValue);
this->statistics.add(evaluated);
auto value = attributeValue(evaluated);
for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
@@ -170,7 +170,7 @@ public:
}
private:
- style::SourceFunction<T> function;
+ style::PropertyExpression<T> expression;
T defaultValue;
gl::VertexVector<BaseVertex> vertexVector;
optional<gl::VertexBuffer<BaseVertex>> vertexBuffer;
@@ -187,14 +187,14 @@ public:
using AttributeBinding = typename Attribute::Binding;
using Vertex = gl::detail::Vertex<Attribute>;
- CompositeFunctionPaintPropertyBinder(style::CompositeFunction<T> function_, float zoom, T defaultValue_)
- : function(std::move(function_)),
+ CompositeFunctionPaintPropertyBinder(style::PropertyExpression<T> expression_, float zoom, T defaultValue_)
+ : expression(std::move(expression_)),
defaultValue(std::move(defaultValue_)),
zoomRange({zoom, zoom + 1}) {
}
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override {
- Range<T> range = function.evaluate(zoomRange, feature, defaultValue);
+ Range<T> range = expression.evaluate(zoomRange, feature, defaultValue);
this->statistics.add(range.min);
this->statistics.add(range.max);
AttributeValue value = zoomInterpolatedAttributeValue(
@@ -218,10 +218,10 @@ public:
}
float interpolationFactor(float currentZoom) const override {
- if (function.useIntegerZoom) {
- return function.interpolationFactor(zoomRange, std::floor(currentZoom));
+ if (expression.useIntegerZoom) {
+ return expression.interpolationFactor(zoomRange, std::floor(currentZoom));
} else {
- return function.interpolationFactor(zoomRange, currentZoom);
+ return expression.interpolationFactor(zoomRange, currentZoom);
}
}
@@ -235,7 +235,7 @@ public:
}
private:
- style::CompositeFunction<T> function;
+ style::PropertyExpression<T> expression;
T defaultValue;
Range<float> zoomRange;
gl::VertexVector<Vertex> vertexVector;
@@ -249,11 +249,12 @@ PaintPropertyBinder<T, A>::create(const PossiblyEvaluatedPropertyValue<T>& value
[&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<T, A>> {
return std::make_unique<ConstantPaintPropertyBinder<T, A>>(constant);
},
- [&] (const style::SourceFunction<T>& function) {
- return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(function, defaultValue);
- },
- [&] (const style::CompositeFunction<T>& function) {
- return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(function, zoom, defaultValue);
+ [&] (const style::PropertyExpression<T>& expression) -> std::unique_ptr<PaintPropertyBinder<T, A>> {
+ if (expression.isZoomConstant()) {
+ return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(expression, defaultValue);
+ } else {
+ return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(expression, zoom, defaultValue);
+ }
}
);
}
diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp
index e662d5dfb1..f2d265f2f7 100644
--- a/src/mbgl/renderer/possibly_evaluated_property_value.hpp
+++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp
@@ -1,7 +1,6 @@
#pragma once
-#include <mbgl/style/function/source_function.hpp>
-#include <mbgl/style/function/composite_function.hpp>
+#include <mbgl/style/property_expression.hpp>
#include <mbgl/util/interpolate.hpp>
#include <mbgl/util/variant.hpp>
@@ -12,8 +11,7 @@ class PossiblyEvaluatedPropertyValue {
private:
using Value = variant<
T,
- style::SourceFunction<T>,
- style::CompositeFunction<T>>;
+ style::PropertyExpression<T>>;
Value value;
@@ -45,17 +43,14 @@ public:
template <class Feature>
T evaluate(const Feature& feature, float zoom, T defaultValue) const {
return this->match(
- [&] (const T& constant_) { return constant_; },
- [&] (const style::SourceFunction<T>& function) {
- return function.evaluate(feature, defaultValue);
- },
- [&] (const style::CompositeFunction<T>& function) {
- if (useIntegerZoom) {
- return function.evaluate(floor(zoom), feature, defaultValue);
- } else {
- return function.evaluate(zoom, feature, defaultValue);
- }
+ [&] (const T& constant_) { return constant_; },
+ [&] (const style::PropertyExpression<T>& expression) {
+ if (useIntegerZoom) {
+ return expression.evaluate(floor(zoom), feature, defaultValue);
+ } else {
+ return expression.evaluate(zoom, feature, defaultValue);
}
+ }
);
}
diff --git a/src/mbgl/renderer/property_evaluator.hpp b/src/mbgl/renderer/property_evaluator.hpp
index 3ac0573920..03e0f5a002 100644
--- a/src/mbgl/renderer/property_evaluator.hpp
+++ b/src/mbgl/renderer/property_evaluator.hpp
@@ -16,7 +16,7 @@ public:
T operator()(const style::Undefined&) const { return defaultValue; }
T operator()(const T& constant) const { return constant; }
- T operator()(const style::CameraFunction<T>& fn) const { return fn.evaluate(parameters.z); }
+ T operator()(const style::PropertyExpression<T>& fn) const { return fn.evaluate(parameters.z); }
private:
const PropertyEvaluationParameters& parameters;
diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp
index bcdc175f14..a667d5837e 100644
--- a/src/mbgl/renderer/render_layer.cpp
+++ b/src/mbgl/renderer/render_layer.cpp
@@ -9,8 +9,10 @@
#include <mbgl/renderer/layers/render_raster_layer.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/layers/render_heatmap_layer.hpp>
+#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
@@ -73,5 +75,32 @@ void RenderLayer::setRenderTiles(std::vector<std::reference_wrapper<RenderTile>>
renderTiles = std::move(tiles);
}
+void RenderLayer::checkRenderability(const PaintParameters& parameters,
+ const uint32_t activeBindingCount) {
+ // Only warn once for every layer.
+ if (hasRenderFailures) {
+ return;
+ }
+
+ if (activeBindingCount > parameters.context.maximumVertexBindingCount) {
+ Log::Error(Event::OpenGL,
+ "The layer '%s' uses more data-driven properties than the current device "
+ "supports, and will have rendering errors. To ensure compatibility with this "
+ "device, use %d fewer data driven properties in this layer.",
+ getID().c_str(),
+ activeBindingCount - parameters.context.minimumRequiredVertexBindingCount);
+ hasRenderFailures = true;
+ } else if (activeBindingCount > parameters.context.minimumRequiredVertexBindingCount) {
+ Log::Error(Event::OpenGL,
+ "The layer '%s' uses more data-driven properties than some devices may support. "
+ "Though it will render correctly on this device, it may have rendering errors "
+ "on other devices. To ensure compatibility with all devices, use %d fewer "
+ "data-driven properties in this layer.",
+ getID().c_str(),
+ activeBindingCount - parameters.context.minimumRequiredVertexBindingCount);
+ hasRenderFailures = true;
+ }
+}
+
} //namespace mbgl
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index 04a1608564..3e2f1d7525 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -85,6 +85,11 @@ public:
friend std::string layoutKey(const RenderLayer&);
protected:
+ // Checks whether the current hardware can render this layer. If it can't, we'll show a warning
+ // in the console to inform the developer.
+ void checkRenderability(const PaintParameters&, uint32_t activeBindingCount);
+
+protected:
// renderTiles are exposed directly to CrossTileSymbolIndex and Placement so they
// can update opacities in the symbol buckets immediately before rendering
friend class CrossTileSymbolIndex;
@@ -95,6 +100,12 @@ protected:
// Stores what render passes this layer is currently enabled for. This depends on the
// evaluated StyleProperties object and is updated accordingly.
RenderPass passes = RenderPass::None;
+
+private:
+ // Some layers may not render correctly on some hardware when the vertex attribute limit of
+ // that GPU is exceeded. More attributes are used when adding many data driven paint properties
+ // to a layer.
+ bool hasRenderFailures = false;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp
index 35b34833e4..64790938ef 100644
--- a/src/mbgl/renderer/render_tile.cpp
+++ b/src/mbgl/renderer/render_tile.cpp
@@ -74,6 +74,8 @@ void RenderTile::finishRender(PaintParameters& parameters) {
static const style::Properties<>::PossiblyEvaluated properties {};
static const DebugProgram::PaintPropertyBinders paintAttributeData(properties, 0);
+ auto& program = parameters.programs.debug;
+
if (parameters.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
tile.debugBucket->complete != tile.isComplete() ||
@@ -85,41 +87,51 @@ void RenderTile::finishRender(PaintParameters& parameters) {
tile.expires, parameters.debugOptions, parameters.context);
}
- parameters.programs.debug.draw(
+ const auto allAttributeBindings = program.computeAllAttributeBindings(
+ *tile.debugBucket->vertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ program.draw(
parameters.context,
gl::Lines { 4.0f * parameters.pixelRatio },
gl::DepthMode::disabled(),
parameters.stencilModeForClipping(clip),
gl::ColorMode::unblended(),
- DebugProgram::UniformValues {
- uniforms::u_matrix::Value{ matrix },
- uniforms::u_color::Value{ Color::white() }
- },
- *tile.debugBucket->vertexBuffer,
*tile.debugBucket->indexBuffer,
tile.debugBucket->segments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
+ program.computeAllUniformValues(
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::white() }
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ ),
+ allAttributeBindings,
"debug"
);
- parameters.programs.debug.draw(
+ program.draw(
parameters.context,
gl::Lines { 2.0f * parameters.pixelRatio },
gl::DepthMode::disabled(),
parameters.stencilModeForClipping(clip),
gl::ColorMode::unblended(),
- DebugProgram::UniformValues {
- uniforms::u_matrix::Value{ matrix },
- uniforms::u_color::Value{ Color::black() }
- },
- *tile.debugBucket->vertexBuffer,
*tile.debugBucket->indexBuffer,
tile.debugBucket->segments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
+ program.computeAllUniformValues(
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::black() }
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ ),
+ allAttributeBindings,
"debug"
);
}
@@ -131,16 +143,22 @@ void RenderTile::finishRender(PaintParameters& parameters) {
gl::DepthMode::disabled(),
parameters.stencilModeForClipping(clip),
gl::ColorMode::unblended(),
- DebugProgram::UniformValues {
- uniforms::u_matrix::Value{ matrix },
- uniforms::u_color::Value{ Color::red() }
- },
- parameters.staticData.tileVertexBuffer,
parameters.staticData.tileBorderIndexBuffer,
parameters.staticData.tileBorderSegments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
+ program.computeAllUniformValues(
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::red() }
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ ),
+ program.computeAllAttributeBindings(
+ parameters.staticData.tileVertexBuffer,
+ paintAttributeData,
+ properties
+ ),
"debug"
);
}
diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp
index 3db02393d2..bfa695586c 100644
--- a/src/mbgl/renderer/render_tile.hpp
+++ b/src/mbgl/renderer/render_tile.hpp
@@ -22,7 +22,7 @@ public:
RenderTile& operator=(const RenderTile&) = delete;
RenderTile& operator=(RenderTile&&) = default;
- const UnwrappedTileID id;
+ UnwrappedTileID id;
Tile& tile;
ClipID clip;
mat4 matrix;
diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp
index ded07a0909..fea27403c9 100644
--- a/src/mbgl/renderer/renderer_impl.cpp
+++ b/src/mbgl/renderer/renderer_impl.cpp
@@ -380,12 +380,15 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
}
for (auto it = order.rbegin(); it != order.rend(); ++it) {
if (it->layer.is<RenderSymbolLayer>()) {
- if (crossTileSymbolIndex.addLayer(*it->layer.as<RenderSymbolLayer>())) symbolBucketsChanged = true;
+ const float lng = parameters.state.getLatLng().longitude();
+ if (crossTileSymbolIndex.addLayer(*it->layer.as<RenderSymbolLayer>(), lng)) symbolBucketsChanged = true;
}
}
bool placementChanged = false;
if (!placement->stillRecent(parameters.timePoint)) {
+ placementChanged = true;
+
auto newPlacement = std::make_unique<Placement>(parameters.state, parameters.mapMode);
std::set<std::string> usedSymbolLayers;
for (auto it = order.rbegin(); it != order.rend(); ++it) {
@@ -395,13 +398,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
}
}
- placementChanged = newPlacement->commit(*placement, parameters.timePoint);
+ newPlacement->commit(*placement, parameters.timePoint);
crossTileSymbolIndex.pruneUnusedLayers(usedSymbolLayers);
- if (placementChanged || symbolBucketsChanged) {
- placement = std::move(newPlacement);
- }
-
- placement->setRecent(parameters.timePoint);
+ placement = std::move(newPlacement);
updateFadingTiles();
} else {
@@ -486,7 +485,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
static const ClippingMaskProgram::PaintPropertyBinders paintAttributeData(properties, 0);
for (const auto& clipID : parameters.clipIDGenerator.getClipIDs()) {
- parameters.staticData.programs.clippingMask.draw(
+ auto& program = parameters.staticData.programs.clippingMask;
+
+ program.draw(
parameters.context,
gl::Triangles(),
gl::DepthMode::disabled(),
@@ -499,15 +500,21 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
gl::StencilMode::Replace
},
gl::ColorMode::disabled(),
- ClippingMaskProgram::UniformValues {
- uniforms::u_matrix::Value{ parameters.matrixForTile(clipID.first) },
- },
- parameters.staticData.tileVertexBuffer,
parameters.staticData.quadTriangleIndexBuffer,
parameters.staticData.tileTriangleSegments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
+ program.computeAllUniformValues(
+ ClippingMaskProgram::UniformValues {
+ uniforms::u_matrix::Value{ parameters.matrixForTile(clipID.first) },
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ ),
+ program.computeAllAttributeBindings(
+ parameters.staticData.tileVertexBuffer,
+ paintAttributeData,
+ properties
+ ),
"clipping"
);
}
diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp
index 5c497e8144..2ce046a7a0 100644
--- a/src/mbgl/renderer/sources/render_image_source.cpp
+++ b/src/mbgl/renderer/sources/render_image_source.cpp
@@ -58,24 +58,32 @@ void RenderImageSource::finishRender(PaintParameters& parameters) {
static const style::Properties<>::PossiblyEvaluated properties {};
static const DebugProgram::PaintPropertyBinders paintAttributeData(properties, 0);
+ auto& programInstance = parameters.programs.debug;
+
for (auto matrix : matrices) {
- parameters.programs.debug.draw(
+ programInstance.draw(
parameters.context,
gl::LineStrip { 4.0f * parameters.pixelRatio },
gl::DepthMode::disabled(),
gl::StencilMode::disabled(),
gl::ColorMode::unblended(),
- DebugProgram::UniformValues {
- uniforms::u_matrix::Value{ matrix },
- uniforms::u_color::Value{ Color::red() }
- },
- parameters.staticData.tileVertexBuffer,
parameters.staticData.tileBorderIndexBuffer,
parameters.staticData.tileBorderSegments,
- paintAttributeData,
- properties,
- parameters.state.getZoom(),
- "debug"
+ programInstance.computeAllUniformValues(
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::red() }
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ ),
+ programInstance.computeAllAttributeBindings(
+ parameters.staticData.tileVertexBuffer,
+ paintAttributeData,
+ properties
+ ),
+ "image"
);
}
}
@@ -131,7 +139,7 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
auto dx = nePoint.x - swPoint.x;
auto dy = nePoint.y - swPoint.y;
auto dMax = std::max(dx, dy);
- double zoom = std::max(0.0, std::floor(-util::log2(dMax)));
+ double zoom = std::max(0.0, std::floor(-::log2(dMax)));
// Only enable if the long side of the image is > 2 pixels. Resulting in a
// display of at least 2 x 1 px image
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index d28e95181b..fd4356ca02 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -90,6 +90,8 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
return;
}
+ handleWrapJump(parameters.transformState.getLatLng().longitude());
+
// Determine the overzooming/underzooming amounts and required tiles.
int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize);
int32_t tileZoom = overscaledZoom;
@@ -238,6 +240,44 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
}
}
+void TilePyramid::handleWrapJump(float lng) {
+ // On top of the regular z/x/y values, TileIDs have a `wrap` value that specify
+ // which cppy of the world the tile belongs to. For example, at `lng: 10` you
+ // might render z/x/y/0 while at `lng: 370` you would render z/x/y/1.
+ //
+ // When lng values get wrapped (going from `lng: 370` to `long: 10`) you expect
+ // to see the same thing on the screen (370 degrees and 10 degrees is the same
+ // place in the world) but all the TileIDs will have different wrap values.
+ //
+ // In order to make this transition seamless, we calculate the rounded difference of
+ // "worlds" between the last frame and the current frame. If the map panned by
+ // a world, then we can assign all the tiles new TileIDs with updated wrap values.
+ // For example, assign z/x/y/1 a new id: z/x/y/0. It is the same tile, just rendered
+ // in a different position.
+ //
+ // This enables us to reuse the tiles at more ideal locations and prevent flickering.
+
+ const float lngDifference = lng - prevLng;
+ const float worldDifference = lngDifference / 360;
+ const int wrapDelta = ::round(worldDifference);
+ prevLng = lng;
+
+ if (wrapDelta) {
+ std::map<OverscaledTileID, std::unique_ptr<Tile>> newTiles;
+ for (auto& tile : tiles) {
+ auto newID = tile.second->id.unwrapTo(tile.second->id.wrap + wrapDelta);
+ tile.second->id = newID;
+ newTiles.emplace(newID, std::move(tile.second));
+ }
+ tiles = std::move(newTiles);
+
+ for (auto& renderTile : renderTiles) {
+ renderTile.id = renderTile.id.unwrapTo(renderTile.id.wrap + wrapDelta);
+ }
+ }
+}
+
+
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp
index 0cef9e2c40..4e5f50fd52 100644
--- a/src/mbgl/renderer/tile_pyramid.hpp
+++ b/src/mbgl/renderer/tile_pyramid.hpp
@@ -49,6 +49,8 @@ public:
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles();
Tile* getTile(const OverscaledTileID&);
+ void handleWrapJump(float lng);
+
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
@@ -72,6 +74,8 @@ public:
std::vector<RenderTile> renderTiles;
TileObserver* observer = nullptr;
+
+ float prevLng = 0;
};
} // namespace mbgl
diff --git a/src/mbgl/shaders/background.cpp b/src/mbgl/shaders/background.cpp
index 3eafa47b49..b0d176f07d 100644
--- a/src/mbgl/shaders/background.cpp
+++ b/src/mbgl/shaders/background.cpp
@@ -1,34 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/background.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* background::name = "background";
-const char* background::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-
-uniform mat4 u_matrix;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-}
-
-)MBGL_SHADER";
-const char* background::fragmentSource = R"MBGL_SHADER(
-uniform vec4 u_color;
-uniform float u_opacity;
-
-void main() {
- gl_FragColor = u_color * u_opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* background::vertexSource = source() + 2738;
+const char* background::fragmentSource = source() + 2850;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/background_pattern.cpp b/src/mbgl/shaders/background_pattern.cpp
index 6fd0a53d19..f80a86a0d9 100644
--- a/src/mbgl/shaders/background_pattern.cpp
+++ b/src/mbgl/shaders/background_pattern.cpp
@@ -1,65 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/background_pattern.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* background_pattern::name = "background_pattern";
-const char* background_pattern::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_pattern_size_a;
-uniform vec2 u_pattern_size_b;
-uniform vec2 u_pixel_coord_upper;
-uniform vec2 u_pixel_coord_lower;
-uniform float u_scale_a;
-uniform float u_scale_b;
-uniform float u_tile_units_to_pixels;
-
-attribute vec2 a_pos;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-
- v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);
- v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);
-}
-
-)MBGL_SHADER";
-const char* background_pattern::fragmentSource = R"MBGL_SHADER(
-uniform vec2 u_pattern_tl_a;
-uniform vec2 u_pattern_br_a;
-uniform vec2 u_pattern_tl_b;
-uniform vec2 u_pattern_br_b;
-uniform vec2 u_texsize;
-uniform float u_mix;
-uniform float u_opacity;
-
-uniform sampler2D u_image;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-
-void main() {
- vec2 imagecoord = mod(v_pos_a, 1.0);
- vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);
- vec4 color1 = texture2D(u_image, pos);
-
- vec2 imagecoord_b = mod(v_pos_b, 1.0);
- vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);
- vec4 color2 = texture2D(u_image, pos2);
-
- gl_FragColor = mix(color1, color2, u_mix) * u_opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* background_pattern::vertexSource = source() + 3019;
+const char* background_pattern::fragmentSource = source() + 3663;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp
index c14335914b..1ba1865504 100644
--- a/src/mbgl/shaders/circle.cpp
+++ b/src/mbgl/shaders/circle.cpp
@@ -1,287 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/circle.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* circle::name = "circle";
-const char* circle::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform bool u_scale_with_map;
-uniform bool u_pitch_with_map;
-uniform vec2 u_extrude_scale;
-uniform highp float u_camera_to_center_distance;
-
-attribute vec2 a_pos;
-
-
-#ifndef HAS_UNIFORM_u_color
-uniform lowp float a_color_t;
-attribute highp vec4 a_color;
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_radius
-uniform lowp float a_radius_t;
-attribute mediump vec2 a_radius;
-varying mediump float radius;
-#else
-uniform mediump float u_radius;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
-uniform lowp float a_blur_t;
-attribute lowp vec2 a_blur;
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_color
-uniform lowp float a_stroke_color_t;
-attribute highp vec4 a_stroke_color;
-varying highp vec4 stroke_color;
-#else
-uniform highp vec4 u_stroke_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_width
-uniform lowp float a_stroke_width_t;
-attribute mediump vec2 a_stroke_width;
-varying mediump float stroke_width;
-#else
-uniform mediump float u_stroke_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_opacity
-uniform lowp float a_stroke_opacity_t;
-attribute lowp vec2 a_stroke_opacity;
-varying lowp float stroke_opacity;
-#else
-uniform lowp float u_stroke_opacity;
-#endif
-
-
-varying vec3 v_data;
-
-void main(void) {
-
-#ifndef HAS_UNIFORM_u_color
- color = unpack_mix_vec4(a_color, a_color_t);
-#else
- highp vec4 color = u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_radius
- radius = unpack_mix_vec2(a_radius, a_radius_t);
-#else
- mediump float radius = u_radius;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
- blur = unpack_mix_vec2(a_blur, a_blur_t);
-#else
- lowp float blur = u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_color
- stroke_color = unpack_mix_vec4(a_stroke_color, a_stroke_color_t);
-#else
- highp vec4 stroke_color = u_stroke_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_width
- stroke_width = unpack_mix_vec2(a_stroke_width, a_stroke_width_t);
-#else
- mediump float stroke_width = u_stroke_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_opacity
- stroke_opacity = unpack_mix_vec2(a_stroke_opacity, a_stroke_opacity_t);
-#else
- lowp float stroke_opacity = u_stroke_opacity;
-#endif
-
-
- // unencode the extrusion vector that we snuck into the a_pos vector
- vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);
-
- // multiply a_pos by 0.5, since we had it * 2 in order to sneak
- // in extrusion data
- vec2 circle_center = floor(a_pos * 0.5);
- if (u_pitch_with_map) {
- vec2 corner_position = circle_center;
- if (u_scale_with_map) {
- corner_position += extrude * (radius + stroke_width) * u_extrude_scale;
- } else {
- // Pitching the circle with the map effectively scales it with the map
- // To counteract the effect for pitch-scale: viewport, we rescale the
- // whole circle based on the pitch scaling effect at its central point
- vec4 projected_center = u_matrix * vec4(circle_center, 0, 1);
- corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance);
- }
-
- gl_Position = u_matrix * vec4(corner_position, 0, 1);
- } else {
- gl_Position = u_matrix * vec4(circle_center, 0, 1);
-
- if (u_scale_with_map) {
- gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance;
- } else {
- gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * gl_Position.w;
- }
- }
-
- // This is a minimum blur distance that serves as a faux-antialiasing for
- // the circle. since blur is a ratio of the circle's size and the intent is
- // to keep the blur at roughly 1px, the two are inversely related.
- lowp float antialiasblur = 1.0 / DEVICE_PIXEL_RATIO / (radius + stroke_width);
-
- v_data = vec3(extrude.x, extrude.y, antialiasblur);
-}
-
-)MBGL_SHADER";
-const char* circle::fragmentSource = R"MBGL_SHADER(
-
-#ifndef HAS_UNIFORM_u_color
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_radius
-varying mediump float radius;
-#else
-uniform mediump float u_radius;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_color
-varying highp vec4 stroke_color;
-#else
-uniform highp vec4 u_stroke_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_width
-varying mediump float stroke_width;
-#else
-uniform mediump float u_stroke_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_stroke_opacity
-varying lowp float stroke_opacity;
-#else
-uniform lowp float u_stroke_opacity;
-#endif
-
-
-varying vec3 v_data;
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_color
- highp vec4 color = u_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_radius
- mediump float radius = u_radius;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_blur
- lowp float blur = u_blur;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_stroke_color
- highp vec4 stroke_color = u_stroke_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_stroke_width
- mediump float stroke_width = u_stroke_width;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_stroke_opacity
- lowp float stroke_opacity = u_stroke_opacity;
-#endif
-
-
- vec2 extrude = v_data.xy;
- float extrude_length = length(extrude);
-
- lowp float antialiasblur = v_data.z;
- float antialiased_blur = -max(blur, antialiasblur);
-
- float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0);
-
- float color_t = stroke_width < 0.01 ? 0.0 : smoothstep(
- antialiased_blur,
- 0.0,
- extrude_length - radius / (radius + stroke_width)
- );
-
- gl_FragColor = opacity_t * mix(color * opacity, stroke_color * stroke_opacity, color_t);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* circle::vertexSource = source() + 4415;
+const char* circle::fragmentSource = source() + 8663;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/clipping_mask.cpp b/src/mbgl/shaders/clipping_mask.cpp
index fb08d7cb00..dff0e08ced 100644
--- a/src/mbgl/shaders/clipping_mask.cpp
+++ b/src/mbgl/shaders/clipping_mask.cpp
@@ -1,27 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/clipping_mask.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* clipping_mask::name = "clipping_mask";
-const char* clipping_mask::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-
-uniform mat4 u_matrix;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-}
-
-)MBGL_SHADER";
-const char* clipping_mask::fragmentSource = R"MBGL_SHADER(
-void main() {
- gl_FragColor = vec4(1.0);
-}
-
-)MBGL_SHADER";
+const char* clipping_mask::vertexSource = source() + 10630;
+const char* clipping_mask::fragmentSource = source() + 10742;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/collision_box.cpp b/src/mbgl/shaders/collision_box.cpp
index bc5d9bc6f9..e09881e87d 100644
--- a/src/mbgl/shaders/collision_box.cpp
+++ b/src/mbgl/shaders/collision_box.cpp
@@ -1,63 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/collision_box.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* collision_box::name = "collision_box";
-const char* collision_box::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-attribute vec2 a_anchor_pos;
-attribute vec2 a_extrude;
-attribute vec2 a_placed;
-
-uniform mat4 u_matrix;
-uniform vec2 u_extrude_scale;
-uniform float u_camera_to_center_distance;
-
-varying float v_placed;
-varying float v_notUsed;
-
-void main() {
- vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1);
- highp float camera_to_anchor_distance = projectedPoint.w;
- highp float collision_perspective_ratio = clamp(
- 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance),
- 0.0, // Prevents oversized near-field boxes in pitched/overzoomed tiles
- 4.0);
-
- gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
- gl_Position.xy += a_extrude * u_extrude_scale * gl_Position.w * collision_perspective_ratio;
-
- v_placed = a_placed.x;
- v_notUsed = a_placed.y;
-}
-
-)MBGL_SHADER";
-const char* collision_box::fragmentSource = R"MBGL_SHADER(
-
-varying float v_placed;
-varying float v_notUsed;
-
-void main() {
-
- float alpha = 0.5;
-
- // Red = collision, hide label
- gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * alpha;
-
- // Blue = no collision, label is showing
- if (v_placed > 0.5) {
- gl_FragColor = vec4(0.0, 0.0, 1.0, 0.5) * alpha;
- }
-
- if (v_notUsed > 0.5) {
- // This box not used, fade it out
- gl_FragColor *= .1;
- }
-}
-)MBGL_SHADER";
+const char* collision_box::vertexSource = source() + 14425;
+const char* collision_box::fragmentSource = source() + 15249;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/collision_circle.cpp b/src/mbgl/shaders/collision_circle.cpp
index 82ebbf05a0..9188d728d8 100644
--- a/src/mbgl/shaders/collision_circle.cpp
+++ b/src/mbgl/shaders/collision_circle.cpp
@@ -1,87 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/collision_circle.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* collision_circle::name = "collision_circle";
-const char* collision_circle::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-attribute vec2 a_anchor_pos;
-attribute vec2 a_extrude;
-attribute vec2 a_placed;
-
-uniform mat4 u_matrix;
-uniform vec2 u_extrude_scale;
-uniform float u_camera_to_center_distance;
-
-varying float v_placed;
-varying float v_notUsed;
-varying float v_radius;
-
-varying vec2 v_extrude;
-varying vec2 v_extrude_scale;
-
-void main() {
- vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1);
- highp float camera_to_anchor_distance = projectedPoint.w;
- highp float collision_perspective_ratio = clamp(
- 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance),
- 0.0, // Prevents oversized near-field circles in pitched/overzoomed tiles
- 4.0);
-
- gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
-
- highp float padding_factor = 1.2; // Pad the vertices slightly to make room for anti-alias blur
- gl_Position.xy += a_extrude * u_extrude_scale * padding_factor * gl_Position.w * collision_perspective_ratio;
-
- v_placed = a_placed.x;
- v_notUsed = a_placed.y;
- v_radius = abs(a_extrude.y); // We don't pitch the circles, so both units of the extrusion vector are equal in magnitude to the radius
-
- v_extrude = a_extrude * padding_factor;
- v_extrude_scale = u_extrude_scale * u_camera_to_center_distance * collision_perspective_ratio;
-}
-
-)MBGL_SHADER";
-const char* collision_circle::fragmentSource = R"MBGL_SHADER(
-uniform float u_overscale_factor;
-
-varying float v_placed;
-varying float v_notUsed;
-varying float v_radius;
-varying vec2 v_extrude;
-varying vec2 v_extrude_scale;
-
-void main() {
- float alpha = 0.5;
-
- // Red = collision, hide label
- vec4 color = vec4(1.0, 0.0, 0.0, 1.0) * alpha;
-
- // Blue = no collision, label is showing
- if (v_placed > 0.5) {
- color = vec4(0.0, 0.0, 1.0, 0.5) * alpha;
- }
-
- if (v_notUsed > 0.5) {
- // This box not used, fade it out
- color *= .2;
- }
-
- float extrude_scale_length = length(v_extrude_scale);
- float extrude_length = length(v_extrude) * extrude_scale_length;
- float stroke_width = 15.0 * extrude_scale_length / u_overscale_factor;
- float radius = v_radius * extrude_scale_length;
-
- float distance_to_edge = abs(extrude_length - radius);
- float opacity_t = smoothstep(-stroke_width, 0.0, -distance_to_edge);
-
- gl_FragColor = opacity_t * color;
-}
-
-)MBGL_SHADER";
+const char* collision_circle::vertexSource = source() + 15668;
+const char* collision_circle::fragmentSource = source() + 16974;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/debug.cpp b/src/mbgl/shaders/debug.cpp
index 9012cfa755..25f2cb2675 100644
--- a/src/mbgl/shaders/debug.cpp
+++ b/src/mbgl/shaders/debug.cpp
@@ -1,29 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/debug.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* debug::name = "debug";
-const char* debug::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-
-uniform mat4 u_matrix;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-}
-
-)MBGL_SHADER";
-const char* debug::fragmentSource = R"MBGL_SHADER(
-uniform highp vec4 u_color;
-
-void main() {
- gl_FragColor = u_color;
-}
-
-)MBGL_SHADER";
+const char* debug::vertexSource = source() + 17916;
+const char* debug::fragmentSource = source() + 18028;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/extrusion_texture.cpp b/src/mbgl/shaders/extrusion_texture.cpp
index c756db181c..a9de78da1f 100644
--- a/src/mbgl/shaders/extrusion_texture.cpp
+++ b/src/mbgl/shaders/extrusion_texture.cpp
@@ -1,39 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/extrusion_texture.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* extrusion_texture::name = "extrusion_texture";
-const char* extrusion_texture::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_world;
-attribute vec2 a_pos;
-varying vec2 v_pos;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos * u_world, 0, 1);
-
- v_pos.x = a_pos.x;
- v_pos.y = 1.0 - a_pos.y;
-}
-
-)MBGL_SHADER";
-const char* extrusion_texture::fragmentSource = R"MBGL_SHADER(
-uniform sampler2D u_image;
-uniform float u_opacity;
-varying vec2 v_pos;
-
-void main() {
- gl_FragColor = texture2D(u_image, v_pos) * u_opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(0.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* extrusion_texture::vertexSource = source() + 31747;
+const char* extrusion_texture::fragmentSource = source() + 31963;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/fill.cpp b/src/mbgl/shaders/fill.cpp
index 3ba00836a2..146dbfb737 100644
--- a/src/mbgl/shaders/fill.cpp
+++ b/src/mbgl/shaders/fill.cpp
@@ -1,91 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/fill.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* fill::name = "fill";
-const char* fill::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-
-uniform mat4 u_matrix;
-
-
-#ifndef HAS_UNIFORM_u_color
-uniform lowp float a_color_t;
-attribute highp vec4 a_color;
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_color
- color = unpack_mix_vec4(a_color, a_color_t);
-#else
- highp vec4 color = u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-}
-
-)MBGL_SHADER";
-const char* fill::fragmentSource = R"MBGL_SHADER(
-
-#ifndef HAS_UNIFORM_u_color
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_color
- highp vec4 color = u_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- gl_FragColor = color * opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* fill::vertexSource = source() + 18102;
+const char* fill::fragmentSource = source() + 18807;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/fill_extrusion.cpp b/src/mbgl/shaders/fill_extrusion.cpp
index 5bb2b9cd07..ece4635dc4 100644
--- a/src/mbgl/shaders/fill_extrusion.cpp
+++ b/src/mbgl/shaders/fill_extrusion.cpp
@@ -1,164 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/fill_extrusion.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* fill_extrusion::name = "fill_extrusion";
-const char* fill_extrusion::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec3 u_lightcolor;
-uniform lowp vec3 u_lightpos;
-uniform lowp float u_lightintensity;
-
-attribute vec2 a_pos;
-attribute vec4 a_normal_ed;
-
-varying vec4 v_color;
-
-
-#ifndef HAS_UNIFORM_u_base
-uniform lowp float a_base_t;
-attribute lowp vec2 a_base;
-varying lowp float base;
-#else
-uniform lowp float u_base;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_height
-uniform lowp float a_height_t;
-attribute lowp vec2 a_height;
-varying lowp float height;
-#else
-uniform lowp float u_height;
-#endif
-
-
-
-#ifndef HAS_UNIFORM_u_color
-uniform lowp float a_color_t;
-attribute highp vec4 a_color;
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_base
- base = unpack_mix_vec2(a_base, a_base_t);
-#else
- lowp float base = u_base;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_height
- height = unpack_mix_vec2(a_height, a_height_t);
-#else
- lowp float height = u_height;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_color
- color = unpack_mix_vec4(a_color, a_color_t);
-#else
- highp vec4 color = u_color;
-#endif
-
-
- vec3 normal = a_normal_ed.xyz;
-
- base = max(0.0, base);
- height = max(0.0, height);
-
- float t = mod(normal.x, 2.0);
-
- gl_Position = u_matrix * vec4(a_pos, t > 0.0 ? height : base, 1);
-
- // Relative luminance (how dark/bright is the surface color?)
- float colorvalue = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
-
- v_color = vec4(0.0, 0.0, 0.0, 1.0);
-
- // Add slight ambient lighting so no extrusions are totally black
- vec4 ambientlight = vec4(0.03, 0.03, 0.03, 1.0);
- color += ambientlight;
-
- // Calculate cos(theta), where theta is the angle between surface normal and diffuse light ray
- float directional = clamp(dot(normal / 16384.0, u_lightpos), 0.0, 1.0);
-
- // Adjust directional so that
- // the range of values for highlight/shading is narrower
- // with lower light intensity
- // and with lighter/brighter surface colors
- directional = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), directional);
-
- // Add gradient along z axis of side surfaces
- if (normal.y != 0.0) {
- directional *= clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0);
- }
-
- // Assign final color based on surface + ambient light color, diffuse light directional, and light color
- // with lower bounds adjusted to hue of light
- // so that shading is tinted with the complementary (opposite) color to the light color
- v_color.r += clamp(color.r * directional * u_lightcolor.r, mix(0.0, 0.3, 1.0 - u_lightcolor.r), 1.0);
- v_color.g += clamp(color.g * directional * u_lightcolor.g, mix(0.0, 0.3, 1.0 - u_lightcolor.g), 1.0);
- v_color.b += clamp(color.b * directional * u_lightcolor.b, mix(0.0, 0.3, 1.0 - u_lightcolor.b), 1.0);
-}
-
-)MBGL_SHADER";
-const char* fill_extrusion::fragmentSource = R"MBGL_SHADER(
-varying vec4 v_color;
-
-#ifndef HAS_UNIFORM_u_base
-varying lowp float base;
-#else
-uniform lowp float u_base;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_height
-varying lowp float height;
-#else
-uniform lowp float u_height;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_color
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_base
- lowp float base = u_base;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_height
- lowp float height = u_height;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_color
- highp vec4 color = u_color;
-#endif
-
-
- gl_FragColor = v_color;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* fill_extrusion::vertexSource = source() + 24858;
+const char* fill_extrusion::fragmentSource = source() + 27694;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/fill_extrusion_pattern.cpp b/src/mbgl/shaders/fill_extrusion_pattern.cpp
index 466d0e04fe..1d7a2d4428 100644
--- a/src/mbgl/shaders/fill_extrusion_pattern.cpp
+++ b/src/mbgl/shaders/fill_extrusion_pattern.cpp
@@ -1,158 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/fill_extrusion_pattern.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* fill_extrusion_pattern::name = "fill_extrusion_pattern";
-const char* fill_extrusion_pattern::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_pattern_size_a;
-uniform vec2 u_pattern_size_b;
-uniform vec2 u_pixel_coord_upper;
-uniform vec2 u_pixel_coord_lower;
-uniform float u_scale_a;
-uniform float u_scale_b;
-uniform float u_tile_units_to_pixels;
-uniform float u_height_factor;
-
-uniform vec3 u_lightcolor;
-uniform lowp vec3 u_lightpos;
-uniform lowp float u_lightintensity;
-
-attribute vec2 a_pos;
-attribute vec4 a_normal_ed;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-varying vec4 v_lighting;
-varying float v_directional;
-
-
-#ifndef HAS_UNIFORM_u_base
-uniform lowp float a_base_t;
-attribute lowp vec2 a_base;
-varying lowp float base;
-#else
-uniform lowp float u_base;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_height
-uniform lowp float a_height_t;
-attribute lowp vec2 a_height;
-varying lowp float height;
-#else
-uniform lowp float u_height;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_base
- base = unpack_mix_vec2(a_base, a_base_t);
-#else
- lowp float base = u_base;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_height
- height = unpack_mix_vec2(a_height, a_height_t);
-#else
- lowp float height = u_height;
-#endif
-
-
- vec3 normal = a_normal_ed.xyz;
- float edgedistance = a_normal_ed.w;
-
- base = max(0.0, base);
- height = max(0.0, height);
-
- float t = mod(normal.x, 2.0);
- float z = t > 0.0 ? height : base;
-
- gl_Position = u_matrix * vec4(a_pos, z, 1);
-
- vec2 pos = normal.x == 1.0 && normal.y == 0.0 && normal.z == 16384.0
- ? a_pos // extrusion top
- : vec2(edgedistance, z * u_height_factor); // extrusion side
-
- v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, pos);
- v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, pos);
-
- v_lighting = vec4(0.0, 0.0, 0.0, 1.0);
- float directional = clamp(dot(normal / 16383.0, u_lightpos), 0.0, 1.0);
- directional = mix((1.0 - u_lightintensity), max((0.5 + u_lightintensity), 1.0), directional);
-
- if (normal.y != 0.0) {
- directional *= clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0);
- }
-
- v_lighting.rgb += clamp(directional * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));
-}
-
-)MBGL_SHADER";
-const char* fill_extrusion_pattern::fragmentSource = R"MBGL_SHADER(
-uniform vec2 u_pattern_tl_a;
-uniform vec2 u_pattern_br_a;
-uniform vec2 u_pattern_tl_b;
-uniform vec2 u_pattern_br_b;
-uniform vec2 u_texsize;
-uniform float u_mix;
-
-uniform sampler2D u_image;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-varying vec4 v_lighting;
-
-
-#ifndef HAS_UNIFORM_u_base
-varying lowp float base;
-#else
-uniform lowp float u_base;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_height
-varying lowp float height;
-#else
-uniform lowp float u_height;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_base
- lowp float base = u_base;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_height
- lowp float height = u_height;
-#endif
-
-
- vec2 imagecoord = mod(v_pos_a, 1.0);
- vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);
- vec4 color1 = texture2D(u_image, pos);
-
- vec2 imagecoord_b = mod(v_pos_b, 1.0);
- vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);
- vec4 color2 = texture2D(u_image, pos2);
-
- vec4 mixedColor = mix(color1, color2, u_mix);
-
- gl_FragColor = mixedColor * v_lighting;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* fill_extrusion_pattern::vertexSource = source() + 28334;
+const char* fill_extrusion_pattern::fragmentSource = source() + 30619;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/fill_outline.cpp b/src/mbgl/shaders/fill_outline.cpp
index 9ade598d10..873e49f8c2 100644
--- a/src/mbgl/shaders/fill_outline.cpp
+++ b/src/mbgl/shaders/fill_outline.cpp
@@ -1,99 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/fill_outline.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* fill_outline::name = "fill_outline";
-const char* fill_outline::vertexSource = R"MBGL_SHADER(
-attribute vec2 a_pos;
-
-uniform mat4 u_matrix;
-uniform vec2 u_world;
-
-varying vec2 v_pos;
-
-
-#ifndef HAS_UNIFORM_u_outline_color
-uniform lowp float a_outline_color_t;
-attribute highp vec4 a_outline_color;
-varying highp vec4 outline_color;
-#else
-uniform highp vec4 u_outline_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_outline_color
- outline_color = unpack_mix_vec4(a_outline_color, a_outline_color_t);
-#else
- highp vec4 outline_color = u_outline_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
- v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;
-}
-
-)MBGL_SHADER";
-const char* fill_outline::fragmentSource = R"MBGL_SHADER(
-
-#ifndef HAS_UNIFORM_u_outline_color
-varying highp vec4 outline_color;
-#else
-uniform highp vec4 u_outline_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-varying vec2 v_pos;
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_outline_color
- highp vec4 outline_color = u_outline_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- float dist = length(v_pos - gl_FragCoord.xy);
- float alpha = 1.0 - smoothstep(0.0, 1.0, dist);
- gl_FragColor = outline_color * (alpha * opacity);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* fill_outline::vertexSource = source() + 19276;
+const char* fill_outline::fragmentSource = source() + 20180;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/fill_outline_pattern.cpp b/src/mbgl/shaders/fill_outline_pattern.cpp
index 11cddb7d07..d1bcaa95bb 100644
--- a/src/mbgl/shaders/fill_outline_pattern.cpp
+++ b/src/mbgl/shaders/fill_outline_pattern.cpp
@@ -1,107 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/fill_outline_pattern.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* fill_outline_pattern::name = "fill_outline_pattern";
-const char* fill_outline_pattern::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_world;
-uniform vec2 u_pattern_size_a;
-uniform vec2 u_pattern_size_b;
-uniform vec2 u_pixel_coord_upper;
-uniform vec2 u_pixel_coord_lower;
-uniform float u_scale_a;
-uniform float u_scale_b;
-uniform float u_tile_units_to_pixels;
-
-attribute vec2 a_pos;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-varying vec2 v_pos;
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-
- v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);
- v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);
-
- v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world;
-}
-
-)MBGL_SHADER";
-const char* fill_outline_pattern::fragmentSource = R"MBGL_SHADER(
-uniform vec2 u_pattern_tl_a;
-uniform vec2 u_pattern_br_a;
-uniform vec2 u_pattern_tl_b;
-uniform vec2 u_pattern_br_b;
-uniform vec2 u_texsize;
-uniform float u_mix;
-
-uniform sampler2D u_image;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-varying vec2 v_pos;
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- vec2 imagecoord = mod(v_pos_a, 1.0);
- vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);
- vec4 color1 = texture2D(u_image, pos);
-
- vec2 imagecoord_b = mod(v_pos_b, 1.0);
- vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);
- vec4 color2 = texture2D(u_image, pos2);
-
- // find distance to outline for alpha interpolation
-
- float dist = length(v_pos - gl_FragCoord.xy);
- float alpha = 1.0 - smoothstep(0.0, 1.0, dist);
-
-
- gl_FragColor = mix(color1, color2, u_mix) * alpha * opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* fill_outline_pattern::vertexSource = source() + 20838;
+const char* fill_outline_pattern::fragmentSource = source() + 21901;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/fill_pattern.cpp b/src/mbgl/shaders/fill_pattern.cpp
index a3817c4426..88b4fc92a2 100644
--- a/src/mbgl/shaders/fill_pattern.cpp
+++ b/src/mbgl/shaders/fill_pattern.cpp
@@ -1,96 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/fill_pattern.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* fill_pattern::name = "fill_pattern";
-const char* fill_pattern::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_pattern_size_a;
-uniform vec2 u_pattern_size_b;
-uniform vec2 u_pixel_coord_upper;
-uniform vec2 u_pixel_coord_lower;
-uniform float u_scale_a;
-uniform float u_scale_b;
-uniform float u_tile_units_to_pixels;
-
-attribute vec2 a_pos;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
-
- v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_a * u_pattern_size_a, u_tile_units_to_pixels, a_pos);
- v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, u_scale_b * u_pattern_size_b, u_tile_units_to_pixels, a_pos);
-}
-
-)MBGL_SHADER";
-const char* fill_pattern::fragmentSource = R"MBGL_SHADER(
-uniform vec2 u_pattern_tl_a;
-uniform vec2 u_pattern_br_a;
-uniform vec2 u_pattern_tl_b;
-uniform vec2 u_pattern_br_b;
-uniform vec2 u_texsize;
-uniform float u_mix;
-
-uniform sampler2D u_image;
-
-varying vec2 v_pos_a;
-varying vec2 v_pos_b;
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- vec2 imagecoord = mod(v_pos_a, 1.0);
- vec2 pos = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, imagecoord);
- vec4 color1 = texture2D(u_image, pos);
-
- vec2 imagecoord_b = mod(v_pos_b, 1.0);
- vec2 pos2 = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, imagecoord_b);
- vec4 color2 = texture2D(u_image, pos2);
-
- gl_FragColor = mix(color1, color2, u_mix) * opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* fill_pattern::vertexSource = source() + 22998;
+const char* fill_pattern::fragmentSource = source() + 23950;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/heatmap.cpp b/src/mbgl/shaders/heatmap.cpp
index 19927cfcc6..c669e8e0af 100644
--- a/src/mbgl/shaders/heatmap.cpp
+++ b/src/mbgl/shaders/heatmap.cpp
@@ -1,128 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/heatmap.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* heatmap::name = "heatmap";
-const char* heatmap::vertexSource = R"MBGL_SHADER(
-
-#ifndef HAS_UNIFORM_u_weight
-uniform lowp float a_weight_t;
-attribute highp vec2 a_weight;
-varying highp float weight;
-#else
-uniform highp float u_weight;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_radius
-uniform lowp float a_radius_t;
-attribute mediump vec2 a_radius;
-#else
-uniform mediump float u_radius;
-#endif
-
-
-uniform mat4 u_matrix;
-uniform float u_extrude_scale;
-uniform float u_opacity;
-uniform float u_intensity;
-
-attribute vec2 a_pos;
-
-varying vec2 v_extrude;
-
-// Effective "0" in the kernel density texture to adjust the kernel size to;
-// this empirically chosen number minimizes artifacts on overlapping kernels
-// for typical heatmap cases (assuming clustered source)
-const highp float ZERO = 1.0 / 255.0 / 16.0;
-
-// Gaussian kernel coefficient: 1 / sqrt(2 * PI)
-#define GAUSS_COEF 0.3989422804014327
-
-void main(void) {
-
-#ifndef HAS_UNIFORM_u_weight
- weight = unpack_mix_vec2(a_weight, a_weight_t);
-#else
- highp float weight = u_weight;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_radius
- mediump float radius = unpack_mix_vec2(a_radius, a_radius_t);
-#else
- mediump float radius = u_radius;
-#endif
-
-
- // unencode the extrusion vector that we snuck into the a_pos vector
- vec2 unscaled_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);
-
- // This 'extrude' comes in ranging from [-1, -1], to [1, 1]. We'll use
- // it to produce the vertices of a square mesh framing the point feature
- // we're adding to the kernel density texture. We'll also pass it as
- // a varying, so that the fragment shader can determine the distance of
- // each fragment from the point feature.
- // Before we do so, we need to scale it up sufficiently so that the
- // kernel falls effectively to zero at the edge of the mesh.
- // That is, we want to know S such that
- // weight * u_intensity * GAUSS_COEF * exp(-0.5 * 3.0^2 * S^2) == ZERO
- // Which solves to:
- // S = sqrt(-2.0 * log(ZERO / (weight * u_intensity * GAUSS_COEF))) / 3.0
- float S = sqrt(-2.0 * log(ZERO / weight / u_intensity / GAUSS_COEF)) / 3.0;
-
- // Pass the varying in units of radius
- v_extrude = S * unscaled_extrude;
-
- // Scale by radius and the zoom-based scale factor to produce actual
- // mesh position
- vec2 extrude = v_extrude * radius * u_extrude_scale;
-
- // multiply a_pos by 0.5, since we had it * 2 in order to sneak
- // in extrusion data
- vec4 pos = vec4(floor(a_pos * 0.5) + extrude, 0, 1);
-
- gl_Position = u_matrix * pos;
-}
-
-)MBGL_SHADER";
-const char* heatmap::fragmentSource = R"MBGL_SHADER(
-
-#ifndef HAS_UNIFORM_u_weight
-varying highp float weight;
-#else
-uniform highp float u_weight;
-#endif
-
-
-uniform highp float u_intensity;
-varying vec2 v_extrude;
-
-// Gaussian kernel coefficient: 1 / sqrt(2 * PI)
-#define GAUSS_COEF 0.3989422804014327
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_weight
- highp float weight = u_weight;
-#endif
-
-
- // Kernel density estimation with a Gaussian kernel of size 5x5
- float d = -0.5 * 3.0 * 3.0 * dot(v_extrude, v_extrude);
- float val = weight * u_intensity * GAUSS_COEF * exp(d);
-
- gl_FragColor = vec4(val, 1.0, 1.0, 1.0);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* heatmap::vertexSource = source() + 10789;
+const char* heatmap::fragmentSource = source() + 13245;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/heatmap_texture.cpp b/src/mbgl/shaders/heatmap_texture.cpp
index c5d35c48ae..8f5ec1f176 100644
--- a/src/mbgl/shaders/heatmap_texture.cpp
+++ b/src/mbgl/shaders/heatmap_texture.cpp
@@ -1,42 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/heatmap_texture.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* heatmap_texture::name = "heatmap_texture";
-const char* heatmap_texture::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_world;
-attribute vec2 a_pos;
-varying vec2 v_pos;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos * u_world, 0, 1);
-
- v_pos.x = a_pos.x;
- v_pos.y = 1.0 - a_pos.y;
-}
-
-)MBGL_SHADER";
-const char* heatmap_texture::fragmentSource = R"MBGL_SHADER(
-uniform sampler2D u_image;
-uniform sampler2D u_color_ramp;
-uniform float u_opacity;
-varying vec2 v_pos;
-
-void main() {
- float t = texture2D(u_image, v_pos).r;
- vec4 color = texture2D(u_color_ramp, vec2(t, 0.5));
- gl_FragColor = color * u_opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(0.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* heatmap_texture::vertexSource = source() + 13886;
+const char* heatmap_texture::fragmentSource = source() + 14102;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/hillshade.cpp b/src/mbgl/shaders/hillshade.cpp
index 4083faa4b4..ea81d7c10c 100644
--- a/src/mbgl/shaders/hillshade.cpp
+++ b/src/mbgl/shaders/hillshade.cpp
@@ -1,80 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/hillshade.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* hillshade::name = "hillshade";
-const char* hillshade::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-
-attribute vec2 a_pos;
-attribute vec2 a_texture_pos;
-
-varying vec2 v_pos;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
- v_pos = a_texture_pos / 8192.0;
-}
-
-)MBGL_SHADER";
-const char* hillshade::fragmentSource = R"MBGL_SHADER(
-uniform sampler2D u_image;
-varying vec2 v_pos;
-
-uniform vec2 u_latrange;
-uniform vec2 u_light;
-uniform vec4 u_shadow;
-uniform vec4 u_highlight;
-uniform vec4 u_accent;
-
-#define PI 3.141592653589793
-
-void main() {
- vec4 pixel = texture2D(u_image, v_pos);
-
- vec2 deriv = ((pixel.rg * 2.0) - 1.0);
-
- // We divide the slope by a scale factor based on the cosin of the pixel's approximate latitude
- // to account for mercator projection distortion. see #4807 for details
- float scaleFactor = cos(radians((u_latrange[0] - u_latrange[1]) * (1.0 - v_pos.y) + u_latrange[1]));
- // We also multiply the slope by an arbitrary z-factor of 1.25
- float slope = atan(1.25 * length(deriv) / scaleFactor);
- float aspect = deriv.x != 0.0 ? atan(deriv.y, -deriv.x) : PI / 2.0 * (deriv.y > 0.0 ? 1.0 : -1.0);
-
- float intensity = u_light.x;
- // We add PI to make this property match the global light object, which adds PI/2 to the light's azimuthal
- // position property to account for 0deg corresponding to north/the top of the viewport in the style spec
- // and the original shader was written to accept (-illuminationDirection - 90) as the azimuthal.
- float azimuth = u_light.y + PI;
-
- // We scale the slope exponentially based on intensity, using a calculation similar to
- // the exponential interpolation function in the style spec:
- // https://github.com/mapbox/mapbox-gl-js/blob/master/src/style-spec/expression/definitions/interpolate.js#L217-L228
- // so that higher intensity values create more opaque hillshading.
- float base = 1.875 - intensity * 1.75;
- float maxValue = 0.5 * PI;
- float scaledSlope = intensity != 0.5 ? ((pow(base, slope) - 1.0) / (pow(base, maxValue) - 1.0)) * maxValue : slope;
-
- // The accent color is calculated with the cosine of the slope while the shade color is calculated with the sine
- // so that the accent color's rate of change eases in while the shade color's eases out.
- float accent = cos(scaledSlope);
- // We multiply both the accent and shade color by a clamped intensity value
- // so that intensities >= 0.5 do not additionally affect the color values
- // while intensity values < 0.5 make the overall color more transparent.
- vec4 accent_color = (1.0 - accent) * u_accent * clamp(intensity * 2.0, 0.0, 1.0);
- float shade = abs(mod((aspect + azimuth) / PI + 0.5, 2.0) - 1.0);
- vec4 shade_color = mix(u_shadow, u_highlight, shade) * sin(scaledSlope) * clamp(intensity * 2.0, 0.0, 1.0);
- gl_FragColor = accent_color * (1.0 - shade_color.a) + shade_color;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* hillshade::vertexSource = source() + 34909;
+const char* hillshade::fragmentSource = source() + 35108;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/hillshade_prepare.cpp b/src/mbgl/shaders/hillshade_prepare.cpp
index 8d0571f6a4..fb610f01b2 100644
--- a/src/mbgl/shaders/hillshade_prepare.cpp
+++ b/src/mbgl/shaders/hillshade_prepare.cpp
@@ -1,100 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/hillshade_prepare.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* hillshade_prepare::name = "hillshade_prepare";
-const char* hillshade_prepare::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-
-attribute vec2 a_pos;
-attribute vec2 a_texture_pos;
-
-varying vec2 v_pos;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
- v_pos = (a_texture_pos / 8192.0) / 2.0 + 0.25;
-}
-
-)MBGL_SHADER";
-const char* hillshade_prepare::fragmentSource = R"MBGL_SHADER(
-#ifdef GL_ES
-precision highp float;
-#endif
-
-uniform sampler2D u_image;
-varying vec2 v_pos;
-uniform vec2 u_dimension;
-uniform float u_zoom;
-uniform float u_maxzoom;
-
-float getElevation(vec2 coord, float bias) {
- // Convert encoded elevation value to meters
- vec4 data = texture2D(u_image, coord) * 255.0;
- return (data.r + data.g * 256.0 + data.b * 256.0 * 256.0) / 4.0;
-}
-
-void main() {
- vec2 epsilon = 1.0 / u_dimension;
-
- // queried pixels:
- // +-----------+
- // | | | |
- // | a | b | c |
- // | | | |
- // +-----------+
- // | | | |
- // | d | e | f |
- // | | | |
- // +-----------+
- // | | | |
- // | g | h | i |
- // | | | |
- // +-----------+
-
- float a = getElevation(v_pos + vec2(-epsilon.x, -epsilon.y), 0.0);
- float b = getElevation(v_pos + vec2(0, -epsilon.y), 0.0);
- float c = getElevation(v_pos + vec2(epsilon.x, -epsilon.y), 0.0);
- float d = getElevation(v_pos + vec2(-epsilon.x, 0), 0.0);
- float e = getElevation(v_pos, 0.0);
- float f = getElevation(v_pos + vec2(epsilon.x, 0), 0.0);
- float g = getElevation(v_pos + vec2(-epsilon.x, epsilon.y), 0.0);
- float h = getElevation(v_pos + vec2(0, epsilon.y), 0.0);
- float i = getElevation(v_pos + vec2(epsilon.x, epsilon.y), 0.0);
-
- // here we divide the x and y slopes by 8 * pixel size
- // where pixel size (aka meters/pixel) is:
- // circumference of the world / (pixels per tile * number of tiles)
- // which is equivalent to: 8 * 40075016.6855785 / (512 * pow(2, u_zoom))
- // which can be reduced to: pow(2, 19.25619978527 - u_zoom)
- // we want to vertically exaggerate the hillshading though, because otherwise
- // it is barely noticeable at low zooms. to do this, we multiply this by some
- // scale factor pow(2, (u_zoom - u_maxzoom) * a) where a is an arbitrary value
- // Here we use a=0.3 which works out to the expression below. see
- // nickidlugash's awesome breakdown for more info
- // https://github.com/mapbox/mapbox-gl-js/pull/5286#discussion_r148419556
- float exaggeration = u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;
-
- vec2 deriv = vec2(
- (c + f + f + i) - (a + d + d + g),
- (g + h + h + i) - (a + b + b + c)
- ) / pow(2.0, (u_zoom - u_maxzoom) * exaggeration + 19.2562 - u_zoom);
-
- gl_FragColor = clamp(vec4(
- deriv.x / 2.0 + 0.5,
- deriv.y / 2.0 + 0.5,
- 1.0,
- 1.0), 0.0, 1.0);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* hillshade_prepare::vertexSource = source() + 32175;
+const char* hillshade_prepare::fragmentSource = source() + 32389;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp
index 68d2dcc468..1ba2a9f403 100644
--- a/src/mbgl/shaders/line.cpp
+++ b/src/mbgl/shaders/line.cpp
@@ -1,240 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/line.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* line::name = "line";
-const char* line::vertexSource = R"MBGL_SHADER(
-
-
-// the distance over which the line edge fades out.
-// Retina devices need a smaller distance to avoid aliasing.
-#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0
-
-// floor(127 / 2) == 63.0
-// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
-// stored in a byte (-128..127). we scale regular normals up to length 63, but
-// there are also "special" normals that have a bigger length (of up to 126 in
-// this case).
-// #define scale 63.0
-#define scale 0.015873016
-
-attribute vec4 a_pos_normal;
-attribute vec4 a_data;
-
-uniform mat4 u_matrix;
-uniform mediump float u_ratio;
-uniform vec2 u_gl_units_to_pixels;
-
-varying vec2 v_normal;
-varying vec2 v_width2;
-varying float v_gamma_scale;
-varying highp float v_linesofar;
-
-
-#ifndef HAS_UNIFORM_u_color
-uniform lowp float a_color_t;
-attribute highp vec4 a_color;
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
-uniform lowp float a_blur_t;
-attribute lowp vec2 a_blur;
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_gapwidth
-uniform lowp float a_gapwidth_t;
-attribute mediump vec2 a_gapwidth;
-#else
-uniform mediump float u_gapwidth;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_offset
-uniform lowp float a_offset_t;
-attribute lowp vec2 a_offset;
-#else
-uniform lowp float u_offset;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
-uniform lowp float a_width_t;
-attribute mediump vec2 a_width;
-#else
-uniform mediump float u_width;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_color
- color = unpack_mix_vec4(a_color, a_color_t);
-#else
- highp vec4 color = u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
- blur = unpack_mix_vec2(a_blur, a_blur_t);
-#else
- lowp float blur = u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_gapwidth
- mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t);
-#else
- mediump float gapwidth = u_gapwidth;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_offset
- lowp float offset = unpack_mix_vec2(a_offset, a_offset_t);
-#else
- lowp float offset = u_offset;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
- mediump float width = unpack_mix_vec2(a_width, a_width_t);
-#else
- mediump float width = u_width;
-#endif
-
-
- vec2 a_extrude = a_data.xy - 128.0;
- float a_direction = mod(a_data.z, 4.0) - 1.0;
-
- v_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0;
-
- vec2 pos = a_pos_normal.xy;
-
- // x is 1 if it's a round cap, 0 otherwise
- // y is 1 if the normal points up, and -1 if it points down
- mediump vec2 normal = a_pos_normal.zw;
- v_normal = normal;
-
- // these transformations used to be applied in the JS and native code bases.
- // moved them into the shader for clarity and simplicity.
- gapwidth = gapwidth / 2.0;
- float halfwidth = width / 2.0;
- offset = -1.0 * offset;
-
- float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
- float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
-
- // Scale the extrusion vector down to a normal and then up by the line width
- // of this vertex.
- mediump vec2 dist = outset * a_extrude * scale;
-
- // Calculate the offset when drawing a line that is to the side of the actual line.
- // We do this by creating a vector that points towards the extrude, but rotate
- // it when we're drawing round end points (a_direction = -1 or 1) since their
- // extrude vector points in another direction.
- mediump float u = 0.5 * a_direction;
- mediump float t = 1.0 - abs(u);
- mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
-
- vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
- gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
-
- // calculate how much the perspective view squishes or stretches the extrude
- float extrude_length_without_perspective = length(dist);
- float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);
- v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;
-
- v_width2 = vec2(outset, inset);
-}
-
-)MBGL_SHADER";
-const char* line::fragmentSource = R"MBGL_SHADER(
-
-#ifndef HAS_UNIFORM_u_color
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-varying vec2 v_width2;
-varying vec2 v_normal;
-varying float v_gamma_scale;
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_color
- highp vec4 color = u_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_blur
- lowp float blur = u_blur;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- // Calculate the distance of the pixel from the line in pixels.
- float dist = length(v_normal) * v_width2.s;
-
- // Calculate the antialiasing fade factor. This is either when fading in
- // the line in case of an offset line (v_width2.t) or when fading out
- // (v_width2.s)
- float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;
- float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);
-
- gl_FragColor = color * (alpha * opacity);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* line::vertexSource = source() + 37744;
+const char* line::fragmentSource = source() + 42206;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp
index be88255e3c..56eac4a666 100644
--- a/src/mbgl/shaders/line_pattern.cpp
+++ b/src/mbgl/shaders/line_pattern.cpp
@@ -1,241 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/line_pattern.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* line_pattern::name = "line_pattern";
-const char* line_pattern::vertexSource = R"MBGL_SHADER(
-// floor(127 / 2) == 63.0
-// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
-// stored in a byte (-128..127). we scale regular normals up to length 63, but
-// there are also "special" normals that have a bigger length (of up to 126 in
-// this case).
-// #define scale 63.0
-#define scale 0.015873016
-
-// We scale the distance before adding it to the buffers so that we can store
-// long distances for long segments. Use this value to unscale the distance.
-#define LINE_DISTANCE_SCALE 2.0
-
-// the distance over which the line edge fades out.
-// Retina devices need a smaller distance to avoid aliasing.
-#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0
-
-attribute vec4 a_pos_normal;
-attribute vec4 a_data;
-
-uniform mat4 u_matrix;
-uniform mediump float u_ratio;
-uniform vec2 u_gl_units_to_pixels;
-
-varying vec2 v_normal;
-varying vec2 v_width2;
-varying float v_linesofar;
-varying float v_gamma_scale;
-
-
-#ifndef HAS_UNIFORM_u_blur
-uniform lowp float a_blur_t;
-attribute lowp vec2 a_blur;
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_offset
-uniform lowp float a_offset_t;
-attribute lowp vec2 a_offset;
-#else
-uniform lowp float u_offset;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_gapwidth
-uniform lowp float a_gapwidth_t;
-attribute mediump vec2 a_gapwidth;
-#else
-uniform mediump float u_gapwidth;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
-uniform lowp float a_width_t;
-attribute mediump vec2 a_width;
-#else
-uniform mediump float u_width;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_blur
- blur = unpack_mix_vec2(a_blur, a_blur_t);
-#else
- lowp float blur = u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_offset
- lowp float offset = unpack_mix_vec2(a_offset, a_offset_t);
-#else
- lowp float offset = u_offset;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_gapwidth
- mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t);
-#else
- mediump float gapwidth = u_gapwidth;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
- mediump float width = unpack_mix_vec2(a_width, a_width_t);
-#else
- mediump float width = u_width;
-#endif
-
-
- vec2 a_extrude = a_data.xy - 128.0;
- float a_direction = mod(a_data.z, 4.0) - 1.0;
- float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;
-
- vec2 pos = a_pos_normal.xy;
-
- // x is 1 if it's a round cap, 0 otherwise
- // y is 1 if the normal points up, and -1 if it points down
- mediump vec2 normal = a_pos_normal.zw;
- v_normal = normal;
-
- // these transformations used to be applied in the JS and native code bases.
- // moved them into the shader for clarity and simplicity.
- gapwidth = gapwidth / 2.0;
- float halfwidth = width / 2.0;
- offset = -1.0 * offset;
-
- float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
- float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
-
- // Scale the extrusion vector down to a normal and then up by the line width
- // of this vertex.
- mediump vec2 dist = outset * a_extrude * scale;
-
- // Calculate the offset when drawing a line that is to the side of the actual line.
- // We do this by creating a vector that points towards the extrude, but rotate
- // it when we're drawing round end points (a_direction = -1 or 1) since their
- // extrude vector points in another direction.
- mediump float u = 0.5 * a_direction;
- mediump float t = 1.0 - abs(u);
- mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
-
- vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
- gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
-
- // calculate how much the perspective view squishes or stretches the extrude
- float extrude_length_without_perspective = length(dist);
- float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);
- v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;
-
- v_linesofar = a_linesofar;
- v_width2 = vec2(outset, inset);
-}
-
-)MBGL_SHADER";
-const char* line_pattern::fragmentSource = R"MBGL_SHADER(
-uniform vec2 u_pattern_size_a;
-uniform vec2 u_pattern_size_b;
-uniform vec2 u_pattern_tl_a;
-uniform vec2 u_pattern_br_a;
-uniform vec2 u_pattern_tl_b;
-uniform vec2 u_pattern_br_b;
-uniform vec2 u_texsize;
-uniform float u_fade;
-
-uniform sampler2D u_image;
-
-varying vec2 v_normal;
-varying vec2 v_width2;
-varying float v_linesofar;
-varying float v_gamma_scale;
-
-
-#ifndef HAS_UNIFORM_u_blur
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_blur
- lowp float blur = u_blur;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- // Calculate the distance of the pixel from the line in pixels.
- float dist = length(v_normal) * v_width2.s;
-
- // Calculate the antialiasing fade factor. This is either when fading in
- // the line in case of an offset line (v_width2.t) or when fading out
- // (v_width2.s)
- float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;
- float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);
-
- float x_a = mod(v_linesofar / u_pattern_size_a.x, 1.0);
- float x_b = mod(v_linesofar / u_pattern_size_b.x, 1.0);
-
- // v_normal.y is 0 at the midpoint of the line, -1 at the lower edge, 1 at the upper edge
- // we clamp the line width outset to be between 0 and half the pattern height plus padding (2.0)
- // to ensure we don't sample outside the designated symbol on the sprite sheet.
- // 0.5 is added to shift the component to be bounded between 0 and 1 for interpolation of
- // the texture coordinate
- float y_a = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (u_pattern_size_a.y + 2.0) / 2.0) / u_pattern_size_a.y);
- float y_b = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (u_pattern_size_b.y + 2.0) / 2.0) / u_pattern_size_b.y);
- vec2 pos_a = mix(u_pattern_tl_a / u_texsize, u_pattern_br_a / u_texsize, vec2(x_a, y_a));
- vec2 pos_b = mix(u_pattern_tl_b / u_texsize, u_pattern_br_b / u_texsize, vec2(x_b, y_b));
-
- vec4 color = mix(texture2D(u_image, pos_a), texture2D(u_image, pos_b), u_fade);
-
- gl_FragColor = color * alpha * opacity;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* line_pattern::vertexSource = source() + 43378;
+const char* line_pattern::fragmentSource = source() + 47787;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp
index c5d50566e8..f36cf2ba00 100644
--- a/src/mbgl/shaders/line_sdf.cpp
+++ b/src/mbgl/shaders/line_sdf.cpp
@@ -1,302 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/line_sdf.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* line_sdf::name = "line_sdf";
-const char* line_sdf::vertexSource = R"MBGL_SHADER(
-// floor(127 / 2) == 63.0
-// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
-// stored in a byte (-128..127). we scale regular normals up to length 63, but
-// there are also "special" normals that have a bigger length (of up to 126 in
-// this case).
-// #define scale 63.0
-#define scale 0.015873016
-
-// We scale the distance before adding it to the buffers so that we can store
-// long distances for long segments. Use this value to unscale the distance.
-#define LINE_DISTANCE_SCALE 2.0
-
-// the distance over which the line edge fades out.
-// Retina devices need a smaller distance to avoid aliasing.
-#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0
-
-attribute vec4 a_pos_normal;
-attribute vec4 a_data;
-
-uniform mat4 u_matrix;
-uniform mediump float u_ratio;
-uniform vec2 u_patternscale_a;
-uniform float u_tex_y_a;
-uniform vec2 u_patternscale_b;
-uniform float u_tex_y_b;
-uniform vec2 u_gl_units_to_pixels;
-
-varying vec2 v_normal;
-varying vec2 v_width2;
-varying vec2 v_tex_a;
-varying vec2 v_tex_b;
-varying float v_gamma_scale;
-
-
-#ifndef HAS_UNIFORM_u_color
-uniform lowp float a_color_t;
-attribute highp vec4 a_color;
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
-uniform lowp float a_blur_t;
-attribute lowp vec2 a_blur;
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_gapwidth
-uniform lowp float a_gapwidth_t;
-attribute mediump vec2 a_gapwidth;
-#else
-uniform mediump float u_gapwidth;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_offset
-uniform lowp float a_offset_t;
-attribute lowp vec2 a_offset;
-#else
-uniform lowp float u_offset;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
-uniform lowp float a_width_t;
-attribute mediump vec2 a_width;
-varying mediump float width;
-#else
-uniform mediump float u_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_floorwidth
-uniform lowp float a_floorwidth_t;
-attribute lowp vec2 a_floorwidth;
-varying lowp float floorwidth;
-#else
-uniform lowp float u_floorwidth;
-#endif
-
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_color
- color = unpack_mix_vec4(a_color, a_color_t);
-#else
- highp vec4 color = u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
- blur = unpack_mix_vec2(a_blur, a_blur_t);
-#else
- lowp float blur = u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_gapwidth
- mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t);
-#else
- mediump float gapwidth = u_gapwidth;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_offset
- lowp float offset = unpack_mix_vec2(a_offset, a_offset_t);
-#else
- lowp float offset = u_offset;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
- width = unpack_mix_vec2(a_width, a_width_t);
-#else
- mediump float width = u_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_floorwidth
- floorwidth = unpack_mix_vec2(a_floorwidth, a_floorwidth_t);
-#else
- lowp float floorwidth = u_floorwidth;
-#endif
-
-
- vec2 a_extrude = a_data.xy - 128.0;
- float a_direction = mod(a_data.z, 4.0) - 1.0;
- float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;
-
- vec2 pos = a_pos_normal.xy;
-
- // x is 1 if it's a round cap, 0 otherwise
- // y is 1 if the normal points up, and -1 if it points down
- mediump vec2 normal = a_pos_normal.zw;
- v_normal = normal;
-
- // these transformations used to be applied in the JS and native code bases.
- // moved them into the shader for clarity and simplicity.
- gapwidth = gapwidth / 2.0;
- float halfwidth = width / 2.0;
- offset = -1.0 * offset;
-
- float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
- float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
-
- // Scale the extrusion vector down to a normal and then up by the line width
- // of this vertex.
- mediump vec2 dist =outset * a_extrude * scale;
-
- // Calculate the offset when drawing a line that is to the side of the actual line.
- // We do this by creating a vector that points towards the extrude, but rotate
- // it when we're drawing round end points (a_direction = -1 or 1) since their
- // extrude vector points in another direction.
- mediump float u = 0.5 * a_direction;
- mediump float t = 1.0 - abs(u);
- mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
-
- vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
- gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
-
- // calculate how much the perspective view squishes or stretches the extrude
- float extrude_length_without_perspective = length(dist);
- float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels);
- v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;
-
- v_tex_a = vec2(a_linesofar * u_patternscale_a.x / floorwidth, normal.y * u_patternscale_a.y + u_tex_y_a);
- v_tex_b = vec2(a_linesofar * u_patternscale_b.x / floorwidth, normal.y * u_patternscale_b.y + u_tex_y_b);
-
- v_width2 = vec2(outset, inset);
-}
-
-)MBGL_SHADER";
-const char* line_sdf::fragmentSource = R"MBGL_SHADER(
-
-uniform sampler2D u_image;
-uniform float u_sdfgamma;
-uniform float u_mix;
-
-varying vec2 v_normal;
-varying vec2 v_width2;
-varying vec2 v_tex_a;
-varying vec2 v_tex_b;
-varying float v_gamma_scale;
-
-
-#ifndef HAS_UNIFORM_u_color
-varying highp vec4 color;
-#else
-uniform highp vec4 u_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_blur
-varying lowp float blur;
-#else
-uniform lowp float u_blur;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_width
-varying mediump float width;
-#else
-uniform mediump float u_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_floorwidth
-varying lowp float floorwidth;
-#else
-uniform lowp float u_floorwidth;
-#endif
-
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_color
- highp vec4 color = u_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_blur
- lowp float blur = u_blur;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_width
- mediump float width = u_width;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_floorwidth
- lowp float floorwidth = u_floorwidth;
-#endif
-
-
- // Calculate the distance of the pixel from the line in pixels.
- float dist = length(v_normal) * v_width2.s;
-
- // Calculate the antialiasing fade factor. This is either when fading in
- // the line in case of an offset line (v_width2.t) or when fading out
- // (v_width2.s)
- float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale;
- float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);
-
- float sdfdist_a = texture2D(u_image, v_tex_a).a;
- float sdfdist_b = texture2D(u_image, v_tex_b).a;
- float sdfdist = mix(sdfdist_a, sdfdist_b, u_mix);
- alpha *= smoothstep(0.5 - u_sdfgamma / floorwidth, 0.5 + u_sdfgamma / floorwidth, sdfdist);
-
- gl_FragColor = color * (alpha * opacity);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* line_sdf::vertexSource = source() + 50098;
+const char* line_sdf::fragmentSource = source() + 55464;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/preludes.cpp b/src/mbgl/shaders/preludes.cpp
index 6baa488a10..f4b0349355 100644
--- a/src/mbgl/shaders/preludes.cpp
+++ b/src/mbgl/shaders/preludes.cpp
@@ -1,106 +1,13 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/preludes.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
-const char* vertexPrelude = R"MBGL_SHADER(
-#ifdef GL_ES
-precision highp float;
-#else
-
-#if !defined(lowp)
-#define lowp
-#endif
-
-#if !defined(mediump)
-#define mediump
-#endif
-
-#if !defined(highp)
-#define highp
-#endif
-
-#endif
-
-// Unpack a pair of values that have been packed into a single float.
-// The packed values are assumed to be 8-bit unsigned integers, and are
-// packed like so:
-// packedValue = floor(input[0]) * 256 + input[1],
-vec2 unpack_float(const float packedValue) {
- int packedIntValue = int(packedValue);
- int v0 = packedIntValue / 256;
- return vec2(v0, packedIntValue - v0 * 256);
-}
-
-vec2 unpack_opacity(const float packedOpacity) {
- int intOpacity = int(packedOpacity) / 2;
- return vec2(float(intOpacity) / 127.0, mod(packedOpacity, 2.0));
-}
-
-// To minimize the number of attributes needed, we encode a 4-component
-// color into a pair of floats (i.e. a vec2) as follows:
-// [ floor(color.r * 255) * 256 + color.g * 255,
-// floor(color.b * 255) * 256 + color.g * 255 ]
-vec4 decode_color(const vec2 encodedColor) {
- return vec4(
- unpack_float(encodedColor[0]) / 255.0,
- unpack_float(encodedColor[1]) / 255.0
- );
-}
-
-// Unpack a pair of paint values and interpolate between them.
-float unpack_mix_vec2(const vec2 packedValue, const float t) {
- return mix(packedValue[0], packedValue[1], t);
-}
-
-// Unpack a pair of paint values and interpolate between them.
-vec4 unpack_mix_vec4(const vec4 packedColors, const float t) {
- vec4 minColor = decode_color(vec2(packedColors[0], packedColors[1]));
- vec4 maxColor = decode_color(vec2(packedColors[2], packedColors[3]));
- return mix(minColor, maxColor, t);
-}
-
-// The offset depends on how many pixels are between the world origin and the edge of the tile:
-// vec2 offset = mod(pixel_coord, size)
-//
-// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile.
-// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that.
-//
-// The pixel_coord is passed in as two 16 bit values:
-// pixel_coord_upper = floor(pixel_coord / 2^16)
-// pixel_coord_lower = mod(pixel_coord, 2^16)
-//
-// The offset is calculated in a series of steps that should preserve this precision:
-vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower,
- const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) {
-
- vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size);
- return (tile_units_to_pixels * pos + offset) / pattern_size;
-}
-
-)MBGL_SHADER";
-const char* fragmentPrelude = R"MBGL_SHADER(
-#ifdef GL_ES
-precision mediump float;
-#else
-
-#if !defined(lowp)
-#define lowp
-#endif
-
-#if !defined(mediump)
-#define mediump
-#endif
-
-#if !defined(highp)
-#define highp
-#endif
-
-#endif
-
-)MBGL_SHADER";
+const char* vertexPrelude = source() + 0;
+const char* fragmentPrelude = source() + 2557;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/raster.cpp b/src/mbgl/shaders/raster.cpp
index 98291bfec6..5348f23257 100644
--- a/src/mbgl/shaders/raster.cpp
+++ b/src/mbgl/shaders/raster.cpp
@@ -1,90 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/raster.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* raster::name = "raster";
-const char* raster::vertexSource = R"MBGL_SHADER(
-uniform mat4 u_matrix;
-uniform vec2 u_tl_parent;
-uniform float u_scale_parent;
-uniform float u_buffer_scale;
-
-attribute vec2 a_pos;
-attribute vec2 a_texture_pos;
-
-varying vec2 v_pos0;
-varying vec2 v_pos1;
-
-void main() {
- gl_Position = u_matrix * vec4(a_pos, 0, 1);
- // We are using Int16 for texture position coordinates to give us enough precision for
- // fractional coordinates. We use 8192 to scale the texture coordinates in the buffer
- // as an arbitrarily high number to preserve adequate precision when rendering.
- // This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,
- // so math for modifying either is consistent.
- v_pos0 = (((a_texture_pos / 8192.0) - 0.5) / u_buffer_scale ) + 0.5;
- v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;
-}
-
-)MBGL_SHADER";
-const char* raster::fragmentSource = R"MBGL_SHADER(
-uniform float u_fade_t;
-uniform float u_opacity;
-uniform sampler2D u_image0;
-uniform sampler2D u_image1;
-varying vec2 v_pos0;
-varying vec2 v_pos1;
-
-uniform float u_brightness_low;
-uniform float u_brightness_high;
-
-uniform float u_saturation_factor;
-uniform float u_contrast_factor;
-uniform vec3 u_spin_weights;
-
-void main() {
-
- // read and cross-fade colors from the main and parent tiles
- vec4 color0 = texture2D(u_image0, v_pos0);
- vec4 color1 = texture2D(u_image1, v_pos1);
- if (color0.a > 0.0) {
- color0.rgb = color0.rgb / color0.a;
- }
- if (color1.a > 0.0) {
- color1.rgb = color1.rgb / color1.a;
- }
- vec4 color = mix(color0, color1, u_fade_t);
- color.a *= u_opacity;
- vec3 rgb = color.rgb;
-
- // spin
- rgb = vec3(
- dot(rgb, u_spin_weights.xyz),
- dot(rgb, u_spin_weights.zxy),
- dot(rgb, u_spin_weights.yzx));
-
- // saturation
- float average = (color.r + color.g + color.b) / 3.0;
- rgb += (average - rgb) * u_saturation_factor;
-
- // contrast
- rgb = (rgb - 0.5) * u_contrast_factor + 0.5;
-
- // brightness
- vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);
- vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);
-
- gl_FragColor = vec4(mix(u_high_vec, u_low_vec, rgb) * color.a, color.a);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* raster::vertexSource = source() + 57390;
+const char* raster::fragmentSource = source() + 58203;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/source.cpp b/src/mbgl/shaders/source.cpp
new file mode 100644
index 0000000000..d5a4593ad9
--- /dev/null
+++ b/src/mbgl/shaders/source.cpp
@@ -0,0 +1,1468 @@
+// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
+
+#include <mbgl/shaders/source.hpp>
+#include <mbgl/util/compression.hpp>
+
+#include <cstdint>
+
+namespace mbgl {
+namespace shaders {
+
+const char* source() {
+ static const uint8_t compressed[] = {
+ 0x78, 0xda, 0xed, 0x7d, 0x6b, 0x73, 0x1b, 0x37,
+ 0xb2, 0xe8, 0x7e, 0xf6, 0xaf, 0x40, 0x36, 0x55,
+ 0xc7, 0xa4, 0xcc, 0xb7, 0x24, 0x5b, 0x96, 0x56,
+ 0x27, 0xe5, 0x93, 0x38, 0x39, 0xbe, 0x37, 0x9b,
+ 0xb8, 0x22, 0x67, 0xb3, 0x75, 0x5c, 0x5e, 0xd6,
+ 0x0c, 0x39, 0x24, 0x67, 0x3d, 0x9c, 0x61, 0x66,
+ 0x86, 0xa2, 0xe4, 0x73, 0xf3, 0xdf, 0x6f, 0x3f,
+ 0xf0, 0x9c, 0x97, 0x28, 0x59, 0x92, 0x65, 0x87,
+ 0x5b, 0xab, 0x58, 0x1a, 0x00, 0x8d, 0x06, 0xd0,
+ 0x68, 0x74, 0x37, 0x1a, 0xdd, 0x5f, 0x87, 0xb3,
+ 0x69, 0x30, 0x13, 0x3f, 0xfc, 0x38, 0x7e, 0x79,
+ 0xf6, 0x68, 0x95, 0x06, 0x93, 0x30, 0x0b, 0x93,
+ 0x58, 0x2c, 0xc2, 0xf9, 0x62, 0x25, 0x66, 0x51,
+ 0xe2, 0xe5, 0x27, 0x8f, 0xbe, 0x0e, 0xa2, 0x2c,
+ 0x78, 0xf4, 0xe8, 0xeb, 0x70, 0x26, 0xbe, 0x82,
+ 0xca, 0x61, 0x1c, 0x4c, 0x5b, 0x51, 0xb2, 0x59,
+ 0xb5, 0x1f, 0x7d, 0xcd, 0x7f, 0x0a, 0xfc, 0x0b,
+ 0xaa, 0xc5, 0xd3, 0x70, 0x56, 0xa8, 0xb7, 0x0c,
+ 0xa6, 0xe1, 0x7a, 0x69, 0x55, 0x95, 0x1f, 0xaa,
+ 0x6b, 0x53, 0xb7, 0xa6, 0x2e, 0xfd, 0x69, 0x6a,
+ 0xca, 0x7f, 0xfb, 0x7d, 0xf1, 0x6b, 0xbc, 0xf2,
+ 0x26, 0xef, 0x85, 0x27, 0x56, 0x5e, 0x98, 0x8a,
+ 0x64, 0x26, 0xce, 0xbd, 0x68, 0x1d, 0x64, 0x22,
+ 0x5f, 0x78, 0xb9, 0x58, 0x78, 0xe7, 0x81, 0xf0,
+ 0x83, 0x20, 0x16, 0x58, 0x29, 0x98, 0x8a, 0x30,
+ 0xce, 0x13, 0xa8, 0x9b, 0x85, 0xf1, 0x3c, 0x0a,
+ 0x78, 0x50, 0x3d, 0x84, 0xf2, 0x66, 0x11, 0xa8,
+ 0x2a, 0xb2, 0xbd, 0x97, 0x06, 0xc2, 0xcb, 0xb2,
+ 0x35, 0x20, 0x29, 0xa0, 0x8d, 0x1f, 0x88, 0xa3,
+ 0xae, 0x1f, 0xe6, 0x62, 0x1d, 0x67, 0xe1, 0x3c,
+ 0x66, 0x50, 0xc1, 0x3c, 0x48, 0xb3, 0x8e, 0xf0,
+ 0xe2, 0x29, 0x56, 0x47, 0x38, 0x12, 0x46, 0x14,
+ 0xbe, 0x0f, 0x44, 0x96, 0x1c, 0x9b, 0x4f, 0xff,
+ 0x40, 0xa8, 0xe2, 0x14, 0xbb, 0x4c, 0xd2, 0x56,
+ 0x18, 0xaf, 0xd6, 0xf9, 0xdb, 0xc1, 0xbb, 0xb6,
+ 0xd8, 0x13, 0xa3, 0xc3, 0xa7, 0xe2, 0x89, 0xe0,
+ 0x2f, 0xc3, 0x77, 0x9d, 0x47, 0xe7, 0xc1, 0x64,
+ 0x04, 0xbd, 0x60, 0xb3, 0x31, 0x21, 0xd8, 0x9a,
+ 0x24, 0x71, 0x96, 0x33, 0xb2, 0x36, 0xb4, 0xb6,
+ 0xf8, 0xdf, 0x47, 0x02, 0xfe, 0x07, 0x88, 0xc8,
+ 0xcf, 0xaf, 0xe2, 0x5c, 0xf5, 0x03, 0x1f, 0x5b,
+ 0x76, 0xdd, 0x13, 0x5d, 0xf5, 0x7c, 0x00, 0xc5,
+ 0x85, 0xfa, 0x7d, 0xc4, 0x82, 0xab, 0xa4, 0x41,
+ 0xbe, 0x4e, 0x63, 0x81, 0x58, 0xb4, 0xce, 0x07,
+ 0x9d, 0x62, 0xcd, 0x2e, 0xb6, 0x27, 0xa4, 0x01,
+ 0xe4, 0x1f, 0x8f, 0x1c, 0x6c, 0x13, 0xf8, 0x6f,
+ 0x98, 0x5f, 0x56, 0xe0, 0xfb, 0x33, 0x97, 0xd8,
+ 0x18, 0xc3, 0x8f, 0xfc, 0xea, 0x60, 0xab, 0x6b,
+ 0x02, 0x4a, 0x65, 0x84, 0x78, 0x3e, 0x4c, 0x53,
+ 0xac, 0x36, 0x1c, 0x3d, 0xeb, 0x01, 0x9e, 0xcb,
+ 0x64, 0xea, 0x82, 0xe8, 0x88, 0x51, 0x6f, 0xd0,
+ 0x66, 0x2c, 0x71, 0x85, 0x13, 0xb1, 0x0c, 0xe3,
+ 0x70, 0x19, 0x7e, 0x08, 0x80, 0x36, 0x02, 0x11,
+ 0xaf, 0x97, 0x7e, 0x40, 0x04, 0xe3, 0xe5, 0x79,
+ 0x1a, 0xfa, 0xeb, 0x1c, 0x16, 0x3d, 0x0e, 0x82,
+ 0x69, 0x30, 0xed, 0x88, 0x4d, 0x20, 0x82, 0x78,
+ 0x92, 0x4c, 0x81, 0x04, 0xc4, 0x41, 0x77, 0x92,
+ 0x2c, 0x57, 0x49, 0x1c, 0xc4, 0x39, 0xc2, 0x99,
+ 0x24, 0x51, 0x92, 0x2a, 0x3a, 0x52, 0x34, 0x47,
+ 0x78, 0x65, 0xa2, 0x15, 0xf6, 0x82, 0x1e, 0x7c,
+ 0x46, 0x5c, 0xdb, 0x40, 0x3d, 0x62, 0x96, 0x44,
+ 0xb0, 0x1f, 0x32, 0xa2, 0x83, 0xb7, 0x72, 0xed,
+ 0x09, 0x40, 0x2f, 0xa5, 0x49, 0x3c, 0x34, 0x04,
+ 0xc0, 0x9f, 0xe7, 0xfc, 0xb9, 0x83, 0x0d, 0x84,
+ 0xd3, 0xc0, 0x6f, 0x6c, 0x20, 0xde, 0xe1, 0x4a,
+ 0x1c, 0x88, 0x69, 0x80, 0x58, 0x8f, 0xa9, 0x4c,
+ 0xae, 0x03, 0xad, 0x10, 0x8f, 0x66, 0xfa, 0x2d,
+ 0x7e, 0x57, 0xab, 0x60, 0x26, 0xf6, 0xa0, 0x45,
+ 0x1f, 0xf0, 0x7f, 0x0e, 0xe1, 0xd9, 0xad, 0x88,
+ 0x5a, 0x91, 0x4e, 0x0e, 0x61, 0xb6, 0xb7, 0xa8,
+ 0x3e, 0x34, 0xd5, 0xa9, 0xb6, 0x5e, 0x88, 0xd2,
+ 0x86, 0x85, 0x7f, 0x91, 0x2c, 0xe5, 0xb6, 0x8b,
+ 0x79, 0x67, 0xa5, 0xab, 0x24, 0xf2, 0x72, 0xdc,
+ 0xbc, 0xf9, 0x06, 0xf7, 0x2f, 0x2c, 0xd9, 0xb2,
+ 0xf7, 0x88, 0x69, 0x4a, 0x76, 0xba, 0x0c, 0x2f,
+ 0xc6, 0x44, 0x15, 0xd6, 0x38, 0x2d, 0x92, 0xef,
+ 0x08, 0x9b, 0x0e, 0xf3, 0xc2, 0xa8, 0xa1, 0xb1,
+ 0xbd, 0x3f, 0x60, 0x74, 0x1d, 0xbb, 0x31, 0xee,
+ 0x44, 0x68, 0x73, 0x1b, 0x38, 0xd3, 0xba, 0xb8,
+ 0x28, 0x1f, 0x18, 0x94, 0x0f, 0x64, 0xaf, 0x34,
+ 0x69, 0x59, 0x0d, 0xce, 0x54, 0x0f, 0xa8, 0x97,
+ 0x2a, 0xc1, 0x76, 0x71, 0x56, 0x99, 0xa6, 0xc0,
+ 0x06, 0x62, 0x8d, 0x45, 0x7e, 0x80, 0xb5, 0x90,
+ 0x0c, 0x80, 0x21, 0x79, 0x17, 0x5b, 0x42, 0x1a,
+ 0x15, 0x21, 0xed, 0x6b, 0x48, 0xd6, 0x3c, 0x2a,
+ 0xcc, 0x3a, 0x1a, 0xb2, 0x3d, 0x77, 0xc8, 0x5a,
+ 0x93, 0xd9, 0x2c, 0x0b, 0x72, 0xe8, 0x6d, 0x05,
+ 0x8c, 0x3b, 0x13, 0x78, 0xaa, 0x24, 0x1b, 0xa8,
+ 0x1d, 0x5f, 0x8a, 0x55, 0x78, 0x01, 0x67, 0x0a,
+ 0xb1, 0x5b, 0x6b, 0xde, 0xc4, 0x26, 0x49, 0xa3,
+ 0xa9, 0x48, 0xd2, 0x70, 0x1e, 0xc6, 0x34, 0xc1,
+ 0xf8, 0x31, 0x98, 0xce, 0x11, 0x16, 0xfd, 0x9e,
+ 0x87, 0x51, 0x40, 0xfb, 0x8a, 0xd6, 0x5d, 0x76,
+ 0x70, 0xca, 0x6c, 0x00, 0x41, 0xc2, 0x98, 0x92,
+ 0x14, 0xb6, 0x72, 0x06, 0x1b, 0xbe, 0x0d, 0xf5,
+ 0xb0, 0xea, 0x8b, 0x9c, 0xce, 0x11, 0xf1, 0x21,
+ 0x49, 0x96, 0x22, 0x0a, 0xce, 0xb1, 0x63, 0x80,
+ 0x85, 0x9c, 0x1e, 0x7f, 0x80, 0xcf, 0xc7, 0xb4,
+ 0xb8, 0x8c, 0xd2, 0xb5, 0xd1, 0xd1, 0x27, 0xc9,
+ 0x3c, 0xca, 0x22, 0x91, 0xad, 0x82, 0x09, 0x8c,
+ 0x34, 0xba, 0x14, 0xf3, 0xb5, 0x97, 0x7a, 0x40,
+ 0x1f, 0x40, 0x2a, 0xc3, 0xa7, 0x02, 0x0e, 0x91,
+ 0x8c, 0x7a, 0xd1, 0x27, 0xec, 0x0c, 0x96, 0xc2,
+ 0x3a, 0x65, 0xb3, 0x9e, 0xf8, 0x2d, 0x20, 0x56,
+ 0x04, 0xa3, 0x49, 0x91, 0x5b, 0x79, 0x31, 0x1d,
+ 0x67, 0x3d, 0x39, 0x0c, 0x3a, 0xac, 0xcc, 0x18,
+ 0x45, 0x98, 0xc1, 0x22, 0x65, 0x19, 0x9d, 0x49,
+ 0xc8, 0x75, 0xf2, 0x4d, 0x22, 0x3b, 0x92, 0x14,
+ 0xca, 0xe7, 0x90, 0x69, 0x31, 0x5e, 0xaf, 0x56,
+ 0x41, 0xaa, 0x4f, 0x23, 0x1b, 0x16, 0x6c, 0xd9,
+ 0x7f, 0x0d, 0x9f, 0xb6, 0x8b, 0x0d, 0x80, 0x8b,
+ 0x51, 0x83, 0xd2, 0xf4, 0xaa, 0xda, 0x85, 0x95,
+ 0x06, 0x94, 0x26, 0x5e, 0x34, 0x59, 0xe3, 0x7e,
+ 0x60, 0xb4, 0x44, 0x16, 0xa4, 0x61, 0x40, 0x23,
+ 0xcf, 0xf2, 0x60, 0x25, 0x0f, 0xe8, 0x6c, 0x91,
+ 0xac, 0x61, 0x62, 0x61, 0x2e, 0xa0, 0xf8, 0x1c,
+ 0xc7, 0x8a, 0x83, 0x51, 0x33, 0x73, 0xcc, 0xc7,
+ 0xcb, 0x3c, 0xc8, 0xc7, 0x2b, 0xe0, 0xd2, 0x41,
+ 0x1a, 0x8f, 0x57, 0x49, 0xe6, 0xec, 0xf7, 0xe2,
+ 0xa0, 0xd4, 0x0e, 0x2a, 0x95, 0xd2, 0x08, 0x98,
+ 0x71, 0x39, 0xfc, 0x82, 0xc1, 0x22, 0x95, 0x14,
+ 0x36, 0x1f, 0x2c, 0xe8, 0x78, 0x1d, 0xc3, 0x62,
+ 0x8d, 0xf3, 0x64, 0xcc, 0x24, 0xe1, 0x02, 0x4f,
+ 0x32, 0xdc, 0x9f, 0x6a, 0x5b, 0x15, 0x68, 0x50,
+ 0xfd, 0x54, 0x20, 0x68, 0xf7, 0x29, 0xd9, 0x79,
+ 0x6f, 0x50, 0xf3, 0x19, 0xf8, 0x7c, 0x79, 0x10,
+ 0x6e, 0x55, 0x67, 0x3b, 0xb6, 0xaa, 0xd0, 0x06,
+ 0x60, 0x80, 0x2c, 0x80, 0x62, 0x0c, 0x91, 0x2f,
+ 0xdb, 0x10, 0x70, 0xa3, 0xfe, 0xe5, 0xeb, 0x6a,
+ 0xe1, 0x4f, 0x8a, 0x68, 0x0f, 0x53, 0xfc, 0xfb,
+ 0x8b, 0x3e, 0xb9, 0x79, 0x01, 0x3c, 0xa4, 0x8e,
+ 0x93, 0x47, 0x8f, 0x60, 0xf8, 0xb0, 0xa5, 0x96,
+ 0xc0, 0x5f, 0x72, 0xe0, 0xbc, 0x63, 0xf8, 0x27,
+ 0x0d, 0x2f, 0xe0, 0xfb, 0x79, 0x12, 0xc2, 0x96,
+ 0x02, 0xce, 0xdd, 0x52, 0x8c, 0x75, 0x1e, 0x8d,
+ 0x5f, 0x27, 0x59, 0x98, 0xe3, 0x50, 0x4f, 0x75,
+ 0x55, 0x98, 0x2f, 0x62, 0xd2, 0x04, 0xaf, 0x23,
+ 0x60, 0x6d, 0x86, 0xc4, 0xcd, 0xfe, 0xa2, 0x00,
+ 0x33, 0x4b, 0x67, 0xae, 0x79, 0xa2, 0xbb, 0x93,
+ 0x87, 0x93, 0x12, 0x83, 0xea, 0x3a, 0xfc, 0x3e,
+ 0xf5, 0xe6, 0x8a, 0xfd, 0x4a, 0x18, 0xd0, 0xa1,
+ 0xdd, 0x4c, 0xae, 0xc5, 0xcf, 0xff, 0x78, 0xf9,
+ 0xcb, 0x77, 0xbf, 0xbc, 0xf8, 0x6d, 0xfc, 0xea,
+ 0xa7, 0xb3, 0xd7, 0x2f, 0xbf, 0x7d, 0xf3, 0xf3,
+ 0x2f, 0x55, 0x20, 0x08, 0xd3, 0x21, 0x48, 0x3a,
+ 0x27, 0x6a, 0x5a, 0x2c, 0x44, 0x0b, 0x33, 0x60,
+ 0xe1, 0x0f, 0x42, 0xdb, 0xd8, 0x26, 0x82, 0xb1,
+ 0xd7, 0x5c, 0xec, 0x97, 0x8b, 0x8b, 0x94, 0xdd,
+ 0x58, 0x83, 0x28, 0xb7, 0x3c, 0x57, 0x19, 0x70,
+ 0x09, 0xa7, 0x6f, 0xb7, 0xc0, 0x2f, 0x17, 0x54,
+ 0x11, 0x38, 0xcc, 0x59, 0x0d, 0x29, 0x9c, 0x7b,
+ 0xe9, 0x25, 0xc8, 0xfa, 0xfc, 0xf1, 0x1c, 0x3f,
+ 0x62, 0x67, 0x15, 0x5f, 0xfd, 0x8f, 0xa6, 0x0f,
+ 0x66, 0x04, 0xdc, 0x05, 0x54, 0x2e, 0x32, 0xad,
+ 0x8a, 0x09, 0xeb, 0x54, 0xcd, 0x51, 0xc7, 0xcc,
+ 0x0a, 0x91, 0x85, 0xbb, 0x48, 0x9d, 0x9a, 0x19,
+ 0xe8, 0xf0, 0x88, 0xd5, 0x29, 0xcf, 0x43, 0xba,
+ 0x15, 0x2c, 0xfc, 0x32, 0x16, 0xfe, 0xd5, 0x58,
+ 0xb8, 0x9b, 0xc5, 0xa6, 0xa6, 0x3c, 0x6a, 0x20,
+ 0x35, 0x3f, 0x6d, 0x28, 0x84, 0x96, 0x7e, 0x53,
+ 0xcb, 0x72, 0x61, 0x1e, 0x5c, 0x30, 0x83, 0x2b,
+ 0x12, 0xd1, 0xd2, 0xde, 0x0d, 0xe5, 0x7d, 0xab,
+ 0x4a, 0x32, 0x6f, 0xb9, 0x8a, 0x82, 0x74, 0xf4,
+ 0x1d, 0x94, 0x86, 0x4b, 0x6f, 0x1e, 0x7c, 0x3c,
+ 0x45, 0x51, 0x05, 0x82, 0xc5, 0xe7, 0x2d, 0x9f,
+ 0x16, 0x12, 0x0e, 0x10, 0x12, 0x6d, 0x64, 0x5d,
+ 0x11, 0xd9, 0xf6, 0x29, 0xc9, 0x58, 0xee, 0x04,
+ 0x02, 0x07, 0xd7, 0xa3, 0xeb, 0x14, 0xe6, 0xcf,
+ 0x2d, 0x33, 0x5d, 0xd9, 0x12, 0x20, 0x71, 0x9d,
+ 0x21, 0x80, 0x86, 0x7a, 0x70, 0x6e, 0x04, 0xa3,
+ 0xef, 0x5a, 0x72, 0x84, 0x1d, 0xc1, 0x0b, 0x58,
+ 0x85, 0x2c, 0x51, 0x94, 0x41, 0xd7, 0xaf, 0x42,
+ 0x77, 0x54, 0x85, 0xaf, 0xdf, 0x80, 0xaf, 0x5f,
+ 0x87, 0xef, 0xd8, 0x2f, 0x61, 0x3c, 0xaa, 0xc5,
+ 0x78, 0xa4, 0x50, 0x2e, 0x70, 0x47, 0x44, 0x85,
+ 0x07, 0xdb, 0x91, 0x20, 0x3a, 0xbc, 0xfc, 0xed,
+ 0xfb, 0xe6, 0xb9, 0x7e, 0x92, 0x44, 0x7a, 0x53,
+ 0x6d, 0xc2, 0x7c, 0x01, 0x35, 0x56, 0xa5, 0xe2,
+ 0x55, 0x98, 0x4f, 0x16, 0x15, 0xc5, 0x92, 0xa0,
+ 0x61, 0xec, 0xe9, 0x1a, 0xe4, 0x75, 0x82, 0x62,
+ 0x4a, 0x2d, 0xe1, 0x11, 0x8f, 0x14, 0x6f, 0x19,
+ 0xa4, 0x1e, 0xee, 0xca, 0x49, 0x80, 0x5a, 0xc9,
+ 0x78, 0x1a, 0x66, 0xb9, 0x17, 0x4f, 0x82, 0x7a,
+ 0x36, 0x89, 0xc3, 0x8f, 0x71, 0xfc, 0xff, 0xfd,
+ 0xe2, 0x6c, 0xfc, 0xeb, 0x4f, 0xaf, 0xbe, 0xff,
+ 0xf9, 0x97, 0xbf, 0x8f, 0xe5, 0xe1, 0xa4, 0x7b,
+ 0xc1, 0xa3, 0x5d, 0x76, 0xe2, 0x71, 0xd1, 0x18,
+ 0x44, 0x02, 0x03, 0x91, 0xb1, 0xa0, 0xd5, 0xf2,
+ 0xd4, 0xd9, 0xa8, 0xf6, 0x85, 0x55, 0x26, 0x4b,
+ 0x58, 0x94, 0x70, 0x47, 0xe0, 0x9e, 0xab, 0xea,
+ 0xb4, 0xaf, 0x41, 0x2e, 0xf5, 0x40, 0x7c, 0xc8,
+ 0xaa, 0xb1, 0xe3, 0x32, 0x17, 0x3d, 0x25, 0xca,
+ 0xc8, 0x81, 0x73, 0x15, 0x83, 0xa1, 0x23, 0xe9,
+ 0x08, 0x55, 0xea, 0x62, 0xe9, 0xd6, 0x59, 0x8f,
+ 0x4d, 0xad, 0x46, 0x4c, 0xfd, 0x68, 0x5d, 0x33,
+ 0x8b, 0x58, 0xe2, 0x62, 0x49, 0xc5, 0x12, 0x45,
+ 0x2c, 0x35, 0x08, 0x5a, 0x0d, 0xb9, 0xc0, 0xc5,
+ 0xcd, 0x2a, 0x5e, 0x8f, 0x55, 0x85, 0x46, 0xb4,
+ 0x24, 0xf1, 0x57, 0x63, 0x26, 0x0b, 0xeb, 0x91,
+ 0xd3, 0x5b, 0xa7, 0x02, 0x3f, 0x5d, 0xd6, 0x80,
+ 0xa2, 0x55, 0xa7, 0x11, 0xcb, 0x2c, 0x4f, 0x93,
+ 0xf7, 0x41, 0x13, 0x29, 0xda, 0x35, 0x1a, 0x28,
+ 0xd2, 0xae, 0x56, 0x49, 0x98, 0x6e, 0x85, 0x06,
+ 0xfa, 0x2c, 0x56, 0xdc, 0x06, 0xff, 0x4d, 0x38,
+ 0xcd, 0x17, 0x8d, 0xf8, 0x53, 0x8d, 0x46, 0x92,
+ 0xb5, 0x2b, 0xd6, 0x11, 0xae, 0x5b, 0xa7, 0x99,
+ 0x7c, 0x8b, 0x75, 0xb7, 0x19, 0x47, 0x23, 0xd1,
+ 0xb8, 0x75, 0xea, 0x69, 0xc7, 0xad, 0x57, 0x49,
+ 0x42, 0xc5, 0x2a, 0x0d, 0x94, 0x54, 0xae, 0x2a,
+ 0x07, 0x62, 0x1d, 0xca, 0xfb, 0x70, 0x28, 0x4f,
+ 0xbd, 0xdc, 0x73, 0xce, 0x64, 0xfc, 0x4d, 0x9d,
+ 0xcb, 0x8d, 0x1c, 0x90, 0x95, 0x46, 0x29, 0xb2,
+ 0x17, 0x2c, 0x39, 0x92, 0xd5, 0x75, 0x0c, 0x4f,
+ 0x6c, 0x2b, 0x6c, 0xb1, 0x59, 0x91, 0xf1, 0x19,
+ 0xa1, 0xdf, 0x20, 0xda, 0xd0, 0xbf, 0x64, 0x72,
+ 0xa4, 0xe1, 0xd1, 0xaf, 0x25, 0x0c, 0x46, 0x2d,
+ 0xc5, 0xcb, 0x3a, 0x16, 0xe3, 0x73, 0x70, 0xa8,
+ 0x62, 0x6d, 0x84, 0x47, 0x91, 0x7f, 0x35, 0x20,
+ 0x42, 0x3c, 0x0c, 0xcb, 0xf1, 0x97, 0x4a, 0x24,
+ 0xb0, 0xa0, 0xa3, 0x79, 0x9a, 0x83, 0x40, 0x81,
+ 0x75, 0x51, 0xdf, 0x2e, 0x8b, 0x6a, 0xe8, 0x59,
+ 0x51, 0x1c, 0x56, 0x49, 0xb4, 0xc5, 0xb8, 0xdc,
+ 0x7f, 0xa2, 0xcc, 0xbe, 0x16, 0xf3, 0xaa, 0xc3,
+ 0xc2, 0x82, 0x53, 0xa6, 0x9b, 0x06, 0x5c, 0x1c,
+ 0x66, 0x84, 0xf5, 0xec, 0x0f, 0x95, 0xc4, 0x61,
+ 0x57, 0xe8, 0x94, 0x98, 0x55, 0x1d, 0xa9, 0x14,
+ 0xc1, 0xd6, 0xb0, 0x9c, 0xab, 0x31, 0x65, 0xb6,
+ 0x63, 0x61, 0x4a, 0x1f, 0x2a, 0xe7, 0xcf, 0xae,
+ 0xd0, 0x29, 0xb1, 0xa5, 0x06, 0x82, 0x2a, 0x42,
+ 0xae, 0xe1, 0x2b, 0x57, 0x23, 0x6b, 0xaf, 0xb4,
+ 0xfb, 0xa9, 0x09, 0x61, 0x6b, 0xdd, 0x8b, 0xfc,
+ 0xa7, 0x6e, 0xf9, 0xcb, 0xc0, 0xeb, 0x99, 0x08,
+ 0x36, 0xed, 0x83, 0x88, 0x1a, 0xcb, 0x0b, 0x01,
+ 0x32, 0xfc, 0xa1, 0x18, 0x46, 0xf6, 0x11, 0x40,
+ 0x25, 0x87, 0x25, 0x22, 0x5b, 0xd6, 0x26, 0x10,
+ 0x59, 0xbc, 0x9e, 0xbc, 0xe7, 0xcb, 0x01, 0xac,
+ 0x47, 0xe2, 0x95, 0xac, 0x63, 0xa4, 0x64, 0x29,
+ 0xc4, 0xb1, 0x1c, 0x39, 0x22, 0x2b, 0x91, 0xd4,
+ 0x24, 0xf1, 0xc2, 0x02, 0x2d, 0x3f, 0xbd, 0x81,
+ 0xe8, 0x4a, 0xd9, 0x5a, 0xf5, 0xbf, 0x5c, 0x47,
+ 0x79, 0xb8, 0x8a, 0x2e, 0x25, 0x4c, 0xff, 0x52,
+ 0x0c, 0x7a, 0x87, 0x68, 0xdd, 0x04, 0xb9, 0x0e,
+ 0x7b, 0x5e, 0x78, 0x53, 0x11, 0xe6, 0xd8, 0x18,
+ 0xad, 0x6d, 0x20, 0x3e, 0x07, 0x29, 0x5e, 0x5b,
+ 0x65, 0x71, 0xe0, 0xbd, 0x57, 0x30, 0xa0, 0xc0,
+ 0x60, 0x8e, 0xdc, 0xd0, 0xe0, 0x34, 0x09, 0xd3,
+ 0x09, 0xc8, 0xa5, 0x2c, 0x30, 0x6a, 0xc3, 0x20,
+ 0xf7, 0xb5, 0x87, 0x5d, 0xa9, 0x0b, 0xa4, 0x99,
+ 0x68, 0x15, 0xa5, 0x54, 0xc5, 0x42, 0x0d, 0xb0,
+ 0x24, 0x8d, 0x41, 0xec, 0x5c, 0x19, 0xcd, 0xd9,
+ 0x01, 0x7f, 0xa2, 0x6b, 0x33, 0x34, 0x57, 0x24,
+ 0xb6, 0xa1, 0x31, 0xdf, 0x75, 0x81, 0x3d, 0x39,
+ 0xd5, 0x13, 0xb8, 0x27, 0x5a, 0x92, 0x99, 0x3d,
+ 0x71, 0x88, 0x90, 0x65, 0xfb, 0x82, 0xac, 0xac,
+ 0xe0, 0xfd, 0x21, 0x90, 0x22, 0x0a, 0x9d, 0xc0,
+ 0xe4, 0xbc, 0xc6, 0x31, 0xe1, 0x69, 0x81, 0x0b,
+ 0xc7, 0xf8, 0x0a, 0xc4, 0x89, 0xfe, 0x06, 0xbc,
+ 0x44, 0x30, 0x9b, 0xc1, 0x42, 0x86, 0xe7, 0x01,
+ 0x2c, 0x02, 0xc1, 0xcc, 0x70, 0xc2, 0xed, 0x2a,
+ 0x45, 0x90, 0x6f, 0x12, 0xc0, 0x7e, 0x8d, 0x43,
+ 0xf6, 0x26, 0x39, 0x13, 0x0e, 0xc1, 0x20, 0x83,
+ 0x2f, 0xcd, 0x61, 0x97, 0x00, 0x1d, 0x8b, 0xf3,
+ 0x30, 0xd8, 0xac, 0x92, 0x34, 0xa7, 0x9b, 0xa7,
+ 0x34, 0xa0, 0xaf, 0xd8, 0xa0, 0x08, 0x71, 0xb3,
+ 0x48, 0x22, 0x8d, 0x9d, 0xef, 0xa1, 0xc9, 0x37,
+ 0x61, 0x03, 0x35, 0x81, 0x23, 0xbc, 0x70, 0x0c,
+ 0xb2, 0x1f, 0x20, 0x4a, 0x34, 0x36, 0xe3, 0xb4,
+ 0xa7, 0x5e, 0x04, 0x7a, 0x12, 0x50, 0xa6, 0x03,
+ 0x92, 0x2f, 0x20, 0xd2, 0xe4, 0xdf, 0x50, 0x3b,
+ 0x98, 0x9a, 0xe5, 0x2f, 0x5a, 0x3a, 0x9c, 0xf5,
+ 0xd3, 0x16, 0x8f, 0xdb, 0x5f, 0x26, 0xac, 0x5b,
+ 0x44, 0xa7, 0xb7, 0x21, 0x0d, 0xb1, 0x56, 0xab,
+ 0xb1, 0x10, 0xf9, 0xe3, 0x91, 0xfe, 0xb5, 0xd9,
+ 0x72, 0x53, 0xc0, 0xd6, 0x19, 0x51, 0x89, 0x40,
+ 0xae, 0x00, 0x55, 0x39, 0x35, 0xd7, 0x22, 0x71,
+ 0xab, 0x83, 0xde, 0xc5, 0xe5, 0xcd, 0xa7, 0xae,
+ 0x51, 0xf5, 0x6b, 0xa4, 0xff, 0xdb, 0xc2, 0xc0,
+ 0x86, 0xb3, 0xb1, 0xd7, 0xc5, 0x5a, 0x1d, 0xba,
+ 0x28, 0x08, 0x33, 0xbc, 0x22, 0xf0, 0xf8, 0x4a,
+ 0x76, 0xbd, 0x64, 0xb1, 0x40, 0x21, 0x2b, 0xaf,
+ 0x06, 0xf0, 0x42, 0x20, 0xc3, 0xfb, 0x0c, 0x4f,
+ 0xcc, 0xbc, 0xf5, 0x45, 0xd7, 0x8b, 0xf3, 0x10,
+ 0xc8, 0xdb, 0xc3, 0xcb, 0x7b, 0xdc, 0x42, 0x0a,
+ 0x9a, 0xd9, 0xb0, 0x3d, 0xc9, 0x0f, 0x09, 0x1a,
+ 0xc1, 0x4f, 0x3d, 0xc0, 0x45, 0xdd, 0xd1, 0x70,
+ 0xa5, 0xc7, 0x19, 0xdd, 0x09, 0xe9, 0x5b, 0x1c,
+ 0xbc, 0xb9, 0xc3, 0xfb, 0xe8, 0x4c, 0xc3, 0x4b,
+ 0xc4, 0xfb, 0x20, 0x58, 0x51, 0x21, 0x41, 0x42,
+ 0xa1, 0x29, 0x59, 0xcf, 0x17, 0xb0, 0xf1, 0x87,
+ 0xab, 0x8b, 0x0e, 0xdf, 0xf7, 0x6c, 0x12, 0xba,
+ 0x34, 0x0a, 0xe3, 0xf3, 0x20, 0xcd, 0x90, 0x27,
+ 0xa4, 0x01, 0x5d, 0x76, 0xf4, 0x8a, 0x87, 0x8d,
+ 0x46, 0x5b, 0x8a, 0x3e, 0xc0, 0xd7, 0x81, 0xa0,
+ 0xbf, 0x7b, 0xf9, 0x8f, 0x57, 0xdf, 0xbe, 0x1c,
+ 0xbf, 0x7e, 0xf5, 0xcf, 0x97, 0x3f, 0x8e, 0x7f,
+ 0x79, 0xf1, 0xe6, 0xd5, 0xcf, 0xf0, 0xb1, 0x66,
+ 0xaa, 0xb5, 0x6d, 0x11, 0x79, 0x36, 0x1f, 0x1b,
+ 0xfb, 0x2d, 0x39, 0xf5, 0x3d, 0xc0, 0x47, 0xfd,
+ 0x8a, 0x67, 0xa0, 0xdd, 0x19, 0xdb, 0xe1, 0x1a,
+ 0x25, 0xdb, 0xbb, 0xd7, 0xcf, 0xef, 0x4b, 0xbf,
+ 0xbe, 0x73, 0x35, 0xf9, 0x3e, 0xf5, 0xdc, 0x4f,
+ 0xa3, 0x9d, 0x7e, 0x5a, 0x8d, 0xf2, 0x13, 0x29,
+ 0x81, 0xb6, 0x02, 0xd8, 0xa4, 0xff, 0x5d, 0x47,
+ 0x91, 0x6b, 0xd4, 0xe3, 0xae, 0xad, 0x8d, 0x35,
+ 0x28, 0x63, 0xdb, 0x2b, 0x56, 0xcd, 0x7a, 0xd5,
+ 0x75, 0x55, 0xa3, 0x2d, 0x34, 0xa3, 0x9b, 0x6b,
+ 0x33, 0x5b, 0x28, 0x33, 0x1f, 0xa5, 0x80, 0x6c,
+ 0xa5, 0x7f, 0x7c, 0x84, 0xb6, 0x50, 0x14, 0xf2,
+ 0x89, 0xe6, 0xe0, 0x58, 0xe5, 0xf3, 0x90, 0x61,
+ 0xaa, 0x83, 0x33, 0x0a, 0xe2, 0x39, 0x21, 0xcd,
+ 0xbf, 0x28, 0xae, 0xae, 0x58, 0x7e, 0xc3, 0x31,
+ 0x22, 0xc1, 0x7e, 0xb0, 0xa1, 0xea, 0x3a, 0x20,
+ 0x3c, 0xc9, 0x6a, 0xdd, 0xa5, 0x77, 0xd1, 0x92,
+ 0xaa, 0x79, 0xe1, 0x6c, 0xb0, 0x1a, 0x6a, 0x8d,
+ 0x09, 0x5a, 0x64, 0xcb, 0x24, 0xc9, 0x17, 0x78,
+ 0x47, 0xdf, 0x1a, 0xe0, 0xbd, 0x74, 0x11, 0x68,
+ 0xa7, 0x88, 0xbc, 0xa3, 0xaa, 0x30, 0x3c, 0xa9,
+ 0xde, 0x22, 0x34, 0x7b, 0x6d, 0xfe, 0x06, 0x9a,
+ 0xc4, 0x60, 0x28, 0xbe, 0xc1, 0x7f, 0xc4, 0xb1,
+ 0xdd, 0x93, 0x16, 0x15, 0x4a, 0xbd, 0xe9, 0x92,
+ 0x81, 0xed, 0x77, 0x54, 0x42, 0x41, 0xee, 0xa3,
+ 0xda, 0x33, 0x54, 0xf9, 0x20, 0x55, 0x99, 0xf3,
+ 0xcd, 0xe8, 0xf7, 0xcc, 0x85, 0x01, 0xfc, 0xae,
+ 0x35, 0x4b, 0x87, 0x80, 0xf7, 0x44, 0x51, 0xf1,
+ 0x34, 0xca, 0xfc, 0x2d, 0x5c, 0x23, 0xdc, 0xf7,
+ 0x9d, 0xf6, 0x95, 0x77, 0xd4, 0x16, 0x96, 0xf5,
+ 0xd2, 0xc4, 0x26, 0x80, 0xed, 0x9e, 0x57, 0x5b,
+ 0x05, 0xb9, 0xac, 0xc6, 0x32, 0x3b, 0xd2, 0x15,
+ 0x8a, 0x36, 0x59, 0x6e, 0xae, 0xca, 0xaa, 0x0e,
+ 0x3c, 0xc5, 0xfb, 0x4d, 0x9d, 0xfb, 0xb8, 0x30,
+ 0xb8, 0xa6, 0xc8, 0x72, 0xc5, 0xb5, 0x90, 0x6a,
+ 0x57, 0x73, 0xb3, 0x53, 0x92, 0x22, 0x8a, 0x05,
+ 0x24, 0xbd, 0x66, 0x7c, 0x87, 0xb5, 0xdd, 0x1d,
+ 0xb8, 0xec, 0xe9, 0x84, 0x9c, 0xb3, 0x5e, 0x2a,
+ 0xa5, 0x56, 0xfc, 0x75, 0xf0, 0x57, 0x34, 0x10,
+ 0xa0, 0x6c, 0xfb, 0x3e, 0x00, 0xed, 0x28, 0x12,
+ 0x53, 0x06, 0xac, 0x6e, 0xdc, 0x50, 0x2e, 0xf6,
+ 0xa6, 0xff, 0x5e, 0x67, 0xb9, 0x5d, 0x89, 0x44,
+ 0xe9, 0x3c, 0x39, 0x79, 0x44, 0x82, 0x38, 0xc8,
+ 0xdc, 0xc1, 0x72, 0x15, 0xa6, 0x21, 0x8c, 0x02,
+ 0x44, 0xe2, 0xc9, 0x22, 0xc9, 0x82, 0x58, 0xb9,
+ 0x5a, 0x2a, 0xf7, 0x4b, 0x74, 0xf6, 0xca, 0xc3,
+ 0x19, 0xe8, 0xc4, 0xe4, 0x09, 0x96, 0x80, 0x00,
+ 0x1d, 0x79, 0xab, 0x15, 0xa2, 0xc8, 0x40, 0x33,
+ 0x04, 0x86, 0x3a, 0x72, 0x7e, 0xb9, 0x42, 0x48,
+ 0x62, 0x11, 0x78, 0x39, 0xaa, 0xe0, 0x13, 0x60,
+ 0x0b, 0x99, 0x68, 0x91, 0x5b, 0x2e, 0x56, 0x9f,
+ 0x44, 0x80, 0x4d, 0x90, 0x82, 0x16, 0x9c, 0x25,
+ 0xeb, 0x14, 0x54, 0xc1, 0x47, 0xec, 0x9f, 0x63,
+ 0x93, 0xc7, 0xff, 0xbc, 0xfc, 0xe5, 0x67, 0x2d,
+ 0x75, 0x93, 0x3b, 0x22, 0xfa, 0x8c, 0x3e, 0xed,
+ 0x0d, 0x78, 0x02, 0x7e, 0xf0, 0xd6, 0x59, 0x16,
+ 0x7a, 0xb1, 0x1a, 0xcf, 0x24, 0x01, 0xdd, 0x39,
+ 0x9c, 0x84, 0xa0, 0x12, 0x1c, 0x8b, 0x21, 0x54,
+ 0xcd, 0x7e, 0x4f, 0xf3, 0xd6, 0x08, 0xb6, 0xcf,
+ 0xeb, 0x57, 0xc6, 0x1d, 0xe5, 0x87, 0x17, 0xbf,
+ 0x9e, 0x9d, 0x8d, 0xbf, 0xfd, 0xf9, 0xe5, 0xf7,
+ 0xc0, 0x96, 0xf6, 0x9f, 0x1f, 0x3d, 0x3f, 0x18,
+ 0x8d, 0x8e, 0x06, 0x07, 0x83, 0xe1, 0xc1, 0xfe,
+ 0xe8, 0xd9, 0x35, 0x4d, 0xcc, 0x72, 0xeb, 0x60,
+ 0x0d, 0xfe, 0xb5, 0xd2, 0xd8, 0xc5, 0x45, 0x1d,
+ 0x6b, 0x3b, 0x55, 0xd8, 0x0e, 0xed, 0x2d, 0x43,
+ 0x7b, 0xbf, 0xb8, 0x33, 0xb6, 0xb3, 0x34, 0xd7,
+ 0x49, 0x28, 0x77, 0x66, 0x77, 0xbe, 0x03, 0x23,
+ 0xdb, 0x3a, 0xa6, 0x9d, 0x34, 0x1d, 0xdf, 0xc8,
+ 0xda, 0x46, 0x0a, 0xea, 0x63, 0xd9, 0xf4, 0x31,
+ 0x10, 0xc5, 0x12, 0xad, 0x3d, 0x31, 0x8c, 0x21,
+ 0x9e, 0x93, 0xf6, 0x99, 0x26, 0x4b, 0xf1, 0xb6,
+ 0x3b, 0xec, 0x88, 0x2e, 0x39, 0x8a, 0x26, 0xe2,
+ 0x2d, 0xfc, 0x3e, 0x7c, 0xd7, 0x13, 0xe2, 0xb7,
+ 0xe0, 0x71, 0x14, 0x89, 0xb5, 0x9c, 0x02, 0xb4,
+ 0xba, 0xe5, 0x58, 0xbe, 0x4a, 0x93, 0xe9, 0x7a,
+ 0xc2, 0x23, 0x03, 0x82, 0xcf, 0xc3, 0x09, 0xfb,
+ 0xc2, 0x79, 0x40, 0x60, 0x6b, 0x54, 0x24, 0xa1,
+ 0x87, 0x05, 0xc0, 0xf5, 0x96, 0xca, 0x06, 0x45,
+ 0xd6, 0x1a, 0x31, 0x03, 0xd2, 0x87, 0xcd, 0xa7,
+ 0x80, 0x6d, 0x82, 0xc7, 0xe8, 0xa9, 0x38, 0x9d,
+ 0x52, 0xad, 0xa4, 0x61, 0xbb, 0x6a, 0x54, 0xbc,
+ 0x28, 0x4b, 0xc8, 0x3f, 0x10, 0x31, 0xf1, 0xb4,
+ 0x96, 0xeb, 0x09, 0xc9, 0x17, 0xe0, 0x78, 0x4b,
+ 0x78, 0x6e, 0x11, 0x18, 0x60, 0x30, 0x5f, 0xa2,
+ 0x3e, 0x9c, 0x2d, 0x3c, 0xb4, 0x21, 0x4e, 0x60,
+ 0x6b, 0x4c, 0x03, 0xd8, 0x64, 0x4b, 0xa4, 0x7b,
+ 0xac, 0xa1, 0xb5, 0xf4, 0x64, 0xa6, 0x60, 0x05,
+ 0xde, 0x64, 0x61, 0x5a, 0xd2, 0xe4, 0x94, 0x46,
+ 0xd0, 0x53, 0x95, 0xff, 0x2b, 0x98, 0xa1, 0x57,
+ 0x23, 0x2c, 0xe4, 0x34, 0x81, 0xae, 0xc9, 0xe4,
+ 0x45, 0xce, 0x8e, 0x68, 0xae, 0x24, 0x3b, 0x02,
+ 0x7a, 0xd9, 0xaf, 0x44, 0xb6, 0x56, 0x1b, 0x11,
+ 0x0d, 0x6e, 0x06, 0x45, 0x05, 0x47, 0x0e, 0x7b,
+ 0x06, 0x9c, 0x26, 0x73, 0x8c, 0x73, 0x00, 0xe7,
+ 0x43, 0x90, 0x26, 0x42, 0x8e, 0xc8, 0xf6, 0xd2,
+ 0xc4, 0x49, 0xee, 0x99, 0x45, 0x46, 0xfb, 0x58,
+ 0x46, 0x08, 0x6c, 0x40, 0xee, 0x20, 0xc5, 0x3f,
+ 0x4e, 0x36, 0xe2, 0x0c, 0xfa, 0x9e, 0x2c, 0xa8,
+ 0x43, 0x33, 0xef, 0xb4, 0xa7, 0xf6, 0x6c, 0x8e,
+ 0x0b, 0x7f, 0x59, 0x7c, 0x60, 0x0f, 0x08, 0x76,
+ 0xd5, 0xea, 0x0e, 0x7a, 0x87, 0xf0, 0xeb, 0x7e,
+ 0x6f, 0xf0, 0x2f, 0xe4, 0x19, 0x67, 0xff, 0x1a,
+ 0xb5, 0xc5, 0xe9, 0x29, 0x31, 0x21, 0x05, 0xea,
+ 0xb7, 0x45, 0x88, 0x96, 0xba, 0x24, 0x42, 0xeb,
+ 0x46, 0x9e, 0x1c, 0xab, 0xef, 0x67, 0x28, 0x2d,
+ 0x21, 0xb3, 0xe9, 0x22, 0x45, 0xee, 0xc1, 0xf9,
+ 0x34, 0x6f, 0x11, 0xf3, 0x02, 0x99, 0xe6, 0xca,
+ 0xee, 0xdb, 0x6d, 0xf4, 0xea, 0xdb, 0x97, 0xbe,
+ 0xd6, 0xbc, 0xe1, 0x1a, 0x00, 0x4a, 0x78, 0x7d,
+ 0x07, 0x5e, 0xdf, 0x81, 0xc7, 0xe0, 0xcc, 0x96,
+ 0x78, 0x8d, 0x14, 0x44, 0xd4, 0x2b, 0x8f, 0x13,
+ 0xd8, 0x0e, 0xe4, 0xfe, 0x83, 0x73, 0x6b, 0x31,
+ 0x8f, 0x73, 0x6b, 0xc7, 0x9d, 0x21, 0xc6, 0x85,
+ 0x8d, 0x68, 0x20, 0x9e, 0xd1, 0x62, 0xfb, 0x97,
+ 0x8a, 0x33, 0x28, 0x83, 0x0c, 0x7a, 0xe7, 0x76,
+ 0xd9, 0xb8, 0xc9, 0xf4, 0x80, 0x47, 0x45, 0x92,
+ 0xda, 0xbb, 0x08, 0x3e, 0xac, 0xbd, 0x48, 0xdb,
+ 0xc6, 0x71, 0xeb, 0x28, 0x5b, 0x5e, 0xb5, 0x08,
+ 0x6e, 0xcc, 0x59, 0xb2, 0xb3, 0x0a, 0x0b, 0xf1,
+ 0xbd, 0x98, 0xda, 0x0f, 0xa4, 0x4f, 0x0f, 0x49,
+ 0x55, 0x65, 0x2b, 0x3b, 0x88, 0xad, 0x12, 0x2b,
+ 0xd7, 0x94, 0x58, 0x2b, 0xd4, 0xd1, 0x11, 0x7f,
+ 0xa5, 0x5c, 0x76, 0x6b, 0x92, 0x55, 0x75, 0x35,
+ 0x4b, 0x08, 0x69, 0x12, 0x36, 0xee, 0xf8, 0xac,
+ 0x6d, 0xd6, 0xe4, 0xad, 0x63, 0x76, 0xcb, 0xc3,
+ 0x52, 0xad, 0xe5, 0xff, 0x75, 0xf9, 0x6b, 0x90,
+ 0xe5, 0xe1, 0xd2, 0xa3, 0x95, 0x20, 0xe3, 0xbf,
+ 0x57, 0x1a, 0x17, 0xba, 0x38, 0xa3, 0x58, 0x74,
+ 0x78, 0x71, 0x68, 0x6d, 0x47, 0xf4, 0xf5, 0x32,
+ 0xec, 0x41, 0xff, 0x77, 0x9a, 0xe4, 0x2d, 0x3d,
+ 0x4f, 0x1d, 0x33, 0x65, 0x6d, 0x5b, 0xb1, 0x3b,
+ 0x07, 0x21, 0xe8, 0x74, 0x6b, 0x26, 0x34, 0xad,
+ 0xd1, 0x73, 0x88, 0xe6, 0x00, 0x14, 0xf9, 0x6d,
+ 0x99, 0xff, 0xb4, 0xef, 0xd1, 0xe5, 0x94, 0xfc,
+ 0xe8, 0x4f, 0x6a, 0x24, 0xd5, 0xb2, 0x13, 0xdd,
+ 0x4d, 0x15, 0x1c, 0x9a, 0x23, 0xea, 0xab, 0xc2,
+ 0x3d, 0xb3, 0x77, 0x01, 0xcd, 0x3c, 0xfe, 0xcd,
+ 0xf2, 0x97, 0xec, 0x5d, 0x4a, 0x31, 0xb1, 0x2b,
+ 0x0b, 0x2f, 0x1d, 0x37, 0xc6, 0x0a, 0x5f, 0xc0,
+ 0xaa, 0x22, 0xd6, 0x05, 0xe1, 0x18, 0x5f, 0x35,
+ 0x08, 0xf1, 0x5b, 0x0e, 0x54, 0x3a, 0xa2, 0x57,
+ 0x3b, 0xbd, 0x51, 0xb3, 0x76, 0x2f, 0x2d, 0xfa,
+ 0xc8, 0x15, 0x6a, 0x1b, 0x7c, 0x3a, 0x2c, 0x00,
+ 0x81, 0x0c, 0x89, 0x8c, 0x46, 0x92, 0x57, 0x61,
+ 0x65, 0x6f, 0xc7, 0x1b, 0x79, 0xb0, 0x95, 0x4a,
+ 0x5b, 0xfa, 0x0a, 0x42, 0xc5, 0x22, 0x49, 0x6b,
+ 0x0a, 0x35, 0x23, 0x29, 0x03, 0x8b, 0xbc, 0x49,
+ 0x30, 0x3d, 0xb9, 0x52, 0xd3, 0x6a, 0x76, 0xa1,
+ 0xdb, 0xc6, 0x79, 0x4e, 0x2d, 0x9b, 0xdc, 0x93,
+ 0xba, 0xe7, 0xe2, 0xf7, 0x38, 0xc9, 0x7f, 0xcd,
+ 0x08, 0xa5, 0x4a, 0xff, 0x4f, 0xeb, 0xc6, 0xed,
+ 0x35, 0x49, 0x48, 0x55, 0x44, 0x6c, 0x26, 0xc3,
+ 0xb9, 0x9c, 0xb2, 0x59, 0x97, 0x41, 0x55, 0x56,
+ 0xd6, 0x92, 0xd9, 0x69, 0xa1, 0x07, 0x75, 0x17,
+ 0xe3, 0xb4, 0x4e, 0xa2, 0x88, 0x7c, 0xfc, 0xc7,
+ 0xab, 0x20, 0xc5, 0xb7, 0x2a, 0x28, 0x3d, 0x8d,
+ 0xf9, 0xbe, 0x04, 0x08, 0x21, 0x02, 0x8a, 0x69,
+ 0x59, 0xb6, 0x97, 0x43, 0x38, 0x99, 0x98, 0x79,
+ 0xb5, 0x1a, 0x26, 0x09, 0x78, 0x78, 0x2d, 0x56,
+ 0x6d, 0xd7, 0x94, 0x43, 0x32, 0x45, 0x1a, 0x9c,
+ 0x03, 0x80, 0x8c, 0x74, 0x40, 0x64, 0x99, 0x53,
+ 0x90, 0x04, 0xbd, 0xb4, 0x3b, 0x0b, 0x83, 0x68,
+ 0x2a, 0xfc, 0xe4, 0x82, 0xa5, 0x6e, 0xba, 0xdb,
+ 0x0c, 0xa6, 0x7d, 0xac, 0x85, 0xc2, 0x01, 0xca,
+ 0x8a, 0x61, 0x14, 0x64, 0x1a, 0xde, 0x81, 0x11,
+ 0xde, 0xb7, 0xb3, 0x7e, 0x18, 0xce, 0x57, 0x7d,
+ 0xfb, 0xe5, 0x59, 0x02, 0xc3, 0x15, 0xb7, 0x5c,
+ 0xf0, 0x77, 0xc3, 0x54, 0x1a, 0xbe, 0x43, 0xb4,
+ 0xc2, 0x8c, 0x87, 0x7e, 0x35, 0xbc, 0x47, 0x92,
+ 0x8b, 0x5d, 0xc6, 0xac, 0xe7, 0xa3, 0x09, 0xce,
+ 0x36, 0x0d, 0x46, 0xab, 0x05, 0xde, 0x1d, 0xc1,
+ 0x1a, 0x1a, 0x49, 0xe7, 0x17, 0xea, 0x55, 0xa3,
+ 0xdf, 0x01, 0x02, 0x81, 0x21, 0x47, 0x9e, 0x1f,
+ 0x44, 0x4d, 0x7c, 0x5f, 0x4e, 0xa0, 0x9e, 0x45,
+ 0x98, 0x02, 0x02, 0x6f, 0x00, 0xff, 0x17, 0x3f,
+ 0x42, 0x8d, 0x13, 0x1b, 0x38, 0xc1, 0xc5, 0x6b,
+ 0xb9, 0x6c, 0x91, 0x6c, 0x00, 0x7d, 0xed, 0x50,
+ 0xa0, 0x67, 0xe7, 0x3f, 0x59, 0x06, 0x72, 0xae,
+ 0x5e, 0xab, 0xb8, 0x8b, 0xe9, 0x9b, 0x99, 0x99,
+ 0x41, 0xc0, 0xba, 0x67, 0x64, 0xc8, 0x6a, 0x72,
+ 0x4b, 0xa0, 0x95, 0x96, 0x07, 0x54, 0x06, 0x78,
+ 0xe6, 0xa8, 0xb1, 0xc1, 0x61, 0x31, 0x03, 0xa5,
+ 0x07, 0x85, 0xbb, 0x64, 0x9d, 0x57, 0x23, 0xb1,
+ 0x77, 0x2a, 0x7a, 0x43, 0xd5, 0xcf, 0x1f, 0x7f,
+ 0x5e, 0xd6, 0x56, 0x2c, 0x50, 0x2a, 0x7d, 0xad,
+ 0x00, 0x58, 0xfd, 0x5d, 0xcb, 0xde, 0x3b, 0x4e,
+ 0xf9, 0x11, 0x9c, 0x92, 0x2f, 0xb6, 0xef, 0x9c,
+ 0x57, 0x96, 0x66, 0x66, 0xc5, 0x86, 0x88, 0xb1,
+ 0x54, 0xd0, 0x50, 0x7c, 0x1a, 0x9d, 0xb0, 0xb2,
+ 0x38, 0x75, 0x2d, 0x1d, 0x59, 0x84, 0xa2, 0x2b,
+ 0x2b, 0xe7, 0x4b, 0xef, 0x7d, 0x20, 0x52, 0x7c,
+ 0x82, 0x89, 0x36, 0x3e, 0x34, 0xf8, 0x77, 0xc9,
+ 0xe2, 0x2f, 0xf4, 0xb5, 0xd6, 0x75, 0x19, 0x72,
+ 0x01, 0x8f, 0x7b, 0xe2, 0xd0, 0x5c, 0xa6, 0xcd,
+ 0x5a, 0x9e, 0x9f, 0xb5, 0x34, 0x9a, 0xbd, 0xcb,
+ 0x36, 0x4d, 0xc4, 0x6f, 0x68, 0xe5, 0x88, 0x1f,
+ 0xe7, 0xd2, 0x3f, 0xc7, 0x78, 0x21, 0x64, 0x64,
+ 0x76, 0xf1, 0x13, 0x50, 0x20, 0xb4, 0x16, 0x5d,
+ 0x69, 0xf5, 0x42, 0xdb, 0x50, 0xf0, 0x3b, 0x68,
+ 0xbb, 0xb8, 0xba, 0x20, 0xfa, 0x41, 0x65, 0x9c,
+ 0x06, 0x69, 0xfb, 0x91, 0x8a, 0x77, 0x49, 0xf3,
+ 0xb6, 0xe7, 0xcb, 0x9d, 0x9d, 0x13, 0xb7, 0xae,
+ 0x9c, 0xc3, 0xd3, 0xeb, 0xb9, 0x93, 0x5c, 0x35,
+ 0xa5, 0x96, 0xdc, 0xac, 0x85, 0x5f, 0x24, 0x5c,
+ 0x72, 0x83, 0x51, 0x78, 0xdc, 0x1e, 0xd3, 0xb9,
+ 0x35, 0x9e, 0xf3, 0x11, 0x67, 0xa5, 0x23, 0x81,
+ 0xdf, 0xff, 0x49, 0x39, 0xf9, 0xa4, 0x47, 0xe4,
+ 0x44, 0x9f, 0x8d, 0x23, 0xa7, 0x03, 0xf7, 0xb2,
+ 0x93, 0x97, 0xbf, 0x78, 0xe5, 0x59, 0x58, 0x97,
+ 0xf6, 0x36, 0xd7, 0xa4, 0x46, 0x4b, 0x26, 0x95,
+ 0xb7, 0x0c, 0xde, 0x06, 0x52, 0xb8, 0x1e, 0x1e,
+ 0x1e, 0x92, 0xde, 0x5d, 0x89, 0x54, 0xbf, 0x92,
+ 0x50, 0x0d, 0x28, 0xbd, 0xd9, 0xf5, 0xbe, 0xaf,
+ 0xeb, 0xde, 0x56, 0xfc, 0xe5, 0xa6, 0xc1, 0x7d,
+ 0x44, 0xc6, 0x48, 0xe6, 0x15, 0x35, 0x57, 0x98,
+ 0xce, 0xf8, 0x6b, 0xee, 0x65, 0xbb, 0xae, 0xaf,
+ 0x2e, 0xad, 0x74, 0xb7, 0xd8, 0xcd, 0x16, 0x97,
+ 0x9d, 0xf2, 0x02, 0xfe, 0x8f, 0x4f, 0xf7, 0x92,
+ 0xb6, 0xca, 0xaf, 0x68, 0xeb, 0x67, 0xb3, 0x37,
+ 0xc1, 0xfc, 0x73, 0x7c, 0xe9, 0xf4, 0xd0, 0x1e,
+ 0xea, 0x54, 0x9b, 0xdc, 0x1e, 0xe0, 0xeb, 0x89,
+ 0x7b, 0x7f, 0x3a, 0x70, 0x93, 0xad, 0xf0, 0xa9,
+ 0xfc, 0xf3, 0x6e, 0xdd, 0xaf, 0xed, 0xbe, 0x7d,
+ 0xaa, 0x6e, 0xe2, 0xc0, 0xd4, 0x64, 0xf4, 0xba,
+ 0xcd, 0xc7, 0xa0, 0xd7, 0xe3, 0x4a, 0xd5, 0x46,
+ 0xd2, 0x6a, 0x33, 0x61, 0xdd, 0x6a, 0xae, 0xf3,
+ 0x28, 0x8c, 0x1b, 0xdf, 0xc9, 0x39, 0x55, 0x1a,
+ 0x18, 0x9a, 0x53, 0xaf, 0x92, 0xb1, 0x15, 0x6a,
+ 0x34, 0x90, 0x62, 0xa9, 0xe6, 0x97, 0xc9, 0xe8,
+ 0xdc, 0xd9, 0x27, 0x76, 0x63, 0x7f, 0xa9, 0x64,
+ 0x7c, 0x4e, 0x8d, 0x4e, 0x79, 0x7d, 0xea, 0x18,
+ 0x61, 0x09, 0x72, 0xdd, 0x24, 0x7f, 0xd6, 0x8c,
+ 0x51, 0x9b, 0xe5, 0xa1, 0x66, 0xab, 0xa0, 0x0f,
+ 0xf6, 0x0b, 0xfa, 0xdd, 0x13, 0x96, 0xad, 0xfb,
+ 0x82, 0xef, 0x39, 0xf5, 0x06, 0xaa, 0x67, 0xae,
+ 0xee, 0x7a, 0x7d, 0x02, 0x0a, 0xbf, 0x3d, 0x12,
+ 0xdd, 0xee, 0x2a, 0xa1, 0x86, 0x83, 0x96, 0xc8,
+ 0xf6, 0x63, 0xe8, 0xec, 0x16, 0x39, 0xb4, 0x11,
+ 0x9c, 0x6d, 0x99, 0x1f, 0xa9, 0xa1, 0x6b, 0xd8,
+ 0x6f, 0x92, 0x82, 0x8a, 0x7e, 0xe9, 0xc8, 0xcb,
+ 0x4a, 0x73, 0xe3, 0x6b, 0x9c, 0xa2, 0x27, 0x23,
+ 0x29, 0x43, 0x08, 0xb4, 0xfa, 0xf2, 0xc3, 0x1d,
+ 0xf0, 0x9e, 0x68, 0x31, 0x34, 0x7d, 0x30, 0x7c,
+ 0x82, 0x7b, 0xb2, 0x5d, 0xc0, 0x96, 0xa6, 0xf0,
+ 0x1a, 0xd7, 0x3a, 0x1f, 0x3f, 0xdb, 0xa3, 0xe5,
+ 0xc1, 0xb3, 0xea, 0x5d, 0xe0, 0x1b, 0x0b, 0x8b,
+ 0xdb, 0x3a, 0xb8, 0x1e, 0x7c, 0xf4, 0x9c, 0x5b,
+ 0x0b, 0x92, 0x73, 0x93, 0x5d, 0x7c, 0xef, 0x3a,
+ 0xcb, 0x8d, 0x4f, 0xb2, 0x5d, 0xbc, 0x9f, 0xbb,
+ 0x8d, 0xf7, 0x83, 0x9e, 0xc2, 0x61, 0x3c, 0xb5,
+ 0xde, 0x0e, 0x26, 0xea, 0x20, 0xe7, 0xeb, 0x05,
+ 0x3a, 0xc3, 0x4d, 0x74, 0x4e, 0xf4, 0x10, 0xbb,
+ 0x27, 0x11, 0xe3, 0xfa, 0x01, 0x89, 0x0a, 0x02,
+ 0xc7, 0x2e, 0x14, 0xdc, 0x27, 0x0b, 0x05, 0xb7,
+ 0x93, 0x22, 0x76, 0x52, 0xc4, 0x2e, 0x7c, 0xde,
+ 0xfd, 0x08, 0x00, 0xbb, 0xc3, 0x7e, 0x77, 0xd8,
+ 0xdf, 0x7e, 0x70, 0xbf, 0xfb, 0x3d, 0x43, 0xf7,
+ 0xe1, 0x33, 0xb9, 0x38, 0x14, 0x62, 0xc2, 0x2a,
+ 0xf6, 0xaf, 0xcb, 0xe9, 0x2c, 0xaa, 0xa4, 0x57,
+ 0x2a, 0xbe, 0xfa, 0x39, 0x97, 0xf3, 0x15, 0xcd,
+ 0xb5, 0x31, 0x40, 0xf2, 0xa2, 0x71, 0x50, 0xb0,
+ 0x18, 0x1f, 0xc0, 0x06, 0x53, 0x17, 0x6a, 0x75,
+ 0xef, 0xe6, 0xbd, 0xea, 0xbd, 0xe3, 0x51, 0x49,
+ 0x43, 0x5c, 0x3a, 0x28, 0xad, 0x8e, 0x4b, 0x47,
+ 0x05, 0x4d, 0x0f, 0xee, 0x65, 0x85, 0x46, 0x1b,
+ 0xd9, 0xa2, 0xe1, 0x2d, 0xe1, 0xa2, 0xe2, 0x2d,
+ 0xa1, 0x8d, 0xda, 0xa2, 0xf0, 0x94, 0xd0, 0x6a,
+ 0xbc, 0xa8, 0xf4, 0x77, 0x77, 0xd0, 0x5b, 0x14,
+ 0x3d, 0xc0, 0x1f, 0xf6, 0x6d, 0xe1, 0xd6, 0xa7,
+ 0x3f, 0x2d, 0x34, 0x05, 0xef, 0x82, 0x5f, 0xaa,
+ 0x83, 0x77, 0x41, 0x41, 0x47, 0x2f, 0x7c, 0x6d,
+ 0xf0, 0x2e, 0xd9, 0xbc, 0xb0, 0x8e, 0x0d, 0x3d,
+ 0x2f, 0x2c, 0xaf, 0xfb, 0xfa, 0xc7, 0x6d, 0x0b,
+ 0xfd, 0xb8, 0x6d, 0x51, 0xf5, 0xb8, 0xad, 0xb4,
+ 0x88, 0x84, 0xc3, 0x62, 0xfb, 0xb7, 0x6d, 0xf7,
+ 0x72, 0x0f, 0xa9, 0xd8, 0xd9, 0xbe, 0xe0, 0x1d,
+ 0x49, 0x5e, 0x38, 0x7a, 0x73, 0x82, 0x1a, 0xf1,
+ 0x41, 0x72, 0x31, 0x39, 0x8b, 0xf8, 0x30, 0x9b,
+ 0x74, 0x06, 0xfc, 0x5b, 0x39, 0xad, 0xa9, 0xe1,
+ 0xe9, 0x42, 0xfe, 0xe2, 0xbe, 0xae, 0x56, 0x31,
+ 0xc6, 0x19, 0x38, 0x46, 0x00, 0x19, 0x5d, 0xd3,
+ 0xa9, 0x2b, 0x27, 0x67, 0x8f, 0x81, 0xf8, 0x46,
+ 0xf5, 0x78, 0x2c, 0x98, 0x02, 0x86, 0x6d, 0xdb,
+ 0xe3, 0x05, 0xf5, 0xa5, 0x73, 0xd8, 0x60, 0xf8,
+ 0xda, 0x92, 0x94, 0xab, 0x16, 0x86, 0xed, 0x9f,
+ 0x7a, 0xe9, 0xfb, 0xbe, 0x9f, 0x52, 0xbb, 0x90,
+ 0xdf, 0x04, 0x65, 0xeb, 0x74, 0xe6, 0x41, 0x39,
+ 0x4d, 0xc9, 0x37, 0xed, 0xe2, 0x4b, 0xf0, 0x73,
+ 0x99, 0x94, 0xc4, 0xa4, 0xbe, 0x18, 0xf4, 0x46,
+ 0xc3, 0x91, 0x9b, 0xc5, 0x62, 0xd0, 0x7b, 0x36,
+ 0x3c, 0x1c, 0xe9, 0x4f, 0x3e, 0x7d, 0x1a, 0x3c,
+ 0x1b, 0x8d, 0xb4, 0x6c, 0x58, 0xe3, 0xe3, 0x52,
+ 0xf4, 0x50, 0xc3, 0x40, 0xff, 0xd3, 0xa9, 0x74,
+ 0x39, 0x13, 0xde, 0xd2, 0xc7, 0x07, 0x26, 0x42,
+ 0xb2, 0xd7, 0x39, 0xba, 0x5d, 0xc5, 0x89, 0xf1,
+ 0xb3, 0xe2, 0xd4, 0x03, 0x79, 0x92, 0xd3, 0x8b,
+ 0x55, 0x3f, 0x02, 0xb2, 0x30, 0x07, 0x93, 0x6c,
+ 0x1c, 0xc9, 0x55, 0x51, 0x1d, 0xef, 0x53, 0xa7,
+ 0xfa, 0xbf, 0xe6, 0xa0, 0x64, 0x0c, 0xd1, 0x5f,
+ 0xcd, 0x6a, 0x68, 0xd0, 0xfa, 0x56, 0x85, 0xc4,
+ 0x87, 0x8a, 0x59, 0x0b, 0x26, 0x2e, 0xf7, 0xda,
+ 0x1d, 0xb1, 0xa1, 0x0c, 0x04, 0xf4, 0x97, 0x9a,
+ 0x4f, 0x8f, 0xd2, 0xd3, 0xa8, 0x04, 0x04, 0x6a,
+ 0x76, 0x25, 0x5d, 0x79, 0xa4, 0xee, 0xce, 0x66,
+ 0x6b, 0x20, 0x23, 0xc6, 0x2c, 0xf5, 0x2e, 0x1d,
+ 0x9d, 0x36, 0x45, 0x6f, 0xac, 0x24, 0x26, 0x1a,
+ 0x64, 0xff, 0x44, 0x7c, 0x65, 0x22, 0x9b, 0xe3,
+ 0xeb, 0xd7, 0xfd, 0xa3, 0x03, 0x9c, 0x34, 0x73,
+ 0x26, 0xb5, 0x6b, 0xa6, 0x91, 0x9e, 0xfb, 0xda,
+ 0x00, 0xe5, 0x43, 0x3c, 0x3b, 0xf6, 0x0e, 0x3e,
+ 0x8a, 0x0c, 0xac, 0xcc, 0x3b, 0x2a, 0x9d, 0x01,
+ 0xc1, 0xee, 0xe3, 0x3b, 0x42, 0x7a, 0x2e, 0x96,
+ 0x89, 0xd8, 0x4b, 0x53, 0x94, 0x8e, 0xf5, 0xa3,
+ 0x3a, 0x7c, 0x3e, 0xc3, 0x99, 0x05, 0x78, 0x1c,
+ 0xfa, 0xf4, 0xd3, 0x8f, 0x14, 0x61, 0xa8, 0x5c,
+ 0x0b, 0xcb, 0x83, 0x54, 0x92, 0x1d, 0x34, 0x70,
+ 0x28, 0x8e, 0xbd, 0x1b, 0xdd, 0x71, 0xa3, 0x70,
+ 0xd0, 0x62, 0x25, 0xbd, 0x78, 0xb6, 0xb6, 0x29,
+ 0x51, 0x85, 0x2a, 0xb5, 0x28, 0xf4, 0x49, 0x55,
+ 0x55, 0x9c, 0x92, 0x8e, 0x0d, 0xbc, 0x40, 0x67,
+ 0x73, 0xf4, 0xdb, 0x41, 0x0a, 0xf3, 0xa2, 0x04,
+ 0xc6, 0xf9, 0x41, 0x78, 0x17, 0x21, 0xa7, 0x39,
+ 0x40, 0x07, 0x31, 0x89, 0x67, 0xa6, 0xfd, 0xad,
+ 0xe4, 0xa6, 0xbd, 0x14, 0x5f, 0xa1, 0x83, 0xd9,
+ 0xc0, 0xf6, 0xb7, 0xb2, 0x07, 0xb0, 0xa7, 0x56,
+ 0xae, 0x95, 0x03, 0x5a, 0xc4, 0x22, 0xe8, 0xb5,
+ 0xd7, 0xa6, 0xb5, 0x50, 0x6f, 0xf7, 0x86, 0x87,
+ 0x03, 0xe5, 0xdd, 0xd5, 0xa1, 0xe1, 0xc2, 0x0e,
+ 0xc2, 0x3f, 0x9f, 0x1f, 0x75, 0x44, 0xed, 0xc0,
+ 0x0d, 0xad, 0x9a, 0x70, 0x4c, 0x2f, 0x32, 0x4c,
+ 0x69, 0x84, 0x76, 0x14, 0x2f, 0x92, 0x24, 0xac,
+ 0x63, 0x8b, 0xa9, 0x79, 0x7e, 0xe2, 0x6e, 0x24,
+ 0x21, 0xd9, 0xa5, 0x4b, 0x87, 0xd6, 0x00, 0x38,
+ 0x2b, 0x92, 0x55, 0xb7, 0x62, 0xd1, 0xfd, 0x64,
+ 0x8d, 0xd9, 0x40, 0xf8, 0x51, 0x39, 0x3f, 0x00,
+ 0x5d, 0xac, 0x89, 0x92, 0x22, 0x7d, 0x6a, 0x40,
+ 0x0b, 0xf5, 0xf6, 0xd3, 0xa2, 0x24, 0x1a, 0xd2,
+ 0xd4, 0x04, 0x5f, 0xc3, 0x0c, 0x3d, 0x51, 0x80,
+ 0xaf, 0x4f, 0xe1, 0x5c, 0x15, 0xad, 0x64, 0x45,
+ 0xaf, 0x01, 0x61, 0xca, 0x78, 0x34, 0xd2, 0x59,
+ 0xb2, 0x88, 0x8d, 0xe4, 0x28, 0x3d, 0xda, 0xb1,
+ 0x3c, 0xdb, 0x86, 0x43, 0x39, 0x8b, 0xe1, 0x48,
+ 0x77, 0xbd, 0x54, 0x4d, 0x37, 0xcd, 0xfe, 0x7e,
+ 0x61, 0xb6, 0x65, 0x1d, 0x67, 0xae, 0x55, 0x4f,
+ 0xf3, 0x62, 0x4f, 0xf3, 0xe6, 0x9e, 0xe6, 0x5b,
+ 0xf4, 0x34, 0xaf, 0xec, 0xc9, 0x2f, 0xf6, 0xe4,
+ 0x37, 0xf7, 0xe4, 0x6f, 0xd1, 0x93, 0xaf, 0x7b,
+ 0xc2, 0xb8, 0x11, 0xd5, 0xa2, 0x66, 0x83, 0x00,
+ 0x72, 0xd7, 0x02, 0xe3, 0x2d, 0xc9, 0x7c, 0x77,
+ 0xee, 0x8e, 0xb3, 0xad, 0x1a, 0xaa, 0xa5, 0xb6,
+ 0xed, 0x25, 0xb0, 0x46, 0x01, 0xec, 0x7a, 0x62,
+ 0xd4, 0xc7, 0xfa, 0xed, 0x54, 0x2a, 0x57, 0x36,
+ 0x99, 0xec, 0xec, 0x9a, 0xd7, 0xb3, 0x6b, 0x16,
+ 0x6b, 0x49, 0x51, 0x59, 0x7b, 0x53, 0x3f, 0x68,
+ 0x6d, 0xf4, 0x3a, 0xb7, 0x40, 0xc8, 0x4e, 0x94,
+ 0xb4, 0x56, 0xf6, 0xf9, 0xb6, 0x78, 0xd8, 0x4e,
+ 0xb3, 0xbd, 0x39, 0x97, 0xdb, 0xe9, 0x8e, 0xa5,
+ 0xa7, 0xde, 0x57, 0xe8, 0x6e, 0x96, 0x57, 0xfa,
+ 0x74, 0x1e, 0x58, 0x2f, 0x88, 0xec, 0x9a, 0x9b,
+ 0xbb, 0xd6, 0xf1, 0x4c, 0x8d, 0x0f, 0x68, 0x2f,
+ 0xab, 0xd6, 0xe3, 0xae, 0xa3, 0x0a, 0x7e, 0xb0,
+ 0xcd, 0xef, 0xc6, 0x2c, 0xa9, 0xfa, 0xc5, 0xe8,
+ 0x15, 0x28, 0x0a, 0xfc, 0xc7, 0x7f, 0x08, 0x2d,
+ 0xb9, 0x9e, 0x92, 0xe4, 0x6a, 0x7d, 0xfa, 0x40,
+ 0xb5, 0x58, 0xab, 0xd0, 0xd2, 0xec, 0x37, 0x32,
+ 0x7e, 0x02, 0xc6, 0x07, 0xd1, 0x8f, 0x5a, 0xf2,
+ 0xc4, 0x44, 0xc9, 0x3d, 0xe6, 0x07, 0xc9, 0xf6,
+ 0x6c, 0x02, 0x3a, 0x24, 0x98, 0x38, 0xbc, 0x8d,
+ 0x5f, 0xd2, 0x18, 0x18, 0x28, 0x57, 0x7f, 0xea,
+ 0xeb, 0x82, 0x87, 0x70, 0x59, 0xe0, 0x38, 0x1c,
+ 0x68, 0xf5, 0xb6, 0x49, 0x3d, 0xbe, 0xa6, 0x8e,
+ 0xb8, 0xdf, 0xa4, 0x23, 0xde, 0x48, 0xe3, 0xe2,
+ 0xd7, 0x71, 0xd7, 0x51, 0xb2, 0x1e, 0xa2, 0xca,
+ 0x64, 0x66, 0xbb, 0x97, 0xce, 0x2d, 0x41, 0xbb,
+ 0x5e, 0xbc, 0xe6, 0xce, 0x28, 0x6e, 0xeb, 0x80,
+ 0x46, 0x2a, 0x7f, 0xdd, 0x6f, 0x57, 0x09, 0xda,
+ 0xaa, 0x7c, 0xa8, 0xf2, 0x97, 0xfe, 0x39, 0xbd,
+ 0x41, 0x5c, 0x39, 0xe0, 0x4b, 0x50, 0x2d, 0x1e,
+ 0xb6, 0xe4, 0xbf, 0xbb, 0xc2, 0xba, 0x87, 0x2b,
+ 0x2c, 0x99, 0xca, 0xf5, 0x42, 0x66, 0x54, 0x6d,
+ 0xbc, 0xc5, 0xaa, 0xbd, 0xf5, 0x52, 0x8d, 0xf7,
+ 0xdc, 0x1d, 0xb2, 0x0b, 0xe2, 0xf2, 0x11, 0x41,
+ 0x5c, 0x6e, 0x1a, 0xa4, 0xa5, 0x30, 0xad, 0xb5,
+ 0x91, 0x5a, 0x6e, 0x3d, 0xaa, 0x4a, 0xdd, 0x0b,
+ 0xb7, 0x2d, 0x43, 0x12, 0x48, 0x44, 0x6b, 0x9d,
+ 0x63, 0x3e, 0xfa, 0x95, 0x9f, 0xe3, 0x08, 0xe9,
+ 0xf4, 0x07, 0x3b, 0xea, 0x68, 0xf8, 0x7c, 0x64,
+ 0x5c, 0x1f, 0xf1, 0xc1, 0xfc, 0xe8, 0xb0, 0x29,
+ 0x0f, 0x69, 0x21, 0x09, 0x3d, 0x33, 0xac, 0x86,
+ 0x55, 0xad, 0x1a, 0x4f, 0x81, 0x8a, 0xa7, 0xe1,
+ 0x12, 0x8f, 0xf8, 0x24, 0x2e, 0xd3, 0x00, 0x3e,
+ 0x9c, 0xaf, 0x38, 0xe8, 0xbc, 0x0b, 0x2e, 0x90,
+ 0x69, 0xa8, 0x41, 0xde, 0x7b, 0x19, 0x05, 0xe7,
+ 0xe4, 0x53, 0xd6, 0x92, 0x89, 0x2f, 0x28, 0x27,
+ 0xae, 0x64, 0xd8, 0xa1, 0x97, 0xa9, 0x79, 0x43,
+ 0xdb, 0x7f, 0x82, 0x91, 0xe2, 0x73, 0x95, 0x89,
+ 0x5b, 0x04, 0xaa, 0x29, 0x9b, 0xcd, 0xe9, 0x61,
+ 0x3c, 0xc6, 0xd9, 0xcb, 0x0c, 0x9b, 0x90, 0xe1,
+ 0xde, 0x2b, 0x48, 0x8a, 0x19, 0x26, 0xa7, 0xfe,
+ 0xc6, 0x20, 0x6d, 0x76, 0x06, 0x58, 0x0a, 0x0b,
+ 0x9c, 0xc2, 0x9c, 0xd2, 0x2f, 0x73, 0x2b, 0x93,
+ 0x2c, 0x7d, 0xf0, 0xf5, 0x07, 0xf9, 0x2f, 0x2e,
+ 0xc2, 0x01, 0x02, 0xf9, 0xa3, 0x36, 0x5f, 0x61,
+ 0xb0, 0xca, 0xc2, 0x88, 0x96, 0x9c, 0xc3, 0x68,
+ 0x3a, 0x93, 0xa7, 0x06, 0xf8, 0xfb, 0x1a, 0x13,
+ 0xfc, 0x4e, 0x65, 0xf6, 0x64, 0x1d, 0xd6, 0xee,
+ 0x49, 0xd7, 0xfc, 0xef, 0x89, 0xfa, 0xf8, 0xff,
+ 0xe0, 0x1f, 0xfd, 0x63, 0x3e, 0x7a, 0xf0, 0xe3,
+ 0xc3, 0xcf, 0xc4, 0xfe, 0x58, 0x51, 0xf3, 0x3a,
+ 0x30, 0xa7, 0xf0, 0x13, 0xc0, 0xcf, 0xec, 0x16,
+ 0x61, 0xce, 0xe1, 0x67, 0x01, 0x3f, 0xe1, 0xb5,
+ 0x60, 0xda, 0x4e, 0x84, 0xac, 0x2e, 0x58, 0xe4,
+ 0x33, 0xe6, 0x0c, 0xbd, 0xa4, 0x11, 0x75, 0xe5,
+ 0x7c, 0xa3, 0xd6, 0xa7, 0x7f, 0xbf, 0x64, 0xf1,
+ 0xdb, 0x91, 0xe2, 0xfd, 0x46, 0x30, 0x83, 0x2b,
+ 0x5a, 0x4f, 0x1a, 0x5b, 0x6f, 0x8b, 0xc3, 0x74,
+ 0xeb, 0xa1, 0x0c, 0x2a, 0x5a, 0x07, 0x95, 0xad,
+ 0xcb, 0xf5, 0x66, 0xdb, 0xe2, 0x5a, 0xd5, 0xc9,
+ 0x7c, 0x6b, 0x14, 0x9b, 0x06, 0xba, 0xb8, 0x6a,
+ 0xb2, 0x9b, 0x1a, 0x87, 0xdb, 0xe2, 0x5f, 0x06,
+ 0xa2, 0x88, 0x89, 0x6e, 0x09, 0x31, 0x6a, 0x66,
+ 0x78, 0x1e, 0xca, 0x10, 0xa9, 0x17, 0x74, 0xc9,
+ 0x72, 0x29, 0xb2, 0x28, 0x59, 0x05, 0x14, 0xa9,
+ 0xf0, 0x08, 0x35, 0x1e, 0xdc, 0x80, 0x14, 0x81,
+ 0x4e, 0xdf, 0xb9, 0x50, 0x5b, 0xf3, 0x1d, 0xf8,
+ 0xf1, 0x7b, 0x4f, 0xb2, 0x9b, 0x3e, 0x7d, 0x6e,
+ 0x8b, 0xd0, 0x6c, 0x59, 0x8c, 0x50, 0xb1, 0x5e,
+ 0xce, 0xa0, 0x0d, 0x87, 0xf9, 0xb4, 0x32, 0xa0,
+ 0xf7, 0x45, 0x4b, 0xe6, 0x94, 0xc6, 0x04, 0xe2,
+ 0xa8, 0x97, 0x42, 0x87, 0x32, 0xbe, 0x2f, 0x56,
+ 0xc4, 0x50, 0x23, 0x6d, 0xd3, 0x2d, 0x46, 0xba,
+ 0xc4, 0x98, 0xc0, 0xbf, 0xaf, 0x43, 0xe0, 0x72,
+ 0x01, 0xc5, 0xd8, 0x3c, 0x26, 0x24, 0x0f, 0x06,
+ 0x83, 0x67, 0x87, 0x83, 0xe1, 0xd3, 0xde, 0xd3,
+ 0xa3, 0xc3, 0xc3, 0x67, 0x47, 0x87, 0x08, 0xf9,
+ 0x70, 0x38, 0x92, 0x0a, 0x1b, 0x89, 0x40, 0xc8,
+ 0x6c, 0xdb, 0x05, 0x60, 0x18, 0x8e, 0xd4, 0xc7,
+ 0x14, 0x39, 0x18, 0x06, 0x72, 0x4a, 0xd0, 0x64,
+ 0xfd, 0xe1, 0x73, 0x38, 0x42, 0x9e, 0x0e, 0x9f,
+ 0x3f, 0x07, 0x60, 0xa3, 0x67, 0xa4, 0x51, 0x11,
+ 0x00, 0x13, 0xc1, 0x53, 0x07, 0xf9, 0xe4, 0xa8,
+ 0x24, 0x74, 0xdf, 0x1b, 0x5c, 0x78, 0xf3, 0x79,
+ 0x90, 0xe2, 0x95, 0x2c, 0x0e, 0x72, 0x11, 0x46,
+ 0x91, 0xba, 0x66, 0xca, 0x17, 0x98, 0xf3, 0xa3,
+ 0x03, 0xdd, 0x4d, 0x3c, 0xbc, 0xe2, 0x4a, 0x30,
+ 0x53, 0xfc, 0x26, 0x74, 0x02, 0xbb, 0x62, 0x70,
+ 0x04, 0x2f, 0xc5, 0xa0, 0xa3, 0x71, 0x82, 0x81,
+ 0x4e, 0x3c, 0x1f, 0x26, 0x04, 0x96, 0x1b, 0x04,
+ 0x6e, 0x0a, 0x63, 0x99, 0xf5, 0xb0, 0xbf, 0x69,
+ 0x42, 0xa1, 0x91, 0x29, 0xd0, 0xa8, 0x0e, 0x2e,
+ 0x49, 0xc1, 0x92, 0x7d, 0x8c, 0x6c, 0xba, 0xd4,
+ 0x10, 0x9d, 0x70, 0x97, 0x72, 0x5c, 0x2d, 0x1e,
+ 0x07, 0x0d, 0x48, 0x9e, 0x40, 0xe4, 0x2a, 0xdc,
+ 0x96, 0xab, 0x4a, 0x77, 0xc6, 0x30, 0x2b, 0x5e,
+ 0xea, 0x87, 0x79, 0x8a, 0xd7, 0x5f, 0x74, 0x9e,
+ 0x28, 0x90, 0xff, 0x2d, 0xa9, 0x06, 0x47, 0xe0,
+ 0x9d, 0x82, 0xc6, 0x29, 0x27, 0x12, 0x96, 0xf3,
+ 0x7d, 0x86, 0x9e, 0xd2, 0xea, 0x72, 0x2c, 0xb8,
+ 0xc0, 0x24, 0xec, 0x74, 0xd8, 0xfa, 0x01, 0xe0,
+ 0xdf, 0x13, 0x59, 0x10, 0x08, 0x05, 0x26, 0x0e,
+ 0x27, 0xef, 0xc3, 0x69, 0xb4, 0x9e, 0x7b, 0xd9,
+ 0xe2, 0x31, 0xf4, 0xb7, 0x09, 0x10, 0x6f, 0xe1,
+ 0xa7, 0x81, 0xf7, 0x7e, 0x9a, 0x6c, 0x38, 0x87,
+ 0x3d, 0x65, 0xab, 0x0f, 0xe3, 0x59, 0xa2, 0x49,
+ 0x36, 0xcf, 0x57, 0xd9, 0x71, 0xbf, 0x3f, 0x0f,
+ 0xf3, 0xc5, 0xda, 0xef, 0x4d, 0x92, 0x65, 0x7f,
+ 0xe9, 0xad, 0xfc, 0xe4, 0x42, 0xfe, 0xd3, 0x9d,
+ 0x47, 0xdd, 0x7f, 0x03, 0x05, 0xae, 0xa3, 0xa8,
+ 0x7f, 0x38, 0x3a, 0x7a, 0xfa, 0xf5, 0x34, 0xcc,
+ 0x26, 0x6b, 0x42, 0x62, 0x9c, 0x0e, 0x0f, 0x8e,
+ 0x0e, 0x86, 0xcf, 0x0f, 0x0f, 0x9f, 0x3a, 0xf1,
+ 0x20, 0xe4, 0x72, 0x29, 0x01, 0x84, 0xa6, 0xe6,
+ 0x6f, 0x24, 0x44, 0x60, 0x54, 0xf9, 0x03, 0x71,
+ 0x6c, 0x3e, 0x1e, 0xf4, 0x0e, 0xe9, 0xe3, 0xfe,
+ 0x21, 0x7c, 0x85, 0x7f, 0x6c, 0xa5, 0x61, 0x0a,
+ 0x67, 0xd5, 0xb9, 0x8a, 0x09, 0xac, 0xad, 0x09,
+ 0xad, 0x09, 0xec, 0xc8, 0x99, 0xfc, 0x09, 0xdb,
+ 0x30, 0xe7, 0x2d, 0x0f, 0xcf, 0x4d, 0xf9, 0x33,
+ 0xb7, 0x02, 0xf3, 0xb4, 0xe6, 0xf0, 0x61, 0x21,
+ 0x7f, 0x4c, 0x55, 0x5f, 0xfe, 0x4c, 0x64, 0xc0,
+ 0x79, 0x20, 0x6b, 0x5e, 0x48, 0x34, 0x3b, 0xd4,
+ 0x2c, 0xa5, 0x33, 0xa8, 0x27, 0x92, 0x90, 0x47,
+ 0x86, 0x82, 0xab, 0xd5, 0x00, 0x36, 0x39, 0x90,
+ 0xdc, 0x65, 0xac, 0x21, 0x38, 0x2a, 0x90, 0x8c,
+ 0x8d, 0x54, 0x75, 0xd8, 0x29, 0x14, 0x5e, 0x56,
+ 0x17, 0x0e, 0xed, 0xe0, 0xfa, 0x6c, 0x8c, 0x19,
+ 0xdc, 0x47, 0x78, 0xc8, 0x07, 0x29, 0xad, 0x56,
+ 0x0b, 0xab, 0x57, 0x29, 0x12, 0x95, 0x48, 0x15,
+ 0x64, 0xce, 0x08, 0x30, 0x40, 0x6f, 0x89, 0x92,
+ 0x30, 0x2a, 0x1d, 0x45, 0x0a, 0x09, 0xe6, 0x91,
+ 0x15, 0x25, 0x9b, 0xd2, 0x67, 0xed, 0x5c, 0x51,
+ 0x2a, 0xf1, 0x26, 0x18, 0xa8, 0x07, 0x17, 0x4c,
+ 0x06, 0x4f, 0x7d, 0xfd, 0x4a, 0xec, 0xf7, 0x86,
+ 0x07, 0xc3, 0xc3, 0xe7, 0xa3, 0xa7, 0x87, 0xfb,
+ 0x87, 0x47, 0xcf, 0x9f, 0x3d, 0xdf, 0xaf, 0x0f,
+ 0xb6, 0x45, 0x07, 0x44, 0x83, 0x0e, 0x53, 0xb5,
+ 0x83, 0x5a, 0x7c, 0x20, 0xf4, 0xd2, 0x39, 0xc7,
+ 0xd2, 0x6e, 0x97, 0x82, 0x69, 0xff, 0xe6, 0x9c,
+ 0x59, 0x74, 0x56, 0x21, 0xe3, 0xf3, 0x5c, 0x76,
+ 0xe7, 0x64, 0x33, 0x9b, 0xc0, 0xb2, 0xc5, 0xea,
+ 0xe4, 0x21, 0xf8, 0xc8, 0x74, 0x56, 0xab, 0x34,
+ 0xb9, 0xc0, 0xd8, 0xab, 0x18, 0x77, 0x27, 0xa7,
+ 0x38, 0x48, 0x56, 0xce, 0x26, 0x18, 0x3b, 0x26,
+ 0x5b, 0x63, 0x4e, 0x14, 0xa4, 0x13, 0x8f, 0x98,
+ 0x28, 0x47, 0xf7, 0xa2, 0x28, 0xbc, 0x61, 0x06,
+ 0x5f, 0xe8, 0xe5, 0x15, 0xb1, 0xb6, 0xaf, 0x0f,
+ 0x8e, 0x06, 0xcf, 0xa8, 0xf6, 0x34, 0xc8, 0xbd,
+ 0x30, 0xca, 0xec, 0x90, 0x31, 0x88, 0xd9, 0xf7,
+ 0x2a, 0xaa, 0x15, 0x3a, 0xeb, 0xa0, 0x93, 0x87,
+ 0x17, 0x67, 0xad, 0x96, 0x59, 0xc4, 0xb7, 0x83,
+ 0x77, 0x6c, 0xb8, 0x53, 0x7f, 0x0f, 0xdf, 0xe1,
+ 0x76, 0x96, 0x26, 0x50, 0xa9, 0x8e, 0xb6, 0xd9,
+ 0xde, 0x69, 0x55, 0x91, 0xc4, 0xc6, 0x13, 0x43,
+ 0xc1, 0xb9, 0xad, 0x33, 0xc1, 0x9e, 0x1f, 0x9b,
+ 0xa7, 0x7f, 0xe8, 0xca, 0x69, 0x82, 0x39, 0x19,
+ 0x02, 0x7f, 0xb0, 0x71, 0xa5, 0x06, 0x40, 0xb5,
+ 0xb9, 0x17, 0xb7, 0xb0, 0x0c, 0x43, 0x3d, 0xf3,
+ 0x7b, 0x16, 0x5a, 0x23, 0xe4, 0x41, 0xd6, 0x78,
+ 0xdc, 0xc7, 0x2c, 0x14, 0xb8, 0x09, 0x1a, 0x2b,
+ 0xce, 0xc1, 0x16, 0x56, 0xb4, 0xdd, 0x23, 0x34,
+ 0xc9, 0x32, 0x30, 0xb8, 0x0c, 0x97, 0xb7, 0x81,
+ 0x93, 0x02, 0x49, 0xa9, 0x07, 0x6b, 0xaa, 0x82,
+ 0xbe, 0x85, 0x18, 0x52, 0x5e, 0x8f, 0x6e, 0x29,
+ 0x1f, 0x88, 0x09, 0x57, 0x7b, 0xaa, 0x88, 0x5d,
+ 0xa9, 0xed, 0x72, 0x1e, 0xa6, 0x53, 0x04, 0xac,
+ 0xa2, 0x83, 0xd1, 0xe1, 0x08, 0x6b, 0x07, 0x42,
+ 0x06, 0xb4, 0x81, 0x15, 0x97, 0xb1, 0xb3, 0xe6,
+ 0x51, 0xe2, 0x7b, 0x91, 0x74, 0xe4, 0x48, 0x7c,
+ 0x5c, 0xda, 0x8e, 0x3c, 0xd0, 0x00, 0x42, 0x06,
+ 0x20, 0xfa, 0x23, 0xc7, 0xdb, 0x03, 0xc9, 0xe6,
+ 0x43, 0xb8, 0x5c, 0xe7, 0x0b, 0x13, 0x2e, 0x5a,
+ 0xe7, 0xa8, 0xd3, 0x1d, 0x14, 0xa8, 0x67, 0x30,
+ 0x0d, 0xe6, 0x98, 0xd0, 0x0e, 0xce, 0xc3, 0x55,
+ 0x12, 0xab, 0x50, 0xeb, 0x31, 0x10, 0xcf, 0xa2,
+ 0x4f, 0xb9, 0xbf, 0x92, 0x95, 0xa2, 0x4d, 0x95,
+ 0xb8, 0x4f, 0xa5, 0x4e, 0xc8, 0xf2, 0x4b, 0x20,
+ 0x69, 0x9c, 0x55, 0xdb, 0x85, 0x09, 0x4b, 0x92,
+ 0x34, 0x9c, 0x93, 0x83, 0x8d, 0x0c, 0xac, 0xbe,
+ 0xf1, 0x32, 0xb1, 0x49, 0xc3, 0x1c, 0x26, 0x46,
+ 0xf6, 0x1f, 0xac, 0x72, 0xd1, 0xea, 0x82, 0x04,
+ 0x42, 0xee, 0x76, 0x88, 0xe1, 0x77, 0xca, 0xa0,
+ 0x0c, 0xf4, 0xf4, 0x1c, 0x76, 0x96, 0x27, 0xbd,
+ 0xc3, 0xd4, 0x88, 0x7a, 0xf6, 0x52, 0xf2, 0x47,
+ 0x6b, 0x82, 0x2f, 0x81, 0xf4, 0x5e, 0xbf, 0x72,
+ 0xf6, 0xa1, 0x4e, 0x2c, 0x28, 0xa9, 0x06, 0x0e,
+ 0xfd, 0x24, 0x0e, 0x28, 0xe5, 0x0a, 0x3a, 0xbf,
+ 0xa9, 0x2d, 0xa8, 0x97, 0x0b, 0xc4, 0x30, 0xca,
+ 0xb6, 0xe6, 0x81, 0xe0, 0xc5, 0xae, 0x6b, 0x7c,
+ 0x01, 0xb3, 0x0c, 0x23, 0x0f, 0xdd, 0x6a, 0x6c,
+ 0x37, 0x30, 0x0b, 0x96, 0xfb, 0xde, 0x4a, 0xcc,
+ 0xd6, 0x31, 0x8f, 0xa2, 0x34, 0x49, 0xc7, 0xd7,
+ 0x94, 0x14, 0x7c, 0x58, 0x7f, 0xf8, 0x82, 0x49,
+ 0x1f, 0xfa, 0x59, 0x3a, 0xe9, 0x13, 0xa4, 0x2e,
+ 0x42, 0xea, 0x1b, 0xf9, 0xa5, 0x4f, 0xbc, 0x8f,
+ 0x96, 0x38, 0xeb, 0x1b, 0x4c, 0x82, 0xde, 0xbf,
+ 0xb3, 0xaf, 0x7f, 0x1c, 0x0d, 0x9f, 0x75, 0x7f,
+ 0x1c, 0x8d, 0x8e, 0x8a, 0xce, 0x45, 0xc8, 0x53,
+ 0x61, 0x55, 0x0c, 0xa1, 0x4a, 0x67, 0xb6, 0x09,
+ 0x48, 0x38, 0x98, 0x0b, 0x04, 0x45, 0x9b, 0x64,
+ 0xe5, 0x81, 0x92, 0x6b, 0x0b, 0x89, 0xf6, 0x02,
+ 0x48, 0x03, 0xed, 0xb0, 0x77, 0xf4, 0xec, 0x10,
+ 0xd6, 0xcb, 0x8e, 0xd0, 0x3c, 0xec, 0x3d, 0x3b,
+ 0xb4, 0xb7, 0x1d, 0x1c, 0xfe, 0xff, 0x90, 0x2e,
+ 0x91, 0x1c, 0x29, 0x10, 0x97, 0xa9, 0xc0, 0x7d,
+ 0xa6, 0x67, 0x72, 0x5f, 0x1b, 0x40, 0x5f, 0x71,
+ 0xf5, 0x6f, 0x90, 0xe7, 0x82, 0x4c, 0xc1, 0xf7,
+ 0xae, 0xb4, 0x90, 0x8a, 0xe9, 0x92, 0x7c, 0xae,
+ 0x8b, 0x54, 0x37, 0xaa, 0x14, 0xb9, 0x93, 0xee,
+ 0xfa, 0x98, 0x5b, 0xda, 0x39, 0x0f, 0x02, 0xc1,
+ 0xe7, 0x87, 0x74, 0xea, 0x80, 0x2d, 0xa8, 0x56,
+ 0xdd, 0xf5, 0xb5, 0xca, 0xf0, 0x64, 0x91, 0x1b,
+ 0x80, 0xe9, 0x08, 0xb6, 0xa0, 0xa2, 0x2b, 0xa4,
+ 0xee, 0x66, 0x00, 0xd8, 0xbc, 0x38, 0xfd, 0x79,
+ 0xa1, 0x73, 0xd8, 0xb7, 0x24, 0x94, 0x43, 0x2f,
+ 0x93, 0x05, 0xf9, 0x17, 0x06, 0x94, 0xfb, 0x03,
+ 0x28, 0xa8, 0xb2, 0x2f, 0xa8, 0xcf, 0x15, 0x40,
+ 0xa2, 0x75, 0x76, 0x05, 0xc3, 0x64, 0x1e, 0x6e,
+ 0xcd, 0xab, 0xc3, 0x84, 0x35, 0xff, 0xa5, 0x70,
+ 0x7c, 0x16, 0x2a, 0xb8, 0x77, 0xed, 0x01, 0xd1,
+ 0xa9, 0x45, 0x82, 0x17, 0x8c, 0xa7, 0x40, 0x2a,
+ 0xc5, 0x11, 0xa9, 0xe2, 0x10, 0x90, 0xfa, 0x4f,
+ 0x5e, 0xb8, 0x69, 0x42, 0x61, 0xd4, 0x30, 0x1c,
+ 0x1f, 0xdf, 0x12, 0x61, 0x8c, 0x79, 0xce, 0xd4,
+ 0xc9, 0x13, 0x8b, 0x7d, 0x30, 0xdd, 0x59, 0x5a,
+ 0x4f, 0x14, 0x94, 0xa9, 0xf2, 0x6f, 0x04, 0x4f,
+ 0xb2, 0xca, 0x80, 0x82, 0x42, 0x02, 0x34, 0x09,
+ 0x81, 0x68, 0x15, 0xcf, 0x9b, 0x6c, 0x05, 0xba,
+ 0x49, 0x2c, 0xe7, 0x83, 0xfd, 0x33, 0x68, 0x5c,
+ 0xda, 0x91, 0x56, 0x1e, 0x55, 0xfc, 0x95, 0x2d,
+ 0x94, 0x72, 0xe4, 0x7b, 0x52, 0xbe, 0xb4, 0xa9,
+ 0x78, 0x54, 0x7b, 0x9b, 0xc8, 0x73, 0xc4, 0x61,
+ 0xcd, 0xd0, 0xfe, 0xde, 0x92, 0xe7, 0xca, 0x13,
+ 0xc5, 0x95, 0x90, 0x30, 0x81, 0xbd, 0xb3, 0xd0,
+ 0xe9, 0x4a, 0x09, 0x1a, 0x37, 0x02, 0xa2, 0x51,
+ 0x63, 0x1b, 0x3d, 0x0b, 0x40, 0x1d, 0x5b, 0xe6,
+ 0xe9, 0x70, 0x45, 0xc4, 0x16, 0x08, 0xc9, 0x59,
+ 0xd3, 0xad, 0xb1, 0x2e, 0x08, 0xac, 0xce, 0xac,
+ 0xe8, 0x03, 0xdc, 0xc2, 0xa7, 0xe7, 0xe1, 0x31,
+ 0x6e, 0x7d, 0xb8, 0x15, 0x91, 0xf8, 0xd1, 0x23,
+ 0xc9, 0x39, 0x4d, 0x46, 0x8d, 0x73, 0x3c, 0x18,
+ 0xe8, 0x38, 0xe3, 0x13, 0x2c, 0x96, 0xe9, 0x2b,
+ 0x30, 0xe6, 0x9e, 0xa4, 0x6d, 0x72, 0xcc, 0xce,
+ 0xe1, 0x80, 0x80, 0x33, 0xfb, 0x9c, 0x62, 0x6b,
+ 0x52, 0xf2, 0x0c, 0x90, 0xa6, 0x96, 0x40, 0x02,
+ 0x41, 0xea, 0xbc, 0x84, 0xf5, 0x48, 0xd2, 0x53,
+ 0x49, 0x33, 0x7b, 0x5a, 0x2c, 0x7c, 0xf1, 0xd3,
+ 0x9b, 0x57, 0x2f, 0x7e, 0x7c, 0xf5, 0xe2, 0xec,
+ 0xd5, 0x4f, 0x3f, 0x34, 0x25, 0xa4, 0x84, 0xc9,
+ 0x23, 0x2c, 0x39, 0x51, 0xc1, 0x10, 0xf4, 0x6a,
+ 0xf8, 0x46, 0x19, 0x2d, 0x9e, 0x62, 0xae, 0x09,
+ 0x89, 0x3f, 0xf0, 0x14, 0x4a, 0xe2, 0x09, 0xfd,
+ 0x27, 0x1b, 0xc0, 0x65, 0x19, 0xe6, 0xe4, 0xd2,
+ 0xbb, 0x64, 0x0d, 0x19, 0x65, 0x05, 0xb9, 0xc5,
+ 0x97, 0x09, 0xfa, 0x68, 0xf6, 0x4c, 0xa4, 0xcb,
+ 0xa9, 0xf6, 0x6a, 0x0e, 0x29, 0xeb, 0x0f, 0x8a,
+ 0x68, 0xb4, 0xb7, 0x60, 0x40, 0xfe, 0x25, 0x30,
+ 0x80, 0x56, 0x77, 0x38, 0x3a, 0xea, 0xf5, 0xa0,
+ 0xeb, 0x76, 0x8f, 0x92, 0xbf, 0xd0, 0x09, 0x96,
+ 0x06, 0xf3, 0x35, 0x9e, 0x40, 0xdc, 0x36, 0xc3,
+ 0x74, 0x21, 0x30, 0x5a, 0x19, 0x49, 0xef, 0xe9,
+ 0x3e, 0x28, 0xed, 0xeb, 0x5c, 0x62, 0x87, 0x2a,
+ 0x72, 0x2a, 0x05, 0xad, 0xbf, 0x22, 0x59, 0xc2,
+ 0xf9, 0xf4, 0x57, 0xdd, 0x90, 0x79, 0xbf, 0x77,
+ 0x8e, 0x7a, 0xb4, 0x1f, 0xa2, 0x1a, 0xa6, 0xa0,
+ 0xb4, 0x80, 0xf5, 0x30, 0x58, 0x74, 0x54, 0x0f,
+ 0x63, 0x9d, 0xe0, 0x08, 0x93, 0x10, 0xb5, 0x69,
+ 0x1d, 0xd4, 0x6c, 0x32, 0x4e, 0x34, 0x23, 0xee,
+ 0x27, 0xcc, 0x76, 0x76, 0x78, 0xf4, 0x6c, 0x7f,
+ 0x30, 0x7c, 0xfa, 0xa8, 0xec, 0x2a, 0x85, 0x77,
+ 0x54, 0x8c, 0x47, 0x85, 0x1f, 0x95, 0xcc, 0x53,
+ 0x78, 0xc5, 0x85, 0x4c, 0x39, 0xfb, 0x14, 0x85,
+ 0xdf, 0x2c, 0x28, 0x17, 0x40, 0x8c, 0xe5, 0x57,
+ 0xb2, 0x05, 0x75, 0x45, 0x21, 0x52, 0xf8, 0x4c,
+ 0x11, 0x06, 0x47, 0x65, 0x2f, 0xac, 0xb9, 0xb7,
+ 0x5c, 0x7a, 0x2a, 0x90, 0x66, 0x55, 0x76, 0x09,
+ 0xbc, 0x98, 0x8a, 0x83, 0x2c, 0x99, 0x79, 0xe9,
+ 0x67, 0x1a, 0x75, 0x8f, 0xa2, 0xd1, 0x56, 0xfb,
+ 0x90, 0x51, 0x86, 0xfb, 0x5a, 0x1f, 0x32, 0xca,
+ 0xbf, 0x78, 0xe7, 0xe9, 0x48, 0x1f, 0xca, 0x13,
+ 0xe4, 0x6a, 0x2c, 0xe7, 0xde, 0x8a, 0xb3, 0x35,
+ 0x56, 0xa2, 0xa9, 0x4a, 0x1b, 0xf3, 0xad, 0xa9,
+ 0x4a, 0x57, 0x65, 0x5c, 0xb3, 0xeb, 0x35, 0xcf,
+ 0xdc, 0x6c, 0x96, 0x05, 0x35, 0xde, 0x77, 0x5c,
+ 0xd6, 0x30, 0x6f, 0x54, 0xde, 0x3c, 0x35, 0xba,
+ 0x4a, 0x23, 0x16, 0x0d, 0xd3, 0x72, 0xf5, 0x9c,
+ 0x6c, 0x35, 0x21, 0xc5, 0xd9, 0xf8, 0x6c, 0xc2,
+ 0x35, 0xea, 0xf8, 0xcf, 0x2a, 0x97, 0x69, 0xd9,
+ 0xd5, 0x90, 0x13, 0x59, 0xca, 0x1d, 0x58, 0xeb,
+ 0x6a, 0xd8, 0x9c, 0x0a, 0xf5, 0x21, 0x3c, 0x8f,
+ 0x6f, 0xc0, 0x45, 0x6f, 0x9d, 0x72, 0x0a, 0x35,
+ 0x55, 0x54, 0x89, 0x9b, 0x2a, 0xec, 0x38, 0x1b,
+ 0xac, 0x21, 0x21, 0x9b, 0x0d, 0xad, 0x62, 0x17,
+ 0x35, 0x4d, 0x17, 0xef, 0xa4, 0xe2, 0x80, 0xe9,
+ 0x6b, 0xf5, 0xbc, 0x51, 0x51, 0xc7, 0xda, 0x68,
+ 0xb5, 0xb3, 0xa6, 0x81, 0x94, 0x36, 0x54, 0x53,
+ 0x0e, 0xbd, 0x9a, 0x09, 0xab, 0x9f, 0x2d, 0x3d,
+ 0x55, 0x57, 0xcf, 0x93, 0x99, 0xa4, 0xe2, 0xce,
+ 0xd2, 0xc6, 0x30, 0xcf, 0x09, 0xbd, 0x2d, 0xf3,
+ 0xbd, 0xa2, 0x88, 0x0b, 0xb2, 0xcb, 0xc0, 0x31,
+ 0xb8, 0x18, 0xff, 0x65, 0xe9, 0xab, 0x22, 0xab,
+ 0x7f, 0xe8, 0x50, 0x64, 0x76, 0x16, 0x8b, 0x2d,
+ 0xaf, 0x3e, 0x79, 0x86, 0xa2, 0xb0, 0xae, 0xb2,
+ 0x45, 0x71, 0x7d, 0xbe, 0xb5, 0x45, 0xb9, 0x54,
+ 0x7e, 0xc1, 0x38, 0xe7, 0x4f, 0x0f, 0x74, 0x4e,
+ 0xbb, 0xb2, 0x4b, 0xa7, 0x2d, 0x71, 0x50, 0x3a,
+ 0x5a, 0xa5, 0x64, 0x5c, 0xa0, 0x94, 0x36, 0x44,
+ 0x57, 0xbb, 0x90, 0x0c, 0x26, 0x98, 0xed, 0x1c,
+ 0x34, 0x9f, 0x89, 0xb7, 0x02, 0xc9, 0xb9, 0x7c,
+ 0xef, 0x71, 0xa9, 0xab, 0xa3, 0x18, 0x27, 0xc5,
+ 0x37, 0xca, 0xf5, 0x86, 0x82, 0x18, 0x3f, 0xfc,
+ 0xe9, 0x4a, 0x70, 0xea, 0x3b, 0xde, 0x11, 0x38,
+ 0x53, 0x4b, 0x78, 0x59, 0xce, 0xb6, 0x16, 0x6a,
+ 0x1f, 0x36, 0x26, 0xee, 0xba, 0x2c, 0x57, 0xd2,
+ 0x89, 0x65, 0x6f, 0xc8, 0xa4, 0x8e, 0x83, 0x2c,
+ 0x90, 0xcc, 0x0c, 0x19, 0xc5, 0xa7, 0x46, 0x81,
+ 0xcd, 0x0f, 0xd0, 0x56, 0x18, 0x85, 0x2c, 0x48,
+ 0x22, 0x92, 0xff, 0xe7, 0x8c, 0xb0, 0x8a, 0xf9,
+ 0x3d, 0x23, 0xa5, 0x18, 0x44, 0x15, 0x39, 0xd3,
+ 0xb9, 0xe0, 0x96, 0x20, 0x7a, 0x93, 0x9d, 0x66,
+ 0x69, 0x12, 0x0b, 0x4a, 0x43, 0x0d, 0x5a, 0x84,
+ 0x40, 0xad, 0x48, 0x71, 0x2f, 0x93, 0x42, 0x18,
+ 0x2e, 0x01, 0x36, 0x6e, 0x67, 0x6e, 0x6d, 0x6d,
+ 0x23, 0xfd, 0x6b, 0x9f, 0x57, 0xc0, 0xba, 0x3c,
+ 0xf4, 0xa2, 0x99, 0xaa, 0x55, 0xaa, 0xa2, 0x69,
+ 0x1e, 0x0d, 0x67, 0xf8, 0x74, 0x5d, 0x12, 0xbe,
+ 0x63, 0x40, 0xe3, 0x1a, 0xba, 0x87, 0x27, 0xa2,
+ 0xa5, 0x7f, 0x57, 0xd6, 0x37, 0x47, 0xaa, 0x3f,
+ 0x2e, 0xdd, 0x41, 0x82, 0xfa, 0x50, 0x02, 0x62,
+ 0xf0, 0xda, 0xab, 0x00, 0x38, 0x22, 0x73, 0xde,
+ 0x90, 0xc9, 0xac, 0x65, 0x8d, 0x41, 0x59, 0x09,
+ 0x39, 0x8f, 0xaf, 0xdd, 0x6f, 0xbb, 0x98, 0xdf,
+ 0xad, 0x32, 0xa8, 0x3d, 0x5d, 0x19, 0xa1, 0x7e,
+ 0x62, 0xbf, 0x69, 0x84, 0x9a, 0x31, 0x8a, 0xdc,
+ 0xfe, 0xa5, 0xd1, 0x7e, 0xcc, 0xc6, 0x06, 0x80,
+ 0x64, 0x72, 0x08, 0x33, 0xba, 0xbf, 0x0b, 0x2e,
+ 0x7a, 0x65, 0x7a, 0x92, 0xd1, 0x7c, 0xe4, 0x40,
+ 0xf7, 0x9c, 0x28, 0xf8, 0x85, 0x24, 0x6f, 0xe6,
+ 0x29, 0x26, 0x29, 0xd0, 0xbc, 0x02, 0x1b, 0xc4,
+ 0x60, 0x9a, 0x7a, 0x1b, 0xb6, 0x79, 0x45, 0x9c,
+ 0xf2, 0xd0, 0xe3, 0x67, 0xae, 0x92, 0x28, 0xd0,
+ 0x8e, 0x2d, 0x6d, 0x1f, 0x9c, 0x85, 0x8e, 0xaa,
+ 0xf5, 0x6c, 0x63, 0x77, 0xa2, 0x2f, 0xf7, 0xc8,
+ 0x7a, 0xc4, 0xc0, 0xec, 0x24, 0x96, 0x72, 0x53,
+ 0xe4, 0xc9, 0xc6, 0x4b, 0xa7, 0x99, 0xad, 0x0d,
+ 0x91, 0xe6, 0x02, 0xfb, 0x2f, 0x07, 0xcc, 0xac,
+ 0x7b, 0x46, 0x42, 0x8c, 0x73, 0x3f, 0x2a, 0xf4,
+ 0x78, 0x8f, 0x02, 0x27, 0x52, 0xd0, 0x5a, 0x2e,
+ 0x6f, 0x81, 0x1d, 0x08, 0xdd, 0x0d, 0xdb, 0x32,
+ 0x6f, 0x1d, 0xf4, 0x11, 0xea, 0x37, 0x78, 0x6a,
+ 0x56, 0x24, 0x4e, 0x12, 0x00, 0x2a, 0x5d, 0x31,
+ 0xed, 0x76, 0xe3, 0x56, 0xdb, 0xab, 0xe0, 0x87,
+ 0x6b, 0x6d, 0xb6, 0xb2, 0x7a, 0x3c, 0xa9, 0xa8,
+ 0x98, 0x1b, 0x5f, 0x2c, 0x3f, 0x6b, 0xad, 0xdb,
+ 0x27, 0xe5, 0x15, 0xe3, 0x89, 0x47, 0xbf, 0x39,
+ 0xb9, 0x04, 0x15, 0x8b, 0x86, 0x37, 0xcc, 0xca,
+ 0x03, 0x18, 0x0d, 0x58, 0x39, 0x25, 0xb1, 0xea,
+ 0xae, 0x3b, 0x02, 0xfe, 0x9f, 0x3b, 0x8e, 0x75,
+ 0x3a, 0x99, 0x87, 0xc5, 0x8f, 0x8b, 0xf7, 0x3e,
+ 0x44, 0x24, 0x7d, 0xa5, 0x2c, 0x19, 0x27, 0xe9,
+ 0x72, 0x32, 0xa0, 0x8a, 0xc6, 0x7c, 0x69, 0xaf,
+ 0xb0, 0x2e, 0x42, 0x91, 0x3b, 0xa5, 0x84, 0x85,
+ 0x21, 0x3b, 0x6d, 0x0f, 0x13, 0xf8, 0x92, 0x7a,
+ 0xb9, 0x96, 0x9a, 0xbe, 0x95, 0x42, 0x81, 0x4c,
+ 0xca, 0x98, 0x14, 0x34, 0xcc, 0x16, 0xa8, 0xf3,
+ 0xa7, 0x18, 0xbf, 0x3e, 0xc0, 0xa4, 0x1e, 0x0e,
+ 0xa1, 0xd4, 0x06, 0xc9, 0x1f, 0xa3, 0x9d, 0x0d,
+ 0x76, 0x80, 0x9d, 0x96, 0xc1, 0x44, 0xb8, 0xb2,
+ 0xa2, 0x5f, 0xd6, 0x36, 0xae, 0x6e, 0x59, 0x1a,
+ 0x54, 0x55, 0x40, 0xbb, 0xbd, 0x4a, 0x6d, 0x53,
+ 0x5f, 0xaf, 0x59, 0x5a, 0x23, 0x00, 0xde, 0x02,
+ 0xef, 0xfe, 0x55, 0xf8, 0xe9, 0x93, 0x92, 0x15,
+ 0x55, 0x75, 0xa3, 0xcb, 0x1c, 0xa0, 0xc3, 0x6c,
+ 0xf3, 0xd3, 0x86, 0xd9, 0x26, 0xa1, 0xf6, 0xce,
+ 0xb5, 0xc1, 0xbb, 0x8a, 0x27, 0x5b, 0xd4, 0xff,
+ 0x6b, 0xac, 0x05, 0x95, 0x66, 0x81, 0x7b, 0x0f,
+ 0x08, 0xae, 0xf5, 0x87, 0xed, 0x75, 0x81, 0x5b,
+ 0x0c, 0xfe, 0x53, 0x3a, 0x54, 0xac, 0x44, 0xb9,
+ 0xe6, 0x1e, 0xd3, 0x64, 0xc7, 0xa5, 0xd3, 0x85,
+ 0x32, 0xf6, 0xe0, 0x1e, 0xe9, 0x35, 0x04, 0xa5,
+ 0xe3, 0xd9, 0x6e, 0x93, 0xbb, 0x2f, 0x2f, 0x48,
+ 0x2f, 0xab, 0x3b, 0xc9, 0x3c, 0xba, 0x80, 0x61,
+ 0x7b, 0x1f, 0xa7, 0xea, 0xe0, 0x8b, 0xc3, 0x1e,
+ 0xa7, 0xf2, 0x40, 0x67, 0x9c, 0x90, 0x58, 0x3c,
+ 0x1d, 0x29, 0x33, 0xf9, 0xa2, 0x3a, 0xb6, 0x2f,
+ 0x72, 0x14, 0x62, 0x68, 0xe8, 0xa2, 0x14, 0xc5,
+ 0xb1, 0x62, 0xce, 0x54, 0xd2, 0xd2, 0x48, 0xe4,
+ 0x6d, 0x64, 0x4f, 0x36, 0x20, 0x95, 0x13, 0x04,
+ 0x20, 0x99, 0x6a, 0x99, 0x1d, 0x0f, 0x02, 0x97,
+ 0x01, 0xb7, 0x69, 0x8b, 0x16, 0xe6, 0x49, 0xad,
+ 0xf1, 0x91, 0x47, 0xeb, 0xd0, 0x53, 0x39, 0x06,
+ 0x1f, 0x5b, 0x7b, 0x97, 0x40, 0x60, 0x34, 0x65,
+ 0x5d, 0x1b, 0x37, 0xf8, 0x8b, 0xfa, 0xc2, 0xc7,
+ 0x14, 0x1a, 0x13, 0xf8, 0x48, 0x1c, 0x10, 0xba,
+ 0xa4, 0xc2, 0x72, 0xd4, 0x83, 0x9a, 0xd8, 0xf0,
+ 0x77, 0x13, 0x0b, 0x78, 0x67, 0x59, 0xbd, 0x15,
+ 0xcb, 0x6a, 0xf1, 0x6e, 0x53, 0x6f, 0x3c, 0x9f,
+ 0x53, 0x4d, 0xcb, 0x74, 0xd9, 0xa1, 0xf6, 0x75,
+ 0xf2, 0xd7, 0xb3, 0x19, 0x9c, 0x21, 0xfa, 0xae,
+ 0x06, 0x46, 0x8f, 0x8e, 0x65, 0x34, 0x45, 0x08,
+ 0x8d, 0x02, 0x39, 0x28, 0x28, 0x1c, 0xd0, 0x82,
+ 0x3e, 0x65, 0x01, 0x65, 0xb8, 0xce, 0x7a, 0xe2,
+ 0xd7, 0x4c, 0x5e, 0x52, 0x6b, 0xe7, 0x5d, 0x99,
+ 0xe7, 0xd8, 0x41, 0xc0, 0x18, 0xdc, 0x7f, 0x7c,
+ 0xf5, 0xd3, 0xcb, 0xf1, 0x77, 0xaf, 0xce, 0xde,
+ 0xbc, 0xf8, 0x09, 0xe8, 0xfc, 0xec, 0xdb, 0x17,
+ 0x3f, 0xbe, 0xd4, 0xc6, 0xf5, 0xcf, 0xe0, 0x0a,
+ 0xe0, 0x8b, 0xb2, 0x5d, 0x5b, 0x86, 0xe9, 0xe6,
+ 0xf3, 0x6b, 0x67, 0x18, 0xbe, 0x7d, 0xc3, 0xf0,
+ 0xc3, 0x30, 0xc2, 0x3e, 0x44, 0xf3, 0xf4, 0x03,
+ 0x36, 0x0c, 0xef, 0x0c, 0xb3, 0x0f, 0xd2, 0xea,
+ 0xf9, 0x19, 0x58, 0x8a, 0xbf, 0x38, 0xc3, 0xac,
+ 0xdd, 0xe2, 0xa6, 0xd6, 0xd9, 0x0a, 0x61, 0x60,
+ 0x67, 0xad, 0xdd, 0x59, 0x6b, 0x77, 0xd6, 0xda,
+ 0x9d, 0xb5, 0x76, 0x67, 0xad, 0xdd, 0x59, 0x6b,
+ 0xff, 0x04, 0xd6, 0x5a, 0xfb, 0xe4, 0xf4, 0x6c,
+ 0x85, 0x6c, 0x4b, 0x63, 0xee, 0xed, 0x46, 0xf9,
+ 0x7a, 0x48, 0xd1, 0x34, 0x50, 0xcd, 0xbf, 0x5e,
+ 0x38, 0x8d, 0x4f, 0xa1, 0xfd, 0x7e, 0x46, 0xf6,
+ 0xec, 0x6d, 0x43, 0x6e, 0xec, 0x6c, 0xc7, 0x3b,
+ 0xdb, 0xf1, 0x47, 0xda, 0x8e, 0xb9, 0x83, 0x0b,
+ 0x0a, 0x48, 0xc5, 0x61, 0x48, 0x0c, 0x9f, 0xeb,
+ 0x97, 0xd8, 0x14, 0xbe, 0xf6, 0x2d, 0x3a, 0x52,
+ 0x5f, 0x58, 0x21, 0x4c, 0x1a, 0xda, 0xfa, 0xa6,
+ 0xad, 0x9a, 0x32, 0xb5, 0xd2, 0x3d, 0x92, 0xf7,
+ 0x8d, 0x59, 0x38, 0x9c, 0x92, 0xbc, 0xa0, 0xe8,
+ 0x08, 0x81, 0x76, 0x50, 0xda, 0x90, 0xe5, 0x1c,
+ 0x88, 0x15, 0x0d, 0x8c, 0x00, 0x50, 0x7d, 0xa4,
+ 0x50, 0x55, 0xf4, 0xd1, 0x7a, 0x3c, 0x4b, 0xf3,
+ 0x55, 0x10, 0xf5, 0x94, 0xec, 0xc6, 0x52, 0xbc,
+ 0x0a, 0x57, 0x3c, 0x20, 0xf9, 0x10, 0xe5, 0x4f,
+ 0x26, 0x5d, 0xc6, 0x5c, 0x45, 0x9e, 0x59, 0x45,
+ 0xeb, 0x4c, 0xa5, 0xa4, 0x17, 0xf8, 0x2e, 0xb2,
+ 0x6d, 0xbd, 0xe1, 0x0a, 0xe2, 0x6c, 0x2d, 0x5f,
+ 0x39, 0x27, 0xf1, 0xe3, 0x5c, 0xb2, 0x3f, 0xea,
+ 0x46, 0xbd, 0x1f, 0x9b, 0x06, 0x18, 0xac, 0x96,
+ 0x5e, 0x14, 0x64, 0x97, 0x4b, 0x3f, 0x89, 0xd4,
+ 0x9b, 0xb1, 0x6c, 0x05, 0x42, 0x3f, 0xea, 0x01,
+ 0x41, 0x90, 0x6b, 0x01, 0x0f, 0x25, 0x1f, 0x7c,
+ 0x1f, 0x3b, 0x9d, 0xb2, 0xb2, 0x91, 0x2d, 0xc2,
+ 0x59, 0xae, 0x43, 0xc6, 0xd2, 0x7b, 0x15, 0x85,
+ 0x3d, 0x4a, 0x68, 0x50, 0xc9, 0x1d, 0xc5, 0x90,
+ 0x14, 0x0a, 0xf7, 0x39, 0x4b, 0x32, 0xb3, 0x29,
+ 0x5e, 0x3e, 0x96, 0xe3, 0x90, 0x0c, 0xf8, 0x6e,
+ 0xc7, 0x3e, 0xec, 0x2f, 0xc7, 0x32, 0x8f, 0x3c,
+ 0x4a, 0xe4, 0xd6, 0x12, 0x29, 0x47, 0x75, 0x43,
+ 0x5d, 0x92, 0x9a, 0x5a, 0x25, 0x2a, 0xc1, 0x57,
+ 0x3c, 0x26, 0x54, 0x46, 0xbb, 0x8a, 0x90, 0xdc,
+ 0x04, 0x45, 0x97, 0x44, 0x43, 0x1f, 0xd1, 0xa7,
+ 0x7f, 0x75, 0x9f, 0xbe, 0xee, 0x53, 0x69, 0xac,
+ 0x4c, 0xf4, 0x1f, 0x11, 0x08, 0x88, 0x8e, 0xfa,
+ 0x0b, 0x8c, 0x31, 0x04, 0x93, 0xd6, 0x2e, 0x42,
+ 0xf7, 0x3f, 0x32, 0x6c, 0x8f, 0x84, 0xee, 0x23,
+ 0x74, 0xbf, 0xed, 0x48, 0xa1, 0xf6, 0x8b, 0x83,
+ 0xea, 0xe0, 0x3d, 0x63, 0x8c, 0xd2, 0x5d, 0x53,
+ 0x84, 0x31, 0x71, 0xf9, 0xd4, 0xbe, 0xe2, 0x06,
+ 0xe9, 0x2e, 0x72, 0x3b, 0xed, 0xee, 0x8f, 0x76,
+ 0xf7, 0x47, 0xbb, 0xfb, 0xa3, 0xc6, 0xfb, 0x23,
+ 0xc9, 0x12, 0x6a, 0x83, 0xf0, 0xc2, 0xb6, 0x1e,
+ 0x5f, 0xd6, 0x8b, 0xf6, 0xf5, 0x31, 0x7a, 0xa9,
+ 0x9d, 0x7f, 0x97, 0xf7, 0x55, 0xf2, 0x33, 0xf6,
+ 0xe4, 0x55, 0x7e, 0xf5, 0x6f, 0x28, 0xc2, 0xef,
+ 0x9e, 0x5d, 0xec, 0x9e, 0x5d, 0xec, 0x9e, 0x5d,
+ 0x5c, 0xff, 0x76, 0x4d, 0x2d, 0x5e, 0xc5, 0x2d,
+ 0xc4, 0x75, 0xaf, 0xde, 0xaa, 0x91, 0xa4, 0xc3,
+ 0xbc, 0x01, 0x53, 0x53, 0x5e, 0x3f, 0x65, 0xa6,
+ 0x4e, 0x25, 0xb5, 0xd9, 0xc5, 0x0d, 0xb3, 0xea,
+ 0x56, 0xdb, 0x3d, 0x24, 0xd9, 0x3d, 0x24, 0xf9,
+ 0xb3, 0x3d, 0x24, 0xb9, 0xdb, 0x1b, 0xca, 0x06,
+ 0x14, 0x2c, 0x26, 0x20, 0x95, 0x3a, 0xf9, 0x67,
+ 0x25, 0x32, 0xa6, 0xb8, 0x53, 0x60, 0x10, 0x75,
+ 0x13, 0xe3, 0x02, 0xac, 0xde, 0xe9, 0xbb, 0xfb,
+ 0xd3, 0xdd, 0xfd, 0xe9, 0xee, 0xfe, 0xf4, 0xb3,
+ 0xb8, 0x3f, 0xdd, 0x5d, 0x9f, 0xee, 0xae, 0x4f,
+ 0x77, 0xd7, 0xa7, 0x7f, 0xae, 0xeb, 0x53, 0x32,
+ 0x09, 0xa8, 0xeb, 0x51, 0xfb, 0x1c, 0xdd, 0x2b,
+ 0x59, 0x3c, 0x28, 0x1a, 0xa0, 0x2d, 0x24, 0x58,
+ 0xd4, 0x55, 0xaa, 0x7b, 0x49, 0xc1, 0xca, 0xa4,
+ 0x49, 0x44, 0x0f, 0x84, 0x4c, 0x0d, 0x5b, 0xf5,
+ 0xe6, 0x5f, 0xa3, 0x37, 0xdf, 0xe9, 0xcd, 0x6f,
+ 0x5f, 0xe3, 0x25, 0xcf, 0x35, 0xa2, 0x79, 0x67,
+ 0xd3, 0x19, 0xad, 0x43, 0x5d, 0xda, 0x82, 0x07,
+ 0x69, 0x99, 0xd9, 0xbd, 0x46, 0xda, 0x46, 0x97,
+ 0xbf, 0x4f, 0x6d, 0xfc, 0x5e, 0x14, 0xe9, 0x2f,
+ 0xf0, 0x61, 0x54, 0x3d, 0xb4, 0x2b, 0x1d, 0x43,
+ 0xeb, 0x34, 0xa6, 0x2b, 0x15, 0xa6, 0x1b, 0xa8,
+ 0x3a, 0xbb, 0xeb, 0xf7, 0x2f, 0xe7, 0xfa, 0x1d,
+ 0x38, 0x3e, 0xd6, 0x1b, 0x7b, 0x75, 0x81, 0x4c,
+ 0x89, 0x6b, 0xb7, 0x7b, 0xde, 0x49, 0x45, 0x23,
+ 0xbf, 0xa9, 0x91, 0x5f, 0xdd, 0x48, 0x5e, 0x1d,
+ 0xea, 0x7e, 0x3b, 0x06, 0x9a, 0x49, 0xe4, 0x81,
+ 0xad, 0xe4, 0x0d, 0xe0, 0xa9, 0xc8, 0x96, 0x09,
+ 0x48, 0x9e, 0x59, 0x1e, 0xac, 0x28, 0x21, 0x52,
+ 0xd7, 0x3a, 0xa7, 0x0a, 0xc7, 0xa7, 0xca, 0x97,
+ 0x54, 0x53, 0x2c, 0x3b, 0xfa, 0x24, 0x6f, 0xd7,
+ 0xb6, 0x4b, 0x15, 0x92, 0x47, 0x63, 0x0e, 0x42,
+ 0x57, 0x97, 0xfe, 0xb0, 0xae, 0x94, 0xaf, 0xd8,
+ 0xf4, 0x79, 0x79, 0x4b, 0x61, 0x82, 0x07, 0x55,
+ 0x61, 0x7a, 0x87, 0xb7, 0x12, 0x3c, 0x58, 0xc6,
+ 0x31, 0x4d, 0x03, 0x19, 0x32, 0xf3, 0x55, 0x9c,
+ 0x0f, 0x9f, 0x92, 0x3a, 0xad, 0x3c, 0x04, 0x74,
+ 0xdc, 0x51, 0xe3, 0x2a, 0x40, 0x9a, 0xd6, 0x1c,
+ 0x85, 0xbf, 0x35, 0xec, 0xee, 0x18, 0x03, 0x8e,
+ 0x0b, 0x93, 0xf4, 0x62, 0x66, 0xb2, 0xe6, 0xce,
+ 0x52, 0x4f, 0x65, 0x96, 0xb2, 0x5a, 0xf7, 0xb0,
+ 0x4b, 0x8c, 0xec, 0x8d, 0x11, 0x8a, 0xc9, 0xbd,
+ 0x41, 0x2b, 0xa1, 0x65, 0xb7, 0x84, 0x4c, 0x99,
+ 0x07, 0x78, 0x6a, 0x75, 0x7c, 0x52, 0x27, 0x7a,
+ 0x78, 0x18, 0x5d, 0xd2, 0x59, 0xa3, 0x62, 0xba,
+ 0x03, 0x4c, 0x0c, 0xab, 0x19, 0xa4, 0x78, 0x0f,
+ 0x3b, 0x0d, 0x7e, 0x5f, 0x23, 0xb3, 0x32, 0x18,
+ 0x12, 0x03, 0x81, 0x05, 0xc4, 0x38, 0xb0, 0x2a,
+ 0x1a, 0x26, 0x85, 0x92, 0x64, 0x7e, 0x45, 0x57,
+ 0xbb, 0xa4, 0x48, 0x7a, 0xcb, 0x40, 0x5e, 0x75,
+ 0xca, 0x18, 0xa6, 0x2f, 0xff, 0xf9, 0xe6, 0xe5,
+ 0x4f, 0x6f, 0xf0, 0xe6, 0xd4, 0x4c, 0x19, 0x4e,
+ 0x56, 0xb2, 0x96, 0x61, 0xe5, 0x19, 0x4b, 0x32,
+ 0xe6, 0x58, 0x63, 0xe8, 0x58, 0x61, 0x16, 0x61,
+ 0x45, 0x16, 0x32, 0xee, 0x38, 0xd0, 0x24, 0x2d,
+ 0xaa, 0x64, 0x90, 0x78, 0x17, 0x9c, 0xc4, 0x19,
+ 0x6c, 0x0d, 0x13, 0xfe, 0x90, 0x96, 0x9f, 0xe2,
+ 0x15, 0xd7, 0x26, 0x23, 0xe9, 0x52, 0x62, 0x30,
+ 0x52, 0x74, 0x6c, 0xf2, 0x13, 0x6d, 0x0e, 0x5c,
+ 0x68, 0x05, 0x89, 0xc6, 0xd4, 0x44, 0x2d, 0x09,
+ 0x72, 0xaf, 0x40, 0xcb, 0x1c, 0xf1, 0xd7, 0x22,
+ 0x7c, 0x6b, 0xb3, 0xd8, 0x5e, 0x7e, 0xe3, 0xbc,
+ 0x21, 0xf9, 0x4c, 0xad, 0x88, 0x3b, 0x68, 0x28,
+ 0x1b, 0x9e, 0x5c, 0x87, 0xe4, 0x4b, 0x3b, 0x8e,
+ 0x52, 0x6b, 0x83, 0x6c, 0x9f, 0x61, 0x5a, 0xba,
+ 0x93, 0xa6, 0x72, 0xa4, 0x90, 0x0a, 0x08, 0x99,
+ 0x07, 0x93, 0x4a, 0xd6, 0x29, 0x9d, 0x95, 0xb4,
+ 0x58, 0x05, 0x96, 0x05, 0xc8, 0x2c, 0xcb, 0x4b,
+ 0x15, 0x64, 0x56, 0xd2, 0x6c, 0x15, 0xc6, 0xe3,
+ 0x0d, 0x79, 0x0a, 0x95, 0x63, 0x7a, 0xab, 0xb5,
+ 0x4f, 0x03, 0x6f, 0x4a, 0x36, 0x94, 0x49, 0x9a,
+ 0x64, 0x59, 0x77, 0xa6, 0x03, 0x74, 0x66, 0xe6,
+ 0x88, 0xc6, 0x46, 0x54, 0x87, 0x57, 0x81, 0x33,
+ 0x13, 0x14, 0x9c, 0x3e, 0x06, 0x55, 0xdc, 0x7e,
+ 0x20, 0x83, 0x5d, 0x0f, 0xb6, 0xcb, 0x47, 0x35,
+ 0x94, 0xd5, 0x15, 0x1b, 0xc0, 0x7c, 0x75, 0x0c,
+ 0xbc, 0xe7, 0xb1, 0x65, 0xc9, 0x4e, 0x57, 0x27,
+ 0x4b, 0x30, 0x6b, 0xdc, 0xa9, 0xfd, 0x47, 0x5f,
+ 0xfd, 0xe1, 0xa9, 0x44, 0x73, 0x0e, 0xac, 0x61,
+ 0x2d, 0xac, 0xa1, 0x0d, 0x6b, 0x68, 0xc3, 0x1a,
+ 0xba, 0xb0, 0x4a, 0xae, 0x2e, 0xdc, 0xa1, 0x4c,
+ 0x39, 0x35, 0xec, 0x68, 0xa2, 0xb4, 0x33, 0xd9,
+ 0xf7, 0xe8, 0xb8, 0xb2, 0xc8, 0x52, 0xa7, 0xc9,
+ 0xb4, 0x7a, 0xc5, 0x4e, 0x8d, 0x48, 0x83, 0x0b,
+ 0xc8, 0xe9, 0x68, 0xe6, 0x52, 0x67, 0xdc, 0xb7,
+ 0xe2, 0xd3, 0x27, 0x79, 0x0b, 0xbe, 0x77, 0x0a,
+ 0x0b, 0x8d, 0xf9, 0x35, 0xad, 0xd0, 0xfa, 0x75,
+ 0xb5, 0x3e, 0x5c, 0x5c, 0x6e, 0x51, 0xeb, 0xf2,
+ 0xc3, 0x45, 0xdb, 0x32, 0xcb, 0x19, 0x9a, 0xb4,
+ 0x85, 0x10, 0x8c, 0x97, 0x3a, 0x47, 0xb5, 0x5c,
+ 0x27, 0xfc, 0x7e, 0x22, 0x74, 0x86, 0x6e, 0xa1,
+ 0xb2, 0x5d, 0xc3, 0x54, 0xee, 0xeb, 0xec, 0x3a,
+ 0x9c, 0xe8, 0xaf, 0xa5, 0x9a, 0x76, 0xf1, 0x0b,
+ 0x87, 0x4c, 0xad, 0x20, 0x7b, 0x6d, 0x01, 0x91,
+ 0xe4, 0x6e, 0xcd, 0x08, 0x22, 0xad, 0x38, 0xcd,
+ 0x5e, 0x79, 0x47, 0x28, 0x56, 0xa3, 0x20, 0x98,
+ 0x5d, 0x67, 0x26, 0x9f, 0xa3, 0xa1, 0xe2, 0x0d,
+ 0x80, 0x9a, 0xe1, 0xe2, 0xee, 0xed, 0x88, 0xab,
+ 0xbf, 0xb4, 0x4f, 0x6c, 0x88, 0xf0, 0xa1, 0x16,
+ 0x20, 0xf6, 0xd6, 0x11, 0xdb, 0x7c, 0xaa, 0x91,
+ 0x44, 0xe8, 0xc8, 0x64, 0xf7, 0x2d, 0x85, 0x79,
+ 0xc7, 0xf4, 0xd9, 0x51, 0x53, 0x29, 0x69, 0xae,
+ 0xa3, 0x7e, 0xb9, 0x1d, 0x41, 0x05, 0x4f, 0x82,
+ 0x5c, 0x2e, 0xfc, 0xeb, 0x57, 0x50, 0xab, 0x14,
+ 0x10, 0xff, 0xa4, 0xc6, 0x41, 0x45, 0x59, 0xa6,
+ 0x6b, 0x1c, 0x54, 0x9c, 0xcf, 0xfb, 0xd8, 0x46,
+ 0x5b, 0x8d, 0x0a, 0xd2, 0x89, 0xbe, 0xbf, 0xc5,
+ 0x1d, 0x66, 0x1c, 0xc0, 0x14, 0xef, 0xf3, 0x93,
+ 0x24, 0x42, 0x1e, 0x9e, 0xb1, 0x73, 0x1d, 0x26,
+ 0x7d, 0x18, 0x13, 0xd6, 0x9e, 0x2d, 0x19, 0x15,
+ 0x6a, 0xcd, 0x02, 0x8f, 0x8e, 0xb0, 0x72, 0x45,
+ 0x3b, 0x0c, 0xe7, 0x9a, 0x2b, 0xe7, 0x94, 0x42,
+ 0x55, 0xdd, 0x18, 0x58, 0x31, 0xb1, 0xb5, 0xbb,
+ 0x23, 0x25, 0xa6, 0xc8, 0xf2, 0x64, 0x95, 0xf1,
+ 0xa1, 0x4e, 0x69, 0x62, 0xf0, 0x08, 0x67, 0x47,
+ 0xc9, 0x0c, 0x5d, 0x2b, 0x55, 0x1c, 0xef, 0x86,
+ 0x9e, 0x4c, 0x3f, 0x0e, 0x14, 0x0a, 0xac, 0x4c,
+ 0x5d, 0x20, 0x4b, 0x96, 0xa8, 0x0b, 0x85, 0x7a,
+ 0x0d, 0xbc, 0x09, 0x08, 0x0d, 0xa9, 0x87, 0x96,
+ 0x35, 0x0c, 0xcf, 0x0b, 0xa7, 0xb1, 0xd2, 0xca,
+ 0xea, 0x86, 0xba, 0x0a, 0xf3, 0xc9, 0xa2, 0x34,
+ 0x61, 0x6c, 0x5f, 0x1e, 0xb3, 0xb3, 0x68, 0x5d,
+ 0x53, 0x0e, 0x58, 0x5c, 0xf4, 0x21, 0x72, 0x8e,
+ 0x6b, 0x8e, 0x43, 0x7d, 0xf2, 0xd9, 0x78, 0x88,
+ 0x5c, 0xe5, 0x3e, 0xc5, 0x9f, 0x23, 0xcf, 0x0f,
+ 0x40, 0x54, 0x89, 0xbc, 0x38, 0xa8, 0xab, 0x32,
+ 0x57, 0xd9, 0x6a, 0x75, 0xd2, 0x8e, 0x32, 0x49,
+ 0xe2, 0xb9, 0x58, 0x9a, 0x79, 0x5a, 0x0f, 0xb6,
+ 0x62, 0x2e, 0xbd, 0x55, 0x39, 0x1b, 0x86, 0x7e,
+ 0x04, 0x51, 0x61, 0x42, 0x2b, 0x1b, 0xd0, 0x0a,
+ 0x9b, 0x67, 0x6b, 0x67, 0x84, 0x7b, 0xbf, 0x92,
+ 0xb7, 0x6f, 0x4f, 0xed, 0xbb, 0x48, 0x66, 0x27,
+ 0x74, 0x17, 0x69, 0xd5, 0xd0, 0xd7, 0x61, 0x4e,
+ 0xa5, 0x0f, 0x9b, 0x13, 0x07, 0x0e, 0xcc, 0x88,
+ 0x7d, 0x03, 0xeb, 0x40, 0xa0, 0x4d, 0xa6, 0x0b,
+ 0x75, 0x4b, 0x9b, 0xc0, 0xa5, 0xe3, 0xe1, 0x18,
+ 0x28, 0x98, 0xac, 0xd1, 0xdd, 0x02, 0xb3, 0x7a,
+ 0x3b, 0x7a, 0xe7, 0x2a, 0xd1, 0xb4, 0x2c, 0x4a,
+ 0x06, 0xf9, 0xaa, 0x86, 0x37, 0x61, 0x06, 0xe8,
+ 0xaf, 0xea, 0x39, 0x92, 0x2d, 0xac, 0x48, 0x1c,
+ 0xf1, 0x0c, 0x60, 0x84, 0xdf, 0x0e, 0xde, 0x75,
+ 0x24, 0xee, 0x6f, 0x87, 0xef, 0x3a, 0x9a, 0x51,
+ 0xe1, 0xa1, 0x3b, 0x1c, 0xa8, 0x53, 0xf7, 0x0f,
+ 0x81, 0xb3, 0x4f, 0x48, 0xdc, 0x1a, 0x0e, 0xba,
+ 0xff, 0xba, 0x9e, 0x9a, 0x86, 0x7b, 0xad, 0x9e,
+ 0x24, 0x4b, 0xb4, 0xe1, 0x37, 0xd7, 0xa9, 0xba,
+ 0xdc, 0x79, 0x4d, 0xee, 0xfb, 0xdb, 0x68, 0xa0,
+ 0xf6, 0x82, 0x1b, 0xde, 0x09, 0x0c, 0x73, 0x91,
+ 0x18, 0xde, 0x09, 0x90, 0x5c, 0xd0, 0xbd, 0x8d,
+ 0xd6, 0x5f, 0xcf, 0x02, 0x72, 0x8b, 0x27, 0x17,
+ 0x55, 0x54, 0x16, 0x99, 0x65, 0xa2, 0xf1, 0xa1,
+ 0xc7, 0x97, 0x90, 0xa5, 0x6e, 0x14, 0x54, 0x66,
+ 0x9c, 0x84, 0xa5, 0xbb, 0xe9, 0xc5, 0x37, 0x46,
+ 0x5e, 0xad, 0x45, 0xa9, 0xdf, 0xc4, 0xec, 0xc5,
+ 0xb1, 0x86, 0xd0, 0x54, 0xab, 0x5f, 0x0f, 0xbf,
+ 0x3c, 0x3b, 0xd6, 0x9d, 0x8a, 0xc6, 0x9c, 0x0d,
+ 0x52, 0xba, 0x2f, 0xfc, 0x1f, 0x5b, 0x5f, 0xf8,
+ 0xf6, 0xcf, 0x1d, 0x69, 0xa7, 0x50, 0x0f, 0x56,
+ 0x01, 0xe6, 0xef, 0x75, 0x1a, 0x9c, 0xd3, 0xdc,
+ 0xa1, 0x13, 0x2e, 0x2e, 0xeb, 0x54, 0xc4, 0x81,
+ 0x97, 0x76, 0x67, 0x61, 0x10, 0xa9, 0xd7, 0x0a,
+ 0x19, 0xdb, 0x0d, 0xf1, 0x8a, 0x6b, 0xda, 0xc7,
+ 0x7a, 0x48, 0x62, 0x78, 0x2c, 0x6b, 0xfd, 0x44,
+ 0xfd, 0xef, 0xc0, 0x58, 0xb6, 0x88, 0x56, 0x40,
+ 0x12, 0x2f, 0xe1, 0xed, 0x6c, 0xda, 0x19, 0x48,
+ 0x92, 0x67, 0xf2, 0xba, 0x49, 0x33, 0x65, 0xf1,
+ 0x0d, 0xb7, 0xee, 0x8b, 0xd1, 0x01, 0x5d, 0x5f,
+ 0x4b, 0x8e, 0x5b, 0xe2, 0x10, 0xbc, 0xd6, 0x74,
+ 0x58, 0xb2, 0xc9, 0x43, 0x6f, 0x0d, 0xde, 0x7d,
+ 0xce, 0x31, 0x6a, 0x13, 0xfb, 0xd6, 0x84, 0xa3,
+ 0x69, 0x9b, 0x79, 0xdc, 0xeb, 0xad, 0x28, 0x5c,
+ 0xa5, 0xc8, 0x1b, 0xca, 0xd4, 0x7e, 0x56, 0x1e,
+ 0x58, 0xc3, 0x02, 0xcb, 0x44, 0x4d, 0xd7, 0x75,
+ 0xd5, 0x84, 0xae, 0x9b, 0xf9, 0xfa, 0x22, 0xf6,
+ 0x75, 0x45, 0xe3, 0xca, 0x92, 0x8d, 0xd5, 0x75,
+ 0x79, 0xc6, 0x28, 0x67, 0x4e, 0x0b, 0x2f, 0xb6,
+ 0xba, 0x02, 0x5f, 0x65, 0x10, 0x61, 0xdb, 0x92,
+ 0x45, 0x47, 0xe0, 0x0d, 0x19, 0x16, 0x5e, 0xb8,
+ 0x19, 0xc5, 0xed, 0x95, 0x20, 0x1e, 0x3d, 0xc6,
+ 0xfc, 0x47, 0xa7, 0x9c, 0xe1, 0xc0, 0xe1, 0xdd,
+ 0x4f, 0x8a, 0xfd, 0x56, 0x6c, 0x7e, 0x86, 0x30,
+ 0xa1, 0xa3, 0x87, 0xf2, 0x5e, 0x6c, 0x05, 0x01,
+ 0xef, 0x9a, 0x85, 0xfa, 0xa6, 0x96, 0xe2, 0x94,
+ 0xaf, 0xa0, 0x35, 0xc4, 0x8e, 0xf2, 0xda, 0xd0,
+ 0x58, 0x76, 0xca, 0xbf, 0x4e, 0x9c, 0x54, 0x51,
+ 0xf6, 0x45, 0x35, 0x1f, 0x87, 0x55, 0x52, 0x87,
+ 0xb5, 0xe8, 0x76, 0x6d, 0x58, 0x8b, 0xaa, 0xec,
+ 0x0d, 0x8e, 0x65, 0xae, 0x20, 0x9f, 0xe8, 0xdb,
+ 0xeb, 0x02, 0x1c, 0x9b, 0x20, 0xe8, 0xd3, 0x06,
+ 0xa6, 0xa2, 0x38, 0x5e, 0xb4, 0x96, 0xaa, 0x23,
+ 0x19, 0xb4, 0x3f, 0x4e, 0x73, 0xa4, 0x37, 0x56,
+ 0xbb, 0x6c, 0x74, 0x3e, 0xd7, 0x47, 0x33, 0xfe,
+ 0xdb, 0xb7, 0xa5, 0x1a, 0x4d, 0x68, 0xb6, 0xe4,
+ 0x62, 0x44, 0x0f, 0xf9, 0xa1, 0xe5, 0xaa, 0x05,
+ 0x6e, 0xd6, 0x4b, 0x23, 0x77, 0x42, 0x3b, 0xbb,
+ 0x1a, 0x9c, 0x99, 0x64, 0x11, 0xc0, 0x6c, 0x30,
+ 0x8e, 0x7c, 0x8a, 0xe9, 0x97, 0x0a, 0x02, 0x2b,
+ 0xa3, 0x59, 0x40, 0x62, 0xe9, 0x5d, 0xb4, 0x68,
+ 0x2c, 0x68, 0x82, 0xc7, 0xec, 0x6f, 0x2e, 0x78,
+ 0x38, 0x1d, 0x9f, 0xd8, 0xdd, 0x17, 0xf2, 0xd0,
+ 0xdb, 0xa6, 0x27, 0x69, 0x12, 0x39, 0xf9, 0x64,
+ 0x31, 0x0a, 0x6f, 0x2e, 0x2d, 0xde, 0xe2, 0x0b,
+ 0x4e, 0x5b, 0xda, 0x97, 0x57, 0x1c, 0xaa, 0xd1,
+ 0x5e, 0x09, 0x9d, 0x2b, 0xf2, 0x46, 0xcb, 0xdf,
+ 0xe5, 0xbd, 0x43, 0x5b, 0x3d, 0x1e, 0xfa, 0xc2,
+ 0xb5, 0x61, 0x69, 0x2e, 0xe1, 0x03, 0x74, 0xa6,
+ 0xe4, 0x5a, 0x5c, 0x57, 0x37, 0x37, 0x5c, 0x7e,
+ 0xb9, 0xa2, 0xbb, 0x2d, 0x9d, 0xbd, 0x8b, 0xd3,
+ 0xef, 0x28, 0xbd, 0x13, 0x0d, 0xc2, 0xff, 0x8b,
+ 0x33, 0xd8, 0x09, 0x01, 0xdc, 0x1f, 0x5d, 0x84,
+ 0x42, 0x4f, 0x5e, 0xbe, 0x47, 0xcf, 0x36, 0x29,
+ 0xac, 0x65, 0x4a, 0xf6, 0x44, 0xe5, 0x14, 0x8e,
+ 0x76, 0xcc, 0xdb, 0x39, 0xd5, 0xb5, 0xb2, 0x64,
+ 0x9d, 0x4e, 0x8c, 0xba, 0xcb, 0x89, 0x3b, 0xfd,
+ 0x30, 0x46, 0x14, 0xa2, 0x4b, 0xf8, 0x8f, 0xb2,
+ 0x65, 0xe3, 0x33, 0x49, 0x3e, 0xe0, 0x8e, 0x39,
+ 0x1b, 0x18, 0x7d, 0x05, 0xdc, 0x8a, 0x08, 0x88,
+ 0x00, 0x8b, 0xe8, 0xd1, 0x22, 0xdd, 0x08, 0xe0,
+ 0xfb, 0xc3, 0x75, 0x4a, 0x86, 0x49, 0x29, 0x47,
+ 0x5a, 0x28, 0x16, 0xd5, 0xed, 0xec, 0x18, 0xcb,
+ 0xde, 0x12, 0x89, 0x10, 0xb4, 0x16, 0xbd, 0xda,
+ 0xfc, 0x1f, 0x10, 0x1c, 0xce, 0x40, 0x61, 0xef,
+ 0x28, 0x10, 0xed, 0x0e, 0xd6, 0x13, 0x56, 0x3d,
+ 0x7a, 0xc8, 0x59, 0xae, 0x27, 0xde, 0xed, 0x4c,
+ 0x0f, 0xca, 0xf4, 0x50, 0x7b, 0xf9, 0x1f, 0x46,
+ 0x51, 0xd3, 0x43, 0x19, 0x53, 0xde, 0xf0, 0x5a,
+ 0xc6, 0x54, 0xaa, 0x7c, 0x32, 0x63, 0x17, 0x37,
+ 0x78, 0x76, 0xb8, 0xd5, 0x1a, 0x5d, 0x16, 0x16,
+ 0x5e, 0x94, 0x34, 0x61, 0x6d, 0xca, 0x1b, 0xb0,
+ 0x36, 0x95, 0x2a, 0xb1, 0xb6, 0x8b, 0x1b, 0xb0,
+ 0x76, 0xab, 0x7d, 0x01, 0x6f, 0x6b, 0x68, 0x40,
+ 0x0d, 0x8f, 0x33, 0x4c, 0x79, 0x3d, 0xae, 0xa6,
+ 0x4e, 0x25, 0xba, 0x76, 0x71, 0x03, 0xc6, 0x6e,
+ 0xb5, 0xab, 0x91, 0xae, 0x7f, 0x52, 0xa5, 0x8b,
+ 0xaf, 0x40, 0xb9, 0xf6, 0x71, 0x95, 0x55, 0x7a,
+ 0x15, 0xc2, 0x05, 0x0f, 0xa2, 0x87, 0x67, 0x9e,
+ 0xba, 0x27, 0xa3, 0xe2, 0xb5, 0x8d, 0x9c, 0xd5,
+ 0x56, 0xc8, 0x6d, 0x6d, 0x69, 0x78, 0x3a, 0xbb,
+ 0x77, 0x80, 0xfb, 0xf2, 0xeb, 0xf0, 0x3a, 0x56,
+ 0x34, 0x8b, 0x1f, 0x92, 0x7c, 0xaa, 0xff, 0xac,
+ 0x7c, 0xdc, 0x63, 0x8a, 0x3b, 0x05, 0x5e, 0x59,
+ 0xf7, 0xcc, 0xc7, 0x05, 0x58, 0xc9, 0xf3, 0x1a,
+ 0xb0, 0xb3, 0xf8, 0x1e, 0xc1, 0xd5, 0x7f, 0x56,
+ 0x62, 0x67, 0x8a, 0x3b, 0x05, 0x9e, 0x58, 0x87,
+ 0x9d, 0x0b, 0xb0, 0x92, 0xb7, 0x7d, 0x26, 0x8f,
+ 0x82, 0x2c, 0x2e, 0xa6, 0x67, 0xaa, 0xfe, 0x75,
+ 0x89, 0x29, 0xee, 0x14, 0x38, 0x5c, 0x1d, 0x5e,
+ 0x2e, 0xc0, 0x4a, 0x56, 0x75, 0x15, 0x76, 0xda,
+ 0x5b, 0x4d, 0xff, 0x55, 0x8f, 0x9b, 0x7a, 0xc7,
+ 0x65, 0x31, 0xb2, 0x46, 0xcc, 0xb4, 0xd7, 0x5b,
+ 0x15, 0x4b, 0xfa, 0x4c, 0xed, 0xb6, 0x45, 0xb3,
+ 0xed, 0xce, 0x6e, 0xfb, 0x27, 0xb3, 0xdb, 0xbe,
+ 0x92, 0xb1, 0x5d, 0xf0, 0xac, 0x44, 0x91, 0x57,
+ 0x9a, 0x17, 0x4d, 0xc6, 0xd5, 0x25, 0xbe, 0x6d,
+ 0x8a, 0xbc, 0xcb, 0x64, 0x4d, 0xaf, 0x3b, 0xa6,
+ 0x89, 0x72, 0x5f, 0xe4, 0x7a, 0x19, 0x6c, 0xad,
+ 0xa0, 0x63, 0xa5, 0x1c, 0x9d, 0x2c, 0x28, 0xb7,
+ 0x68, 0xc6, 0x20, 0xb5, 0xe3, 0x90, 0xc6, 0x45,
+ 0xc5, 0x09, 0x48, 0x83, 0x88, 0xdf, 0x18, 0x81,
+ 0x64, 0xaf, 0x33, 0x21, 0x13, 0x34, 0xfb, 0x89,
+ 0x08, 0x25, 0x56, 0x0e, 0xd0, 0x81, 0x09, 0x9d,
+ 0x31, 0x64, 0x28, 0x1a, 0xf4, 0xc6, 0xe7, 0xd4,
+ 0xa7, 0xfe, 0xa5, 0x4e, 0xc0, 0x8a, 0x07, 0x94,
+ 0x7c, 0x0f, 0x63, 0x3b, 0xc6, 0xd3, 0x01, 0xda,
+ 0xab, 0x19, 0x2d, 0x86, 0x89, 0xa9, 0x1e, 0x30,
+ 0x45, 0x91, 0xd1, 0xc3, 0x8e, 0x0b, 0x18, 0x5e,
+ 0x67, 0xbc, 0x91, 0x97, 0xce, 0x0b, 0xc3, 0xc5,
+ 0x72, 0x49, 0x4a, 0xa0, 0xa9, 0xd0, 0xfb, 0x14,
+ 0xcb, 0x11, 0x73, 0xd9, 0xdb, 0x6e, 0xe0, 0x94,
+ 0x17, 0xfd, 0xea, 0x51, 0xff, 0x39, 0x4c, 0xee,
+ 0xdb, 0x98, 0xdb, 0x6f, 0xdf, 0xd4, 0xfe, 0x19,
+ 0x99, 0xd9, 0x99, 0xa5, 0x48, 0x1a, 0x25, 0x5a,
+ 0x7f, 0xac, 0x00, 0x75, 0xbd, 0x28, 0x9c, 0xc7,
+ 0x78, 0x56, 0x1c, 0x23, 0xf1, 0x3f, 0x26, 0xaf,
+ 0x3a, 0x58, 0x91, 0xf0, 0x03, 0x60, 0xeb, 0x45,
+ 0x5c, 0x1b, 0xf3, 0x99, 0x53, 0xb2, 0xe1, 0x84,
+ 0x5d, 0xec, 0xe8, 0xe5, 0x8a, 0xdd, 0xc1, 0x9b,
+ 0x04, 0xe4, 0xb0, 0x39, 0xea, 0xc7, 0xb8, 0x65,
+ 0x88, 0x56, 0xf9, 0xe4, 0x09, 0x63, 0xc3, 0x7d,
+ 0xe4, 0xf6, 0xa1, 0xed, 0x95, 0x7a, 0x1b, 0x0c,
+ 0x1b, 0xb2, 0xc0, 0x5d, 0x65, 0xf5, 0xa6, 0xdc,
+ 0x90, 0xb1, 0x17, 0x1b, 0xbe, 0x6c, 0x29, 0x41,
+ 0x89, 0x30, 0xe7, 0xe7, 0x93, 0xcb, 0xc0, 0xa3,
+ 0xb0, 0x4f, 0x80, 0x4d, 0x6d, 0x7f, 0xbd, 0xdd,
+ 0x15, 0xc2, 0xee, 0x0a, 0xe1, 0x8b, 0xbb, 0x42,
+ 0x30, 0x5c, 0xc5, 0x7d, 0x2d, 0xe6, 0x3c, 0x34,
+ 0xb3, 0x25, 0xca, 0xcf, 0xe2, 0xb2, 0x41, 0x3d,
+ 0xe2, 0xd5, 0xa6, 0xbe, 0xe9, 0x2d, 0xdc, 0x3e,
+ 0xc8, 0x6b, 0x0c, 0x52, 0x67, 0xd5, 0xe3, 0x30,
+ 0x7c, 0x17, 0x7b, 0x41, 0xa1, 0xb9, 0x4c, 0x3c,
+ 0x32, 0x56, 0x6d, 0x95, 0x1f, 0x9b, 0x35, 0xad,
+ 0x1d, 0xc1, 0xa1, 0xc0, 0x6a, 0xf1, 0xe2, 0x2b,
+ 0x0e, 0x15, 0xdf, 0xe8, 0xec, 0xbb, 0xef, 0xc7,
+ 0xaf, 0xff, 0x29, 0x8e, 0xac, 0xd0, 0x51, 0x2f,
+ 0xbf, 0xfb, 0xe1, 0xe5, 0xf8, 0x87, 0x17, 0x7f,
+ 0xff, 0xfb, 0x0b, 0x98, 0x8c, 0xe1, 0xe0, 0xb0,
+ 0x5f, 0x7e, 0xfb, 0x50, 0x65, 0x7c, 0x40, 0x55,
+ 0xe3, 0x64, 0x0b, 0x3b, 0xe3, 0x7d, 0x5b, 0x08,
+ 0xef, 0xd5, 0xb6, 0x77, 0x7f, 0xc6, 0xb9, 0x7b,
+ 0xb6, 0xab, 0xdd, 0x89, 0x51, 0xac, 0xf2, 0x7e,
+ 0xad, 0xda, 0x80, 0xe4, 0xbc, 0xb3, 0xa9, 0xb3,
+ 0x7c, 0xdd, 0x86, 0x51, 0xe8, 0x4a, 0x9b, 0xd0,
+ 0xcd, 0xac, 0x39, 0x57, 0x1b, 0x73, 0x6e, 0x64,
+ 0x86, 0xb9, 0xeb, 0xf7, 0x6b, 0x05, 0x3b, 0xca,
+ 0xcd, 0x2c, 0x20, 0x57, 0x19, 0x40, 0x6e, 0x66,
+ 0xbd, 0xe0, 0x33, 0x42, 0x2e, 0xb2, 0x36, 0x3a,
+ 0x54, 0x1d, 0x33, 0x72, 0xc9, 0x7b, 0x17, 0x45,
+ 0x23, 0x82, 0x55, 0x76, 0x59, 0x3a, 0x23, 0xcc,
+ 0x8c, 0xc9, 0x3a, 0x45, 0xef, 0xb1, 0x6b, 0x4b,
+ 0xc8, 0xca, 0xde, 0x6c, 0x3c, 0xd4, 0x6d, 0x8a,
+ 0x29, 0xca, 0x26, 0xfc, 0x12, 0xea, 0xd4, 0x66,
+ 0xc7, 0x7d, 0xd1, 0x32, 0x9d, 0xee, 0xb9, 0xbb,
+ 0x42, 0x1e, 0x0c, 0xf6, 0xd3, 0xc7, 0xf5, 0x6c,
+ 0x86, 0x9e, 0xd8, 0xa3, 0xc3, 0xa7, 0xf4, 0x60,
+ 0x9f, 0xe3, 0x8a, 0x00, 0x62, 0xf8, 0xb7, 0x2d,
+ 0x8c, 0x4b, 0xe6, 0x5d, 0xf2, 0xba, 0x87, 0xc6,
+ 0x36, 0xed, 0xa9, 0x32, 0x85, 0x58, 0xcb, 0x2c,
+ 0xd6, 0x1e, 0x1c, 0xf4, 0xc3, 0xe7, 0x00, 0x5b,
+ 0x1e, 0x27, 0x4f, 0x2c, 0xac, 0xdb, 0xdb, 0xa0,
+ 0x4d, 0x51, 0x8c, 0x24, 0xbe, 0x8c, 0xad, 0x45,
+ 0x5f, 0x7d, 0x4b, 0xae, 0xd0, 0x7d, 0x38, 0x52,
+ 0xa1, 0x35, 0x6a, 0xf9, 0x56, 0xad, 0xf2, 0xa2,
+ 0x19, 0xaf, 0x99, 0xd5, 0x7b, 0x81, 0xd2, 0x54,
+ 0x33, 0x3e, 0x53, 0x0a, 0xa5, 0x81, 0x03, 0xdc,
+ 0x13, 0xa5, 0xb7, 0x7d, 0x8e, 0xe8, 0x28, 0xaf,
+ 0xbf, 0xad, 0x57, 0x6e, 0x34, 0x80, 0xae, 0x03,
+ 0xad, 0xc3, 0xa3, 0x7a, 0x52, 0xf8, 0x78, 0x83,
+ 0xe7, 0x6c, 0x28, 0x5d, 0xb9, 0xa7, 0xf8, 0x2d,
+ 0x5c, 0x93, 0xff, 0x7f, 0xc9, 0x73, 0xe5, 0xd5
+ };
+ static std::string decompressed = util::decompress(std::string(reinterpret_cast<const char*>(compressed), sizeof(compressed)));
+ return decompressed.c_str();
+};
+
+} // namespace shaders
+} // namespace mbgl
diff --git a/src/mbgl/shaders/source.hpp b/src/mbgl/shaders/source.hpp
new file mode 100644
index 0000000000..38a5ea6ece
--- /dev/null
+++ b/src/mbgl/shaders/source.hpp
@@ -0,0 +1,11 @@
+// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
+
+#pragma once
+
+namespace mbgl {
+namespace shaders {
+
+const char* source();
+
+} // namespace shaders
+} // namespace mbgl
diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp
index c037c81005..9e33b99def 100644
--- a/src/mbgl/shaders/symbol_icon.cpp
+++ b/src/mbgl/shaders/symbol_icon.cpp
@@ -1,149 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/symbol_icon.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* symbol_icon::name = "symbol_icon";
-const char* symbol_icon::vertexSource = R"MBGL_SHADER(
-const float PI = 3.141592653589793;
-
-attribute vec4 a_pos_offset;
-attribute vec4 a_data;
-attribute vec3 a_projected_pos;
-attribute float a_fade_opacity;
-
-uniform bool u_is_size_zoom_constant;
-uniform bool u_is_size_feature_constant;
-uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function
-uniform highp float u_size; // used when size is both zoom and feature constant
-uniform highp float u_camera_to_center_distance;
-uniform highp float u_pitch;
-uniform bool u_rotate_symbol;
-uniform highp float u_aspect_ratio;
-uniform float u_fade_change;
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-uniform mat4 u_matrix;
-uniform mat4 u_label_plane_matrix;
-uniform mat4 u_gl_coord_matrix;
-
-uniform bool u_is_text;
-uniform bool u_pitch_with_map;
-
-uniform vec2 u_texsize;
-
-varying vec2 v_tex;
-varying float v_fade_opacity;
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
- vec2 a_pos = a_pos_offset.xy;
- vec2 a_offset = a_pos_offset.zw;
-
- vec2 a_tex = a_data.xy;
- vec2 a_size = a_data.zw;
-
- highp float segment_angle = -a_projected_pos[2];
-
- float size;
- if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {
- size = mix(a_size[0], a_size[1], u_size_t) / 10.0;
- } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {
- size = a_size[0] / 10.0;
- } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {
- size = u_size;
- } else {
- size = u_size;
- }
-
- vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1);
- highp float camera_to_anchor_distance = projectedPoint.w;
- // See comments in symbol_sdf.vertex
- highp float distance_ratio = u_pitch_with_map ?
- camera_to_anchor_distance / u_camera_to_center_distance :
- u_camera_to_center_distance / camera_to_anchor_distance;
- highp float perspective_ratio = clamp(
- 0.5 + 0.5 * distance_ratio,
- 0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles
- 4.0);
-
- size *= perspective_ratio;
-
- float fontScale = u_is_text ? size / 24.0 : size;
-
- highp float symbol_rotation = 0.0;
- if (u_rotate_symbol) {
- // See comments in symbol_sdf.vertex
- vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);
-
- vec2 a = projectedPoint.xy / projectedPoint.w;
- vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w;
-
- symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);
- }
-
- highp float angle_sin = sin(segment_angle + symbol_rotation);
- highp float angle_cos = cos(segment_angle + symbol_rotation);
- mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
-
- vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);
- gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0);
-
- v_tex = a_tex / u_texsize;
- vec2 fade_opacity = unpack_opacity(a_fade_opacity);
- float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;
- v_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change));
-}
-
-)MBGL_SHADER";
-const char* symbol_icon::fragmentSource = R"MBGL_SHADER(
-uniform sampler2D u_texture;
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-varying vec2 v_tex;
-varying float v_fade_opacity;
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
- lowp float alpha = opacity * v_fade_opacity;
- gl_FragColor = texture2D(u_texture, v_tex) * alpha;
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* symbol_icon::vertexSource = source() + 59607;
+const char* symbol_icon::fragmentSource = source() + 63011;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp
index b584c00315..3443b4f21c 100644
--- a/src/mbgl/shaders/symbol_sdf.cpp
+++ b/src/mbgl/shaders/symbol_sdf.cpp
@@ -1,304 +1,14 @@
// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.
#include <mbgl/shaders/symbol_sdf.hpp>
+#include <mbgl/shaders/source.hpp>
namespace mbgl {
namespace shaders {
const char* symbol_sdf::name = "symbol_sdf";
-const char* symbol_sdf::vertexSource = R"MBGL_SHADER(
-const float PI = 3.141592653589793;
-
-attribute vec4 a_pos_offset;
-attribute vec4 a_data;
-attribute vec3 a_projected_pos;
-attribute float a_fade_opacity;
-
-// contents of a_size vary based on the type of property value
-// used for {text,icon}-size.
-// For constants, a_size is disabled.
-// For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature.
-// For composite functions:
-// [ text-size(lowerZoomStop, feature),
-// text-size(upperZoomStop, feature) ]
-uniform bool u_is_size_zoom_constant;
-uniform bool u_is_size_feature_constant;
-uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function
-uniform highp float u_size; // used when size is both zoom and feature constant
-
-
-#ifndef HAS_UNIFORM_u_fill_color
-uniform lowp float a_fill_color_t;
-attribute highp vec4 a_fill_color;
-varying highp vec4 fill_color;
-#else
-uniform highp vec4 u_fill_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_color
-uniform lowp float a_halo_color_t;
-attribute highp vec4 a_halo_color;
-varying highp vec4 halo_color;
-#else
-uniform highp vec4 u_halo_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-uniform lowp float a_opacity_t;
-attribute lowp vec2 a_opacity;
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_width
-uniform lowp float a_halo_width_t;
-attribute lowp vec2 a_halo_width;
-varying lowp float halo_width;
-#else
-uniform lowp float u_halo_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_blur
-uniform lowp float a_halo_blur_t;
-attribute lowp vec2 a_halo_blur;
-varying lowp float halo_blur;
-#else
-uniform lowp float u_halo_blur;
-#endif
-
-
-uniform mat4 u_matrix;
-uniform mat4 u_label_plane_matrix;
-uniform mat4 u_gl_coord_matrix;
-
-uniform bool u_is_text;
-uniform bool u_pitch_with_map;
-uniform highp float u_pitch;
-uniform bool u_rotate_symbol;
-uniform highp float u_aspect_ratio;
-uniform highp float u_camera_to_center_distance;
-uniform float u_fade_change;
-
-uniform vec2 u_texsize;
-
-varying vec2 v_data0;
-varying vec3 v_data1;
-
-void main() {
-
-#ifndef HAS_UNIFORM_u_fill_color
- fill_color = unpack_mix_vec4(a_fill_color, a_fill_color_t);
-#else
- highp vec4 fill_color = u_fill_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_color
- halo_color = unpack_mix_vec4(a_halo_color, a_halo_color_t);
-#else
- highp vec4 halo_color = u_halo_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
- opacity = unpack_mix_vec2(a_opacity, a_opacity_t);
-#else
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_width
- halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t);
-#else
- lowp float halo_width = u_halo_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_blur
- halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t);
-#else
- lowp float halo_blur = u_halo_blur;
-#endif
-
-
- vec2 a_pos = a_pos_offset.xy;
- vec2 a_offset = a_pos_offset.zw;
-
- vec2 a_tex = a_data.xy;
- vec2 a_size = a_data.zw;
-
- highp float segment_angle = -a_projected_pos[2];
- float size;
-
- if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {
- size = mix(a_size[0], a_size[1], u_size_t) / 10.0;
- } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {
- size = a_size[0] / 10.0;
- } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {
- size = u_size;
- } else {
- size = u_size;
- }
-
- vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1);
- highp float camera_to_anchor_distance = projectedPoint.w;
- // If the label is pitched with the map, layout is done in pitched space,
- // which makes labels in the distance smaller relative to viewport space.
- // We counteract part of that effect by multiplying by the perspective ratio.
- // If the label isn't pitched with the map, we do layout in viewport space,
- // which makes labels in the distance larger relative to the features around
- // them. We counteract part of that effect by dividing by the perspective ratio.
- highp float distance_ratio = u_pitch_with_map ?
- camera_to_anchor_distance / u_camera_to_center_distance :
- u_camera_to_center_distance / camera_to_anchor_distance;
- highp float perspective_ratio = clamp(
- 0.5 + 0.5 * distance_ratio,
- 0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles
- 4.0);
-
- size *= perspective_ratio;
-
- float fontScale = u_is_text ? size / 24.0 : size;
-
- highp float symbol_rotation = 0.0;
- if (u_rotate_symbol) {
- // Point labels with 'rotation-alignment: map' are horizontal with respect to tile units
- // To figure out that angle in projected space, we draw a short horizontal line in tile
- // space, project it, and measure its angle in projected space.
- vec4 offsetProjectedPoint = u_matrix * vec4(a_pos + vec2(1, 0), 0, 1);
-
- vec2 a = projectedPoint.xy / projectedPoint.w;
- vec2 b = offsetProjectedPoint.xy / offsetProjectedPoint.w;
-
- symbol_rotation = atan((b.y - a.y) / u_aspect_ratio, b.x - a.x);
- }
-
- highp float angle_sin = sin(segment_angle + symbol_rotation);
- highp float angle_cos = cos(segment_angle + symbol_rotation);
- mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
-
- vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);
- gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0);
- float gamma_scale = gl_Position.w;
-
- vec2 tex = a_tex / u_texsize;
- vec2 fade_opacity = unpack_opacity(a_fade_opacity);
- float fade_change = fade_opacity[1] > 0.5 ? u_fade_change : -u_fade_change;
- float interpolated_fade_opacity = max(0.0, min(1.0, fade_opacity[0] + fade_change));
-
- v_data0 = vec2(tex.x, tex.y);
- v_data1 = vec3(gamma_scale, size, interpolated_fade_opacity);
-}
-
-)MBGL_SHADER";
-const char* symbol_sdf::fragmentSource = R"MBGL_SHADER(
-#define SDF_PX 8.0
-#define EDGE_GAMMA 0.105/DEVICE_PIXEL_RATIO
-
-uniform bool u_is_halo;
-
-#ifndef HAS_UNIFORM_u_fill_color
-varying highp vec4 fill_color;
-#else
-uniform highp vec4 u_fill_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_color
-varying highp vec4 halo_color;
-#else
-uniform highp vec4 u_halo_color;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_opacity
-varying lowp float opacity;
-#else
-uniform lowp float u_opacity;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_width
-varying lowp float halo_width;
-#else
-uniform lowp float u_halo_width;
-#endif
-
-
-#ifndef HAS_UNIFORM_u_halo_blur
-varying lowp float halo_blur;
-#else
-uniform lowp float u_halo_blur;
-#endif
-
-
-uniform sampler2D u_texture;
-uniform highp float u_gamma_scale;
-uniform bool u_is_text;
-
-varying vec2 v_data0;
-varying vec3 v_data1;
-
-void main() {
-
-#ifdef HAS_UNIFORM_u_fill_color
- highp vec4 fill_color = u_fill_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_halo_color
- highp vec4 halo_color = u_halo_color;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_opacity
- lowp float opacity = u_opacity;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_halo_width
- lowp float halo_width = u_halo_width;
-#endif
-
-
-#ifdef HAS_UNIFORM_u_halo_blur
- lowp float halo_blur = u_halo_blur;
-#endif
-
-
- vec2 tex = v_data0.xy;
- float gamma_scale = v_data1.x;
- float size = v_data1.y;
- float fade_opacity = v_data1[2];
-
- float fontScale = u_is_text ? size / 24.0 : size;
-
- lowp vec4 color = fill_color;
- highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale);
- lowp float buff = (256.0 - 64.0) / 256.0;
- if (u_is_halo) {
- color = halo_color;
- gamma = (halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (fontScale * u_gamma_scale);
- buff = (6.0 - halo_width / fontScale) / SDF_PX;
- }
-
- lowp float dist = texture2D(u_texture, tex).a;
- highp float gamma_scaled = gamma * gamma_scale;
- highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
-
- gl_FragColor = color * (alpha * opacity * fade_opacity);
-
-#ifdef OVERDRAW_INSPECTOR
- gl_FragColor = vec4(1.0);
-#endif
-}
-
-)MBGL_SHADER";
+const char* symbol_sdf::vertexSource = source() + 63461;
+const char* symbol_sdf::fragmentSource = source() + 69382;
} // namespace shaders
} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp
index 93d6dfd9ae..df4fe6e8df 100644
--- a/src/mbgl/sprite/sprite_loader.cpp
+++ b/src/mbgl/sprite/sprite_loader.cpp
@@ -86,7 +86,7 @@ void SpriteLoader::emitSpriteLoadedIfComplete() {
return;
}
- loader->worker.invoke(&SpriteLoaderWorker::parse, loader->image, loader->json);
+ loader->worker.self().invoke(&SpriteLoaderWorker::parse, loader->image, loader->json);
}
void SpriteLoader::onParsed(std::vector<std::unique_ptr<style::Image>>&& result) {
diff --git a/src/mbgl/storage/resource.cpp b/src/mbgl/storage/resource.cpp
index 207dd2ee69..c51db44548 100644
--- a/src/mbgl/storage/resource.cpp
+++ b/src/mbgl/storage/resource.cpp
@@ -21,7 +21,7 @@ static std::string getQuadKey(int32_t x, int32_t y, int8_t z) {
}
static mapbox::geometry::point<double> getMercCoord(int32_t x, int32_t y, int8_t z) {
- double resolution = (util::M2PI * util::EARTH_RADIUS_M / 256) / std::pow(2.0f, z);
+ double resolution = (util::M2PI * util::EARTH_RADIUS_M / 256) / std::pow(2, z);
return {
x * resolution - util::M2PI * util::EARTH_RADIUS_M / 2,
y * resolution - util::M2PI * util::EARTH_RADIUS_M / 2,
@@ -30,7 +30,7 @@ static mapbox::geometry::point<double> getMercCoord(int32_t x, int32_t y, int8_t
static std::string getTileBBox(int32_t x, int32_t y, int8_t z) {
// Alter the y for the Google/OSM tile scheme.
- y = std::pow(2.0f, z) - y - 1;
+ y = std::pow(2, z) - y - 1;
auto min = getMercCoord(x * 256, y * 256, z);
auto max = getMercCoord((x + 1) * 256, (y + 1) * 256, z);
@@ -79,13 +79,13 @@ Resource Resource::spriteJSON(const std::string& base, float pixelRatio) {
Resource Resource::glyphs(const std::string& urlTemplate, const FontStack& fontStack, const std::pair<uint16_t, uint16_t>& glyphRange) {
return Resource {
Resource::Kind::Glyphs,
- util::replaceTokens(urlTemplate, [&](const std::string& token) {
+ util::replaceTokens(urlTemplate, [&](const std::string& token) -> optional<std::string> {
if (token == "fontstack") {
return util::percentEncode(fontStackToString(fontStack));
} else if (token == "range") {
return util::toString(glyphRange.first) + "-" + util::toString(glyphRange.second);
} else {
- return std::string();
+ return {};
}
})
};
@@ -104,7 +104,7 @@ Resource Resource::tile(const std::string& urlTemplate,
}
return Resource {
Resource::Kind::Tile,
- util::replaceTokens(urlTemplate, [&](const std::string& token) {
+ util::replaceTokens(urlTemplate, [&](const std::string& token) -> optional<std::string> {
if (token == "z") {
return util::toString(z);
} else if (token == "x") {
@@ -123,7 +123,7 @@ Resource Resource::tile(const std::string& urlTemplate,
} else if (token == "ratio") {
return std::string(pixelRatio > 1.0 ? "@2x" : "");
} else {
- return std::string();
+ return {};
}
}),
Resource::TileData {
diff --git a/src/mbgl/style/conversion/filter.cpp b/src/mbgl/style/conversion/filter.cpp
index 3c941945fd..b690c96388 100644
--- a/src/mbgl/style/conversion/filter.cpp
+++ b/src/mbgl/style/conversion/filter.cpp
@@ -1,17 +1,43 @@
#include <mbgl/style/conversion/filter.hpp>
+#include <mbgl/style/expression/literal.hpp>
#include <mbgl/util/geometry.hpp>
#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/expression/type.hpp>
-#include <mbgl/style/expression/parsing_context.hpp>
+#include <mbgl/style/expression/compound_expression.hpp>
+#include <mbgl/style/expression/boolean_operator.hpp>
namespace mbgl {
namespace style {
namespace conversion {
-using GeometryValue = mapbox::geometry::value;
+using namespace mbgl::style::expression;
+
+static bool isExpression(const Convertible& filter);
+ParseResult convertLegacyFilter(const Convertible& values, Error& error);
+optional<mbgl::Value> serializeLegacyFilter(const Convertible& values);
+
+optional<Filter> Converter<Filter>::operator()(const Convertible& value, Error& error) const {
+ if (isExpression(value)) {
+ ParsingContext parsingContext(type::Boolean);
+ ParseResult parseResult = parsingContext.parseExpression(value);
+ if (!parseResult) {
+ error = { parsingContext.getCombinedErrors() };
+ return {};
+ } else {
+ return { Filter(std::move(parseResult)) };
+ }
+ } else {
+ ParseResult expression = convertLegacyFilter(value, error);
+ if (!expression) {
+ assert(error.message.size() > 0);
+ return {};
+ }
+ return Filter(optional<std::unique_ptr<Expression>>(std::move(*expression)), serializeLegacyFilter(value));
+ }
+}
// This is a port from https://github.com/mapbox/mapbox-gl-js/blob/master/src/style-spec/feature_filter/index.js
-static bool isExpressionFilter(const Convertible& filter) {
+bool isExpression(const Convertible& filter) {
if (!isArray(filter) || arrayLength(filter) == 0) {
return false;
}
@@ -20,7 +46,7 @@ static bool isExpressionFilter(const Convertible& filter) {
if (!op) {
return false;
-
+
} else if (*op == "has") {
if (arrayLength(filter) < 2) return false;
optional<std::string> operand = toString(arrayMember(filter, 1));
@@ -30,12 +56,12 @@ static bool isExpressionFilter(const Convertible& filter) {
return false;
} else if (*op == "==" || *op == "!=" || *op == ">" || *op == ">=" || *op == "<" || *op == "<=") {
- return arrayLength(filter) == 3 && (isArray(arrayMember(filter, 1)) || isArray(arrayMember(filter, 2)));
+ return arrayLength(filter) != 3 || isArray(arrayMember(filter, 1)) || isArray(arrayMember(filter, 2));
} else if (*op == "any" || *op == "all") {
for (std::size_t i = 1; i < arrayLength(filter); i++) {
Convertible f = arrayMember(filter, i);
- if (!isExpressionFilter(f) && !toBool(f)) {
+ if (!isExpression(f) && !toBool(f)) {
return false;
}
}
@@ -46,257 +72,169 @@ static bool isExpressionFilter(const Convertible& filter) {
}
}
-static optional<GeometryValue> normalizeValue(const optional<GeometryValue>& value, Error& error) {
- if (!value) {
- error = { "filter expression value must be a boolean, number, or string" };
- return {};
+ParseResult createExpression(std::string op, optional<std::vector<std::unique_ptr<Expression>>> args, Error& error) {
+ if (!args) return {};
+ assert(std::all_of(args->begin(), args->end(), [](const std::unique_ptr<Expression> &e) {
+ return bool(e.get());
+ }));
+
+ if (op == "any") {
+ return {std::make_unique<Any>(std::move(*args))};
+ } else if (op == "all") {
+ return {std::make_unique<All>(std::move(*args))};
} else {
- return *value;
+ ParsingContext parsingContext(type::Boolean);
+ ParseResult parseResult = createCompoundExpression(op, std::move(*args), parsingContext);
+ if (!parseResult) {
+ error = { parsingContext.getCombinedErrors() };
+ return {};
+ } else {
+ return parseResult;
+ }
}
}
-static optional<FeatureType> toFeatureType(const Convertible& value, Error& error) {
- optional<std::string> type = toString(value);
- if (!type) {
- error = { "value for $type filter must be a string" };
- return {};
- } else if (*type == "Point") {
- return FeatureType::Point;
- } else if (*type == "LineString") {
- return FeatureType::LineString;
- } else if (*type == "Polygon") {
- return FeatureType::Polygon;
- } else {
- error = { "value for $type filter must be Point, LineString, or Polygon" };
+ParseResult createExpression(std::string op, ParseResult arg, Error& error) {
+ if (!arg) {
return {};
}
+
+ std::vector<std::unique_ptr<Expression>> args;
+ args.push_back(std::move(*arg));
+ return createExpression(op, std::move(args), error);
}
-static optional<FeatureIdentifier> toFeatureIdentifier(const Convertible& value, Error& error) {
- optional<GeometryValue> identifier = toValue(value);
- if (!identifier) {
- error = { "filter expression value must be a boolean, number, or string" };
- return {};
+ParseResult convertLiteral(const Convertible& convertible, Error& error) {
+ ParsingContext parsingContext;
+ ParseResult parseResult = Literal::parse(convertible, parsingContext);
+ if (parseResult) {
+ return parseResult;
} else {
- return (*identifier).match(
- [] (uint64_t t) -> optional<FeatureIdentifier> { return { t }; },
- [] ( int64_t t) -> optional<FeatureIdentifier> { return { t }; },
- [] ( double t) -> optional<FeatureIdentifier> { return { t }; },
- [] (const std::string& t) -> optional<FeatureIdentifier> { return { t }; },
- [&] (const auto&) -> optional<FeatureIdentifier> {
- error = { "filter expression value must be a boolean, number, or string" };
- return {};
- });
- }
-}
-
-template <class FilterType, class IdentifierFilterType>
-optional<Filter> convertUnaryFilter(const Convertible& value, Error& error) {
- if (arrayLength(value) < 2) {
- error = { "filter expression must have 2 elements" };
+ error = { parsingContext.getCombinedErrors() };
return {};
}
-
- optional<std::string> key = toString(arrayMember(value, 1));
- if (!key) {
- error = { "filter expression key must be a string" };
- return {};
- }
-
- if (*key == "$id") {
- return { IdentifierFilterType {} };
- } else {
- return { FilterType { *key } };
- }
}
-template <class FilterType, class TypeFilterType, class IdentifierFilterType>
-optional<Filter> convertEqualityFilter(const Convertible& value, Error& error) {
- if (arrayLength(value) < 3) {
- error = { "filter expression must have 3 elements" };
- return {};
- }
-
- optional<std::string> key = toString(arrayMember(value, 1));
- if (!key) {
- error = { "filter expression key must be a string" };
- return {};
- }
-
- if (*key == "$type") {
- optional<FeatureType> filterValue = toFeatureType(arrayMember(value, 2), error);
- if (!filterValue) {
+optional<std::vector<std::unique_ptr<Expression>>> convertLiteralArray(const Convertible &input, Error& error, std::size_t startIndex = 0) {
+ std::vector<std::unique_ptr<Expression>> output;
+ for (std::size_t i = startIndex; i < arrayLength(input); i++) {
+ ParseResult literal = convertLiteral(arrayMember(input, i), error);
+ if (!literal) {
return {};
}
-
- return { TypeFilterType { *filterValue } };
-
- } else if (*key == "$id") {
- optional<FeatureIdentifier> filterValue = toFeatureIdentifier(arrayMember(value, 2), error);
- if (!filterValue) {
- return {};
- }
-
- return { IdentifierFilterType { *filterValue } };
-
- } else {
- optional<GeometryValue> filterValue = normalizeValue(toValue(arrayMember(value, 2)), error);
- if (!filterValue) {
- return {};
- }
-
- return { FilterType { *key, *filterValue } };
+ output.push_back(std::move(*literal));
}
+ return {std::move(output)};
}
-template <class FilterType>
-optional<Filter> convertBinaryFilter(const Convertible& value, Error& error) {
- if (arrayLength(value) < 3) {
- error = { "filter expression must have 3 elements" };
- return {};
- }
-
- optional<std::string> key = toString(arrayMember(value, 1));
- if (!key) {
- error = { "filter expression key must be a string" };
- return {};
- }
-
- optional<GeometryValue> filterValue = normalizeValue(toValue(arrayMember(value, 2)), error);
- if (!filterValue) {
+ParseResult convertLegacyComparisonFilter(const Convertible& values, Error& error, optional<std::string> opOverride = {}) {
+ optional<std::string> op = opOverride ? opOverride : toString(arrayMember(values, 0));
+ optional<std::string> property = toString(arrayMember(values, 1));
+
+ if (!property) {
+ error = { "filter property must be a string" };
return {};
+ } else if (*property == "$type") {
+ return createExpression("filter-type-" + *op, convertLiteralArray(values, error, 2), error);
+ } else if (*property == "$id") {
+ return createExpression("filter-id-" + *op, convertLiteralArray(values, error, 2), error);
+ } else {
+ return createExpression("filter-" + *op, convertLiteralArray(values, error, 1), error);
}
-
- return { FilterType { *key, *filterValue } };
}
-
-template <class FilterType, class TypeFilterType, class IdentifierFilterType>
-optional<Filter> convertSetFilter(const Convertible& value, Error& error) {
- if (arrayLength(value) < 2) {
- error = { "filter expression must at least 2 elements" };
- return {};
- }
-
- optional<std::string> key = toString(arrayMember(value, 1));
- if (!key) {
- error = { "filter expression key must be a string" };
+
+ParseResult convertLegacyHasFilter(const Convertible& values, Error& error) {
+ optional<std::string> property = toString(arrayMember(values, 1));
+
+ if (!property) {
+ error = { "filter property must be a string" };
return {};
+ } else if (*property == "$type") {
+ return {std::make_unique<Literal>(true)};
+ } else if (*property == "$id") {
+ return createExpression("filter-has-id", std::vector<std::unique_ptr<Expression>>(), error);
+ } else {
+ return createExpression("filter-has", {std::make_unique<Literal>(*property)}, error);
}
+}
- if (*key == "$type") {
- std::vector<FeatureType> values;
- for (std::size_t i = 2; i < arrayLength(value); ++i) {
- optional<FeatureType> filterValue = toFeatureType(arrayMember(value, i), error);
- if (!filterValue) {
- return {};
- }
- values.push_back(*filterValue);
- }
-
- return { TypeFilterType { std::move(values) } };
-
- } else if (*key == "$id") {
- std::vector<FeatureIdentifier> values;
- for (std::size_t i = 2; i < arrayLength(value); ++i) {
- optional<FeatureIdentifier> filterValue = toFeatureIdentifier(arrayMember(value, i), error);
- if (!filterValue) {
- return {};
- }
- values.push_back(*filterValue);
- }
-
- return { IdentifierFilterType { std::move(values) } };
-
+ParseResult convertLegacyInFilter(const Convertible& values, Error& error) {
+ optional<std::string> property = toString(arrayMember(values, 1));
+
+ if (!property) {
+ error = { "filter property must be a string" };
+ return {};
+ } else if (arrayLength(values) == 0) {
+ return {std::make_unique<Literal>(false)};
+ } else if (*property == "$type") {
+ return createExpression("filter-type-in", convertLiteralArray(values, error, 2), error);
+ } else if (*property == "$id") {
+ return createExpression("filter-id-in", convertLiteralArray(values, error, 2), error);
} else {
- std::vector<GeometryValue> values;
- for (std::size_t i = 2; i < arrayLength(value); ++i) {
- optional<GeometryValue> filterValue = normalizeValue(toValue(arrayMember(value, i)), error);
- if (!filterValue) {
- return {};
- }
- values.push_back(*filterValue);
- }
-
- return { FilterType { *key, std::move(values) } };
+ return createExpression("filter-in", convertLiteralArray(values, error, 1), error);
}
}
-template <class FilterType>
-optional<Filter> convertCompoundFilter(const Convertible& value, Error& error) {
- std::vector<Filter> filters;
- for (std::size_t i = 1; i < arrayLength(value); ++i) {
- optional<Filter> element = convert<Filter>(arrayMember(value, i), error);
- if (!element) {
+optional<std::vector<std::unique_ptr<Expression>>> convertLegacyFilterArray(const Convertible &input, Error& error, std::size_t startIndex = 0) {
+ std::vector<std::unique_ptr<Expression>> output;
+ for (std::size_t i = startIndex; i < arrayLength(input); i++) {
+ optional<std::unique_ptr<Expression>> child = convertLegacyFilter(arrayMember(input, i), error);
+ if (!child) {
return {};
}
- filters.push_back(*element);
+ output.push_back(std::move(*child));
}
-
- return { FilterType { std::move(filters) } };
+ return {std::move(output)};
}
-optional<Filter> convertExpressionFilter(const Convertible& value, Error& error) {
- expression::ParsingContext ctx(expression::type::Boolean);
- expression::ParseResult expression = ctx.parseExpression(value);
- if (!expression) {
- error = { ctx.getCombinedErrors() };
- return {};
- }
-
- return { ExpressionFilter { std::move(*expression) } };
-}
-
-optional<Filter> Converter<Filter>::operator()(const Convertible& value, Error& error) const {
- if (isExpressionFilter(value)) {
- return convertExpressionFilter(value, error);
+ParseResult convertLegacyFilter(const Convertible& values, Error& error) {
+ if (isUndefined(values)) {
+ return {std::make_unique<Literal>(true)};
}
- if (!isArray(value)) {
- error = { "filter expression must be an array" };
- return {};
- }
-
- if (arrayLength(value) < 1) {
- error = { "filter expression must have at least 1 element" };
- return {};
- }
+ optional<std::string> op = toString(arrayMember(values, 0));
- optional<std::string> op = toString(arrayMember(value, 0));
if (!op) {
error = { "filter operator must be a string" };
return {};
+ } else if (arrayLength(values) <= 1) {
+ return {std::make_unique<Literal>(*op != "any")};
+ } else {
+ return {
+ *op == "==" ||
+ *op == "<" ||
+ *op == ">" ||
+ *op == "<=" ||
+ *op == ">=" ? convertLegacyComparisonFilter(values, error) :
+ *op == "!=" ? createExpression("!", convertLegacyComparisonFilter(values, error, {"=="}), error) :
+ *op == "any" ? createExpression("any", convertLegacyFilterArray(values, error, 1), error) :
+ *op == "all" ? createExpression("all", convertLegacyFilterArray(values, error, 1), error) :
+ *op == "none" ? createExpression("!", createExpression("any", convertLegacyFilterArray(values, error, 1), error), error) :
+ *op == "in" ? convertLegacyInFilter(values, error) :
+ *op == "!in" ? createExpression("!", convertLegacyInFilter(values, error), error) :
+ *op == "has" ? convertLegacyHasFilter(values, error) :
+ *op == "!has" ? createExpression("!", convertLegacyHasFilter(values, error), error) :
+ ParseResult(std::make_unique<Literal>(true))
+ };
}
+}
- if (*op == "==") {
- return convertEqualityFilter<EqualsFilter, TypeEqualsFilter, IdentifierEqualsFilter>(value, error);
- } else if (*op == "!=") {
- return convertEqualityFilter<NotEqualsFilter, TypeNotEqualsFilter, IdentifierNotEqualsFilter>(value, error);
- } else if (*op == ">") {
- return convertBinaryFilter<GreaterThanFilter>(value, error);
- } else if (*op == ">=") {
- return convertBinaryFilter<GreaterThanEqualsFilter>(value, error);
- } else if (*op == "<") {
- return convertBinaryFilter<LessThanFilter>(value, error);
- } else if (*op == "<=") {
- return convertBinaryFilter<LessThanEqualsFilter>(value, error);
- } else if (*op == "in") {
- return convertSetFilter<InFilter, TypeInFilter, IdentifierInFilter>(value, error);
- } else if (*op == "!in") {
- return convertSetFilter<NotInFilter, TypeNotInFilter, IdentifierNotInFilter>(value, error);
- } else if (*op == "all") {
- return convertCompoundFilter<AllFilter>(value, error);
- } else if (*op == "any") {
- return convertCompoundFilter<AnyFilter>(value, error);
- } else if (*op == "none") {
- return convertCompoundFilter<NoneFilter>(value, error);
- } else if (*op == "has") {
- return convertUnaryFilter<HasFilter, HasIdentifierFilter>(value, error);
- } else if (*op == "!has") {
- return convertUnaryFilter<NotHasFilter, NotHasIdentifierFilter>(value, error);
+optional<mbgl::Value> serializeLegacyFilter(const Convertible& values) {
+ if (isUndefined(values)) {
+ return {};
+ } else if (isArray(values)) {
+ std::vector<mbgl::Value> result;
+ for (std::size_t i = 0; i < arrayLength(values); i++) {
+ auto arrayValue = serializeLegacyFilter(arrayMember(values, i));
+ if (arrayValue) {
+ result.push_back(*arrayValue);
+ } else {
+ result.push_back(NullValue());
+ }
+ }
+ return (mbgl::Value)result;
}
-
- error = { R"(filter operator must be one of "==", "!=", ">", ">=", "<", "<=", "in", "!in", "all", "any", "none", "has", or "!has")" };
- return {};
+ return toValue(values);
}
} // namespace conversion
diff --git a/src/mbgl/style/conversion/function.cpp b/src/mbgl/style/conversion/function.cpp
new file mode 100644
index 0000000000..61b45fcbe5
--- /dev/null
+++ b/src/mbgl/style/conversion/function.cpp
@@ -0,0 +1,724 @@
+#include <mbgl/style/conversion/function.hpp>
+#include <mbgl/style/expression/dsl.hpp>
+#include <mbgl/style/expression/step.hpp>
+#include <mbgl/style/expression/interpolate.hpp>
+#include <mbgl/style/expression/match.hpp>
+#include <mbgl/style/expression/case.hpp>
+#include <mbgl/style/expression/array_assertion.hpp>
+#include <mbgl/util/string.hpp>
+
+#include <cassert>
+
+namespace mbgl {
+namespace style {
+namespace conversion {
+
+using namespace expression;
+using namespace expression::dsl;
+
+const static std::string tokenReservedChars = "{}";
+
+bool hasTokens(const std::string& source) {
+ auto pos = source.begin();
+ const auto end = source.end();
+
+ while (pos != end) {
+ auto brace = std::find(pos, end, '{');
+ if (brace == end)
+ return false;
+ for (brace++; brace != end && tokenReservedChars.find(*brace) == std::string::npos; brace++);
+ if (brace != end && *brace == '}') {
+ return true;
+ }
+ pos = brace;
+ }
+
+ return false;
+}
+
+std::unique_ptr<Expression> convertTokenStringToExpression(const std::string& source) {
+ std::vector<std::unique_ptr<Expression>> inputs;
+
+ auto pos = source.begin();
+ const auto end = source.end();
+
+ while (pos != end) {
+ auto brace = std::find(pos, end, '{');
+ if (pos != brace) {
+ inputs.push_back(literal(std::string(pos, brace)));
+ }
+ pos = brace;
+ if (pos != end) {
+ for (brace++; brace != end && tokenReservedChars.find(*brace) == std::string::npos; brace++);
+ if (brace != end && *brace == '}') {
+ inputs.push_back(toString(get(literal(std::string(pos + 1, brace)))));
+ pos = brace + 1;
+ } else {
+ inputs.push_back(literal(std::string(pos, brace)));
+ pos = brace;
+ }
+ }
+ }
+
+ switch (inputs.size()) {
+ case 0:
+ return literal(source);
+ case 1:
+ return std::move(inputs[0]);
+ default:
+ return concat(std::move(inputs));
+ }
+}
+
+// Ad-hoc Converters for double and int64_t. We should replace float with double wholesale,
+// and promote the int64_t Converter to general use (and it should check that the input is
+// an integer).
+template <>
+struct Converter<double> {
+ optional<double> operator()(const Convertible& value, Error& error) const {
+ auto converted = convert<float>(value, error);
+ if (!converted) {
+ return {};
+ }
+ return *converted;
+ }
+};
+
+template <>
+struct Converter<int64_t> {
+ optional<int64_t> operator()(const Convertible& value, Error& error) const {
+ auto converted = convert<float>(value, error);
+ if (!converted) {
+ return {};
+ }
+ return *converted;
+ }
+};
+
+enum class FunctionType {
+ Interval,
+ Exponential,
+ Categorical,
+ Identity,
+ Invalid
+};
+
+static bool interpolatable(type::Type type) {
+ return type.match(
+ [&] (const type::NumberType&) {
+ return true;
+ },
+ [&] (const type::ColorType&) {
+ return true;
+ },
+ [&] (const type::Array& array) {
+ return array.N && array.itemType == type::Number;
+ },
+ [&] (const auto&) {
+ return false;
+ }
+ );
+}
+
+static optional<std::unique_ptr<Expression>> convertLiteral(type::Type type, const Convertible& value, Error& error, bool convertTokens = false) {
+ return type.match(
+ [&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
+ auto result = convert<float>(value, error);
+ if (!result) {
+ return {};
+ }
+ return literal(double(*result));
+ },
+ [&] (const type::BooleanType&) -> optional<std::unique_ptr<Expression>> {
+ auto result = convert<bool>(value, error);
+ if (!result) {
+ return {};
+ }
+ return literal(*result);
+ },
+ [&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> {
+ auto result = convert<std::string>(value, error);
+ if (!result) {
+ return {};
+ }
+ return convertTokens ? convertTokenStringToExpression(*result) : literal(*result);
+ },
+ [&] (const type::ColorType&) -> optional<std::unique_ptr<Expression>> {
+ auto result = convert<Color>(value, error);
+ if (!result) {
+ return {};
+ }
+ return literal(*result);
+ },
+ [&] (const type::Array& array) -> optional<std::unique_ptr<Expression>> {
+ if (!isArray(value)) {
+ error = { "value must be an array" };
+ return {};
+ }
+ if (array.N && arrayLength(value) != *array.N) {
+ error = { "value must be an array of length " + util::toString(*array.N) };
+ return {};
+ }
+ return array.itemType.match(
+ [&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
+ std::vector<expression::Value> result;
+ result.reserve(arrayLength(value));
+ for (std::size_t i = 0; i < arrayLength(value); ++i) {
+ optional<float> number = toNumber(arrayMember(value, i));
+ if (!number) {
+ error = { "value must be an array of numbers" };
+ return {};
+ }
+ result.push_back(double(*number));
+ }
+ return literal(result);
+ },
+ [&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> {
+ std::vector<expression::Value> result;
+ result.reserve(arrayLength(value));
+ for (std::size_t i = 0; i < arrayLength(value); ++i) {
+ optional<std::string> string = toString(arrayMember(value, i));
+ if (!string) {
+ error = { "value must be an array of strings" };
+ return {};
+ }
+ result.push_back(*string);
+ }
+ return literal(result);
+ },
+ [&] (const auto&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ }
+ );
+ },
+ [&] (const type::NullType&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ },
+ [&] (const type::ObjectType&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ },
+ [&] (const type::ErrorType&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ },
+ [&] (const type::ValueType&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ },
+ [&] (const type::CollatorType&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ }
+ );
+}
+
+static optional<std::map<double, std::unique_ptr<Expression>>> convertStops(type::Type type,
+ const Convertible& value,
+ Error& error,
+ bool convertTokens) {
+ auto stopsValue = objectMember(value, "stops");
+ if (!stopsValue) {
+ error = { "function value must specify stops" };
+ return {};
+ }
+
+ if (!isArray(*stopsValue)) {
+ error = { "function stops must be an array" };
+ return {};
+ }
+
+ if (arrayLength(*stopsValue) == 0) {
+ error = { "function must have at least one stop" };
+ return {};
+ }
+
+ std::map<double, std::unique_ptr<Expression>> stops;
+ for (std::size_t i = 0; i < arrayLength(*stopsValue); ++i) {
+ const auto& stopValue = arrayMember(*stopsValue, i);
+
+ if (!isArray(stopValue)) {
+ error = { "function stop must be an array" };
+ return {};
+ }
+
+ if (arrayLength(stopValue) != 2) {
+ error = { "function stop must have two elements" };
+ return {};
+ }
+
+ optional<float> t = convert<float>(arrayMember(stopValue, 0), error);
+ if (!t) {
+ return {};
+ }
+
+ optional<std::unique_ptr<Expression>> e = convertLiteral(type, arrayMember(stopValue, 1), error, convertTokens);
+ if (!e) {
+ return {};
+ }
+
+ stops.emplace(*t, std::move(*e));
+ }
+
+ return { std::move(stops) };
+}
+
+template <class T>
+optional<std::map<T, std::unique_ptr<Expression>>> convertBranches(type::Type type,
+ const Convertible& value,
+ Error& error) {
+ auto stopsValue = objectMember(value, "stops");
+ if (!stopsValue) {
+ error = { "function value must specify stops" };
+ return {};
+ }
+
+ if (!isArray(*stopsValue)) {
+ error = { "function stops must be an array" };
+ return {};
+ }
+
+ if (arrayLength(*stopsValue) == 0) {
+ error = { "function must have at least one stop" };
+ return {};
+ }
+
+ std::map<T, std::unique_ptr<Expression>> stops;
+ for (std::size_t i = 0; i < arrayLength(*stopsValue); ++i) {
+ const auto& stopValue = arrayMember(*stopsValue, i);
+
+ if (!isArray(stopValue)) {
+ error = { "function stop must be an array" };
+ return {};
+ }
+
+ if (arrayLength(stopValue) != 2) {
+ error = { "function stop must have two elements" };
+ return {};
+ }
+
+ optional<T> t = convert<T>(arrayMember(stopValue, 0), error);
+ if (!t) {
+ return {};
+ }
+
+ optional<std::unique_ptr<Expression>> e = convertLiteral(type, arrayMember(stopValue, 1), error);
+ if (!e) {
+ return {};
+ }
+
+ stops.emplace(*t, std::move(*e));
+ }
+
+ return { std::move(stops) };
+}
+
+static optional<double> convertBase(const Convertible& value, Error& error) {
+ auto baseValue = objectMember(value, "base");
+
+ if (!baseValue) {
+ return 1.0;
+ }
+
+ auto base = toNumber(*baseValue);
+ if (!base) {
+ error = { "function base must be a number" };
+ return {};
+ }
+
+ return *base;
+}
+
+static std::unique_ptr<Expression> step(type::Type type, std::unique_ptr<Expression> input, std::map<double, std::unique_ptr<Expression>> stops) {
+ return std::make_unique<Step>(type, std::move(input), std::move(stops));
+}
+
+static std::unique_ptr<Expression> interpolate(type::Type type, Interpolator interpolator, std::unique_ptr<Expression> input, std::map<double, std::unique_ptr<Expression>> stops) {
+ ParsingContext ctx;
+ auto result = createInterpolate(type, std::move(interpolator), std::move(input), std::move(stops), ctx);
+ if (!result) {
+ assert(false);
+ return {};
+ }
+ return std::move(*result);
+}
+
+template <class T>
+std::unique_ptr<Expression> categorical(type::Type type, const std::string& property, std::map<T, std::unique_ptr<Expression>> branches) {
+ std::unordered_map<T, std::shared_ptr<Expression>> convertedBranches;
+ for (auto& b : branches) {
+ convertedBranches[b.first] = std::move(b.second);
+ }
+ return std::make_unique<Match<T>>(type, get(literal(property)), std::move(convertedBranches), error("replaced with default"));
+}
+
+template <>
+std::unique_ptr<Expression> categorical<bool>(type::Type type, const std::string& property, std::map<bool, std::unique_ptr<Expression>> branches) {
+ auto it = branches.find(true);
+ std::unique_ptr<Expression> trueCase = it == branches.end() ?
+ error("replaced with default") :
+ std::move(it->second);
+
+ it = branches.find(false);
+ std::unique_ptr<Expression> falseCase = it == branches.end() ?
+ error("replaced with default") :
+ std::move(it->second);
+
+ std::vector<typename Case::Branch> trueBranch;
+ trueBranch.emplace_back(get(literal(property)), std::move(trueCase));
+
+ return std::make_unique<Case>(type, std::move(trueBranch), std::move(falseCase));
+}
+
+static optional<std::unique_ptr<Expression>> convertIntervalFunction(type::Type type,
+ const Convertible& value,
+ Error& error,
+ std::unique_ptr<Expression> input,
+ bool convertTokens = false) {
+ auto stops = convertStops(type, value, error, convertTokens);
+ if (!stops) {
+ return {};
+ }
+ return step(type, std::move(input), std::move(*stops));
+}
+
+static optional<std::unique_ptr<Expression>> convertExponentialFunction(type::Type type,
+ const Convertible& value,
+ Error& error,
+ std::unique_ptr<Expression> input,
+ bool convertTokens = false) {
+ auto stops = convertStops(type, value, error, convertTokens);
+ if (!stops) {
+ return {};
+ }
+ auto base = convertBase(value, error);
+ if (!base) {
+ return {};
+ }
+ return interpolate(type, exponential(*base), std::move(input), std::move(*stops));
+}
+
+static optional<std::unique_ptr<Expression>> convertCategoricalFunction(type::Type type,
+ const Convertible& value,
+ Error& err,
+ const std::string& property) {
+ auto stopsValue = objectMember(value, "stops");
+ if (!stopsValue) {
+ err = { "function value must specify stops" };
+ return {};
+ }
+
+ if (!isArray(*stopsValue)) {
+ err = { "function stops must be an array" };
+ return {};
+ }
+
+ if (arrayLength(*stopsValue) == 0) {
+ err = { "function must have at least one stop" };
+ return {};
+ }
+
+ const auto& first = arrayMember(*stopsValue, 0);
+
+ if (!isArray(first)) {
+ err = { "function stop must be an array" };
+ return {};
+ }
+
+ if (arrayLength(first) != 2) {
+ err = { "function stop must have two elements" };
+ return {};
+ }
+
+ if (toBool(arrayMember(first, 0))) {
+ auto branches = convertBranches<bool>(type, value, err);
+ if (!branches) {
+ return {};
+ }
+ return categorical(type, property, std::move(*branches));
+ }
+
+ if (toNumber(arrayMember(first, 0))) {
+ auto branches = convertBranches<int64_t>(type, value, err);
+ if (!branches) {
+ return {};
+ }
+ return categorical(type, property, std::move(*branches));
+ }
+
+ if (toString(arrayMember(first, 0))) {
+ auto branches = convertBranches<std::string>(type, value, err);
+ if (!branches) {
+ return {};
+ }
+ return categorical(type, property, std::move(*branches));
+ }
+
+ err = { "stop domain value must be a number, string, or boolean" };
+ return {};
+}
+
+template <class T, class Fn>
+optional<std::unique_ptr<Expression>> composite(type::Type type,
+ const Convertible& value,
+ Error& error,
+ const Fn& makeInnerExpression) {
+ auto base = convertBase(value, error);
+ if (!base) {
+ return {};
+ }
+
+ auto stopsValue = objectMember(value, "stops");
+
+ // Checked by caller.
+ assert(stopsValue);
+ assert(isArray(*stopsValue));
+
+ std::map<float, std::map<T, std::unique_ptr<Expression>>> map;
+
+ for (std::size_t i = 0; i < arrayLength(*stopsValue); ++i) {
+ const auto& stopValue = arrayMember(*stopsValue, i);
+
+ if (!isArray(stopValue)) {
+ error = { "function stop must be an array" };
+ return {};
+ }
+
+ if (arrayLength(stopValue) != 2) {
+ error = { "function stop must have two elements" };
+ return {};
+ }
+
+ const auto& stopInput = arrayMember(stopValue, 0);
+
+ if (!isObject(stopInput)) {
+ error = { "stop input must be an object" };
+ return {};
+ }
+
+ auto zoomValue = objectMember(stopInput, "zoom");
+ if (!zoomValue) {
+ error = { "stop input must specify zoom" };
+ return {};
+ }
+
+ auto sourceValue = objectMember(stopInput, "value");
+ if (!sourceValue) {
+ error = { "stop input must specify value" };
+ return {};
+ }
+
+ optional<float> z = convert<float>(*zoomValue, error);
+ if (!z) {
+ return {};
+ }
+
+ optional<T> d = convert<T>(*sourceValue, error);
+ if (!d) {
+ return {};
+ }
+
+ optional<std::unique_ptr<Expression>> r = convertLiteral(type, arrayMember(stopValue, 1), error);
+ if (!r) {
+ return {};
+ }
+
+ map[*z].emplace(*d, std::move(*r));
+ }
+
+ std::map<double, std::unique_ptr<Expression>> stops;
+
+ for (auto& e : map) {
+ stops.emplace(e.first, makeInnerExpression(type, *base, std::move(e.second)));
+ }
+
+ if (interpolatable(type)) {
+ return interpolate(type, linear(), zoom(), std::move(stops));
+ } else {
+ return step(type, zoom(), std::move(stops));
+ }
+}
+
+optional<std::unique_ptr<Expression>> convertFunctionToExpression(type::Type type,
+ const Convertible& value,
+ Error& err,
+ bool convertTokens) {
+ if (!isObject(value)) {
+ err = { "function must be an object" };
+ return {};
+ }
+
+ FunctionType functionType = FunctionType::Invalid;
+
+ auto typeValue = objectMember(value, "type");
+ if (!typeValue) {
+ functionType = interpolatable(type) ? FunctionType::Exponential : FunctionType::Interval;
+ } else {
+ optional<std::string> string = toString(*typeValue);
+ if (string) {
+ if (*string == "interval")
+ functionType = FunctionType::Interval;
+ if (*string == "exponential" && interpolatable(type))
+ functionType = FunctionType::Exponential;
+ if (*string == "categorical")
+ functionType = FunctionType::Categorical;
+ if (*string == "identity")
+ functionType = FunctionType::Identity;
+ }
+ }
+
+ if (!objectMember(value, "property")) {
+ // Camera function.
+ switch (functionType) {
+ case FunctionType::Interval:
+ return convertIntervalFunction(type, value, err, zoom(), convertTokens);
+ case FunctionType::Exponential:
+ return convertExponentialFunction(type, value, err, zoom(), convertTokens);
+ default:
+ err = { "unsupported function type" };
+ return {};
+ }
+ }
+
+ auto propertyValue = objectMember(value, "property");
+ if (!propertyValue) {
+ err = { "function must specify property" };
+ return {};
+ }
+
+ auto property = toString(*propertyValue);
+ if (!property) {
+ err = { "function property must be a string" };
+ return {};
+ }
+
+ if (functionType == FunctionType::Identity) {
+ return type.match(
+ [&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> {
+ return string(get(literal(*property)));
+ },
+ [&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
+ return number(get(literal(*property)));
+ },
+ [&] (const type::BooleanType&) -> optional<std::unique_ptr<Expression>> {
+ return boolean(get(literal(*property)));
+ },
+ [&] (const type::ColorType&) -> optional<std::unique_ptr<Expression>> {
+ return toColor(get(literal(*property)));
+ },
+ [&] (const type::Array& array) -> optional<std::unique_ptr<Expression>> {
+ return std::unique_ptr<Expression>(
+ std::make_unique<ArrayAssertion>(array, get(literal(*property))));
+ },
+ [&] (const auto&) -> optional<std::unique_ptr<Expression>> {
+ assert(false); // No properties use this type.
+ return {};
+ }
+ );
+ }
+
+ auto stopsValue = objectMember(value, "stops");
+ if (!stopsValue) {
+ err = { "function value must specify stops" };
+ return {};
+ }
+
+ if (!isArray(*stopsValue)) {
+ err = { "function stops must be an array" };
+ return {};
+ }
+
+ if (arrayLength(*stopsValue) == 0) {
+ err = { "function must have at least one stop" };
+ return {};
+ }
+
+ const auto& first = arrayMember(*stopsValue, 0);
+
+ if (!isArray(first)) {
+ err = { "function stop must be an array" };
+ return {};
+ }
+
+ if (arrayLength(first) != 2) {
+ err = { "function stop must have two elements" };
+ return {};
+ }
+
+ const auto& stop = arrayMember(first, 0);
+
+ if (!isObject(stop)) {
+ // Source function.
+ switch (functionType) {
+ case FunctionType::Interval:
+ return convertIntervalFunction(type, value, err, number(get(literal(*property))));
+ case FunctionType::Exponential:
+ return convertExponentialFunction(type, value, err, number(get(literal(*property))));
+ case FunctionType::Categorical:
+ return convertCategoricalFunction(type, value, err, *property);
+ default:
+ err = { "unsupported function type" };
+ return {};
+ }
+ } else {
+ // Composite function.
+ auto sourceValue = objectMember(stop, "value");
+ if (!sourceValue) {
+ err = { "stop must specify value" };
+ return {};
+ }
+
+ if (toBool(*sourceValue)) {
+ switch (functionType) {
+ case FunctionType::Categorical:
+ return composite<bool>(type, value, err, [&] (type::Type type_, double, std::map<bool, std::unique_ptr<Expression>> stops) {
+ return categorical<bool>(type_, *property, std::move(stops));
+ });
+ default:
+ err = { "unsupported function type" };
+ return {};
+ }
+ }
+
+ if (toNumber(*sourceValue)) {
+ switch (functionType) {
+ case FunctionType::Interval:
+ return composite<double>(type, value, err, [&] (type::Type type_, double, std::map<double, std::unique_ptr<Expression>> stops) {
+ return step(type_, number(get(literal(*property))), std::move(stops));
+ });
+ case FunctionType::Exponential:
+ return composite<double>(type, value, err, [&] (type::Type type_, double base, std::map<double, std::unique_ptr<Expression>> stops) {
+ return interpolate(type_, exponential(base), number(get(literal(*property))), std::move(stops));
+ });
+ case FunctionType::Categorical:
+ return composite<int64_t>(type, value, err, [&] (type::Type type_, double, std::map<int64_t, std::unique_ptr<Expression>> stops) {
+ return categorical<int64_t>(type_, *property, std::move(stops));
+ });
+ default:
+ err = { "unsupported function type" };
+ return {};
+ }
+ }
+
+ if (toString(*sourceValue)) {
+ switch (functionType) {
+ case FunctionType::Categorical:
+ return composite<std::string>(type, value, err, [&] (type::Type type_, double, std::map<std::string, std::unique_ptr<Expression>> stops) {
+ return categorical<std::string>(type_, *property, std::move(stops));
+ });
+ default:
+ err = { "unsupported function type" };
+ return {};
+ }
+ }
+
+ err = { "stop domain value must be a number, string, or boolean" };
+ return {};
+ }
+}
+
+} // namespace conversion
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/conversion/light.cpp b/src/mbgl/style/conversion/light.cpp
index f521f74386..57b61eb340 100644
--- a/src/mbgl/style/conversion/light.cpp
+++ b/src/mbgl/style/conversion/light.cpp
@@ -18,7 +18,7 @@ optional<Light> Converter<Light>::operator()(const Convertible& value, Error& er
const auto anchor = objectMember(value, "anchor");
if (anchor) {
optional<PropertyValue<LightAnchorType>> convertedAnchor =
- convert<PropertyValue<LightAnchorType>>(*anchor, error);
+ convert<PropertyValue<LightAnchorType>>(*anchor, error, false);
if (convertedAnchor) {
light.setAnchor(*convertedAnchor);
@@ -41,7 +41,7 @@ optional<Light> Converter<Light>::operator()(const Convertible& value, Error& er
const auto color = objectMember(value, "color");
if (color) {
optional<PropertyValue<Color>> convertedColor =
- convert<PropertyValue<Color>>(*color, error);
+ convert<PropertyValue<Color>>(*color, error, false);
if (convertedColor) {
light.setColor(*convertedColor);
@@ -64,7 +64,7 @@ optional<Light> Converter<Light>::operator()(const Convertible& value, Error& er
const auto position = objectMember(value, "position");
if (position) {
optional<PropertyValue<Position>> convertedPosition =
- convert<PropertyValue<Position>>(*position, error);
+ convert<PropertyValue<Position>>(*position, error, false);
if (convertedPosition) {
light.setPosition(*convertedPosition);
@@ -87,7 +87,7 @@ optional<Light> Converter<Light>::operator()(const Convertible& value, Error& er
const auto intensity = objectMember(value, "intensity");
if (intensity) {
optional<PropertyValue<float>> convertedIntensity =
- convert<PropertyValue<float>>(*intensity, error);
+ convert<PropertyValue<float>>(*intensity, error, false);
if (convertedIntensity) {
light.setIntensity(*convertedIntensity);
diff --git a/src/mbgl/style/conversion/make_property_setters.hpp b/src/mbgl/style/conversion/make_property_setters.hpp
index 25c8fdb1ca..64826106f0 100644
--- a/src/mbgl/style/conversion/make_property_setters.hpp
+++ b/src/mbgl/style/conversion/make_property_setters.hpp
@@ -41,7 +41,7 @@ inline auto makeLayoutPropertySetters() {
result["icon-size"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconSize>;
result["icon-text-fit"] = &setProperty<SymbolLayer, PropertyValue<IconTextFitType>, &SymbolLayer::setIconTextFit>;
result["icon-text-fit-padding"] = &setProperty<SymbolLayer, PropertyValue<std::array<float, 4>>, &SymbolLayer::setIconTextFitPadding>;
- result["icon-image"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setIconImage>;
+ result["icon-image"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setIconImage, true>;
result["icon-rotate"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconRotate>;
result["icon-padding"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconPadding>;
result["icon-keep-upright"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconKeepUpright>;
@@ -50,7 +50,7 @@ inline auto makeLayoutPropertySetters() {
result["icon-pitch-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconPitchAlignment>;
result["text-pitch-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextPitchAlignment>;
result["text-rotation-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextRotationAlignment>;
- result["text-field"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setTextField>;
+ result["text-field"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setTextField, true>;
result["text-font"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<std::vector<std::string>>, &SymbolLayer::setTextFont>;
result["text-size"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextSize>;
result["text-max-width"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextMaxWidth>;
@@ -174,7 +174,7 @@ inline auto makePaintPropertySetters() {
result["heatmap-weight-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapWeightTransition>;
result["heatmap-intensity"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapIntensity>;
result["heatmap-intensity-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapIntensityTransition>;
- result["heatmap-color"] = &setProperty<HeatmapLayer, HeatmapColorPropertyValue, &HeatmapLayer::setHeatmapColor>;
+ result["heatmap-color"] = &setProperty<HeatmapLayer, ColorRampPropertyValue, &HeatmapLayer::setHeatmapColor>;
result["heatmap-color-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapColorTransition>;
result["heatmap-opacity"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapOpacity>;
result["heatmap-opacity-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapOpacityTransition>;
@@ -206,6 +206,8 @@ inline auto makePaintPropertySetters() {
result["raster-saturation-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterSaturationTransition>;
result["raster-contrast"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterContrast>;
result["raster-contrast-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterContrastTransition>;
+ result["raster-resampling"] = &setProperty<RasterLayer, PropertyValue<RasterResamplingType>, &RasterLayer::setRasterResampling>;
+ result["raster-resampling-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterResamplingTransition>;
result["raster-fade-duration"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterFadeDuration>;
result["raster-fade-duration-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterFadeDurationTransition>;
diff --git a/src/mbgl/style/conversion/make_property_setters.hpp.ejs b/src/mbgl/style/conversion/make_property_setters.hpp.ejs
new file mode 100644
index 0000000000..2b8925817d
--- /dev/null
+++ b/src/mbgl/style/conversion/make_property_setters.hpp.ejs
@@ -0,0 +1,46 @@
+#pragma once
+
+// This file is generated. Edit make_property_setters.hpp.ejs, then run `make style-code`.
+
+#include <mbgl/style/conversion/property_setter.hpp>
+
+<% for (const layer of locals.layers) { -%>
+#include <mbgl/style/layers/<%- layer.type.replace('-', '_') %>_layer.hpp>
+<% } -%>
+
+#include <unordered_map>
+
+namespace mbgl {
+namespace style {
+namespace conversion {
+
+inline auto makeLayoutPropertySetters() {
+ std::unordered_map<std::string, PropertySetter> result;
+
+ result["visibility"] = &setVisibility;
+
+<% for (const layer of locals.layers) { -%>
+<% for (const property of layer.layoutProperties) { -%>
+ result["<%- property.name %>"] = &setProperty<<%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %><%- property.name === 'icon-image' || property.name === 'text-field' ? ', true' : '' %>>;
+<% } -%>
+
+<% } -%>
+ return result;
+}
+
+inline auto makePaintPropertySetters() {
+ std::unordered_map<std::string, PropertySetter> result;
+
+<% for (const layer of locals.layers) { -%>
+<% for (const property of layer.paintProperties) { -%>
+ result["<%- property.name %>"] = &setProperty<<%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>;
+ result["<%- property.name %>-transition"] = &setTransition<<%- camelize(layer.type) %>Layer, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>Transition>;
+<% } -%>
+
+<% } -%>
+ return result;
+}
+
+} // namespace conversion
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/conversion/property_setter.hpp b/src/mbgl/style/conversion/property_setter.hpp
index e3716a18dc..8791e36e1f 100644
--- a/src/mbgl/style/conversion/property_setter.hpp
+++ b/src/mbgl/style/conversion/property_setter.hpp
@@ -1,11 +1,12 @@
#pragma once
#include <mbgl/style/layer.hpp>
+#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/color_ramp_property_value.hpp>
#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/property_value.hpp>
#include <mbgl/style/conversion/data_driven_property_value.hpp>
-#include <mbgl/style/conversion/heatmap_color_property_value.hpp>
#include <mbgl/style/conversion/transition_options.hpp>
#include <string>
@@ -16,7 +17,7 @@ namespace conversion {
using PropertySetter = optional<Error> (*) (Layer&, const Convertible&);
-template <class L, class PropertyValue, void (L::*setter)(PropertyValue)>
+template <class L, class PropertyValue, void (L::*setter)(PropertyValue), bool convertTokens = false>
optional<Error> setProperty(Layer& layer, const Convertible& value) {
auto* typedLayer = layer.as<L>();
if (!typedLayer) {
@@ -24,7 +25,7 @@ optional<Error> setProperty(Layer& layer, const Convertible& value) {
}
Error error;
- optional<PropertyValue> typedValue = convert<PropertyValue>(value, error);
+ optional<PropertyValue> typedValue = convert<PropertyValue>(value, error, convertTokens);
if (!typedValue) {
return error;
}
diff --git a/src/mbgl/style/conversion/stringify.hpp b/src/mbgl/style/conversion/stringify.hpp
index 7b7727d7c4..77a39c51f9 100644
--- a/src/mbgl/style/conversion/stringify.hpp
+++ b/src/mbgl/style/conversion/stringify.hpp
@@ -126,162 +126,9 @@ void stringify(Writer& writer, const FeatureIdentifier& id) {
}
template <class Writer>
-class StringifyFilter {
-public:
- Writer& writer;
-
- void operator()(const NullFilter&) {
- writer.Null();
- }
-
- void operator()(const EqualsFilter& f) {
- stringifyBinaryFilter(f, "==");
- }
-
- void operator()(const NotEqualsFilter& f) {
- stringifyBinaryFilter(f, "!=");
- }
-
- void operator()(const LessThanFilter& f) {
- stringifyBinaryFilter(f, "<");
- }
-
- void operator()(const LessThanEqualsFilter& f) {
- stringifyBinaryFilter(f, "<=");
- }
-
- void operator()(const GreaterThanFilter& f) {
- stringifyBinaryFilter(f, ">");
- }
-
- void operator()(const GreaterThanEqualsFilter& f) {
- stringifyBinaryFilter(f, ">=");
- }
-
- void operator()(const InFilter& f) {
- stringifySetFilter(f, "in");
- }
-
- void operator()(const NotInFilter& f) {
- stringifySetFilter(f, "!in");
- }
-
- void operator()(const AllFilter& f) {
- stringifyCompoundFilter(f, "all");
- }
-
- void operator()(const AnyFilter& f) {
- stringifyCompoundFilter(f, "any");
- }
-
- void operator()(const NoneFilter& f) {
- stringifyCompoundFilter(f, "none");
- }
-
- void operator()(const HasFilter& f) {
- stringifyUnaryFilter("has", f.key);
- }
-
- void operator()(const NotHasFilter& f) {
- stringifyUnaryFilter("!has", f.key);
- }
-
- void operator()(const TypeEqualsFilter& f) {
- stringifyBinaryFilter(f, "==", "$type");
- }
-
- void operator()(const TypeNotEqualsFilter& f) {
- stringifyBinaryFilter(f, "!=", "$type");
- }
-
- void operator()(const TypeInFilter& f) {
- stringifySetFilter(f, "in", "$type");
- }
-
- void operator()(const TypeNotInFilter& f) {
- stringifySetFilter(f, "!in", "$type");
- }
-
- void operator()(const IdentifierEqualsFilter& f) {
- stringifyBinaryFilter(f, "==", "$id");
- }
-
- void operator()(const IdentifierNotEqualsFilter& f) {
- stringifyBinaryFilter(f, "!=", "$id");
- }
-
- void operator()(const IdentifierInFilter& f) {
- stringifySetFilter(f, "in", "$id");
- }
-
- void operator()(const IdentifierNotInFilter& f) {
- stringifySetFilter(f, "!in", "$id");
- }
-
- void operator()(const HasIdentifierFilter&) {
- stringifyUnaryFilter("has", "$id");
- }
-
- void operator()(const NotHasIdentifierFilter&) {
- stringifyUnaryFilter("!has", "$id");
- }
-
- void operator()(const ExpressionFilter& filter) {
- stringify(writer, filter.expression->serialize());
- }
-
-private:
- template <class F>
- void stringifyBinaryFilter(const F& f, const char * op) {
- stringifyBinaryFilter(f, op, f.key);
- }
-
- template <class F>
- void stringifyBinaryFilter(const F& f, const char * op, const std::string& key) {
- writer.StartArray();
- writer.String(op);
- writer.String(key);
- stringify(writer, f.value);
- writer.EndArray();
- }
-
- template <class F>
- void stringifySetFilter(const F& f, const char * op) {
- stringifySetFilter(f, op, f.key);
- }
-
- template <class F>
- void stringifySetFilter(const F& f, const char * op, const std::string& key) {
- writer.StartArray();
- writer.String(op);
- writer.String(key);
- for (const auto& value : f.values) {
- stringify(writer, value);
- }
- writer.EndArray();
- }
-
- template <class F>
- void stringifyCompoundFilter(const F& f, const char * op) {
- writer.StartArray();
- writer.String(op);
- for (const auto& filter : f.filters) {
- Filter::visit(filter, *this);
- }
- writer.EndArray();
- }
-
- void stringifyUnaryFilter(const char * op, const std::string& key) {
- writer.StartArray();
- writer.String(op);
- writer.String(key);
- writer.EndArray();
- }
-};
-
-template <class Writer>
-void stringify(Writer& writer, const Filter& f) {
- Filter::visit(f, StringifyFilter<Writer> { writer });
+void stringify(Writer& writer, const Filter& filter) {
+ if (!filter.expression) writer.Null();
+ else stringify(writer, (*filter.expression)->serialize());
}
template <class Writer>
@@ -291,17 +138,7 @@ void stringify(Writer& writer, const Undefined&) {
}
template <class Writer, class T>
-void stringify(Writer& writer, const CameraFunction<T>& fn) {
- stringify(writer, fn.getExpression().serialize());
-}
-
-template <class Writer, class T>
-void stringify(Writer& writer, const SourceFunction<T>& fn) {
- stringify(writer, fn.getExpression().serialize());
-}
-
-template <class Writer, class T>
-void stringify(Writer& writer, const CompositeFunction<T>& fn) {
+void stringify(Writer& writer, const PropertyExpression<T>& fn) {
stringify(writer, fn.getExpression().serialize());
}
diff --git a/src/mbgl/style/conversion/tileset.cpp b/src/mbgl/style/conversion/tileset.cpp
index a2c4aa80b3..fe3254b149 100644
--- a/src/mbgl/style/conversion/tileset.cpp
+++ b/src/mbgl/style/conversion/tileset.cpp
@@ -1,14 +1,11 @@
#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/util/geo.hpp>
+#include <mbgl/math/clamp.hpp>
namespace mbgl {
namespace style {
namespace conversion {
-bool validateLatitude(const double lat) {
- return lat <= 90 && lat >= -90;
-}
-
optional<Tileset> Converter<Tileset>::operator()(const Convertible& value, Error& error) const {
Tileset result;
@@ -95,16 +92,20 @@ optional<Tileset> Converter<Tileset>::operator()(const Convertible& value, Error
error = { "bounds array must contain numeric longitude and latitude values" };
return {};
}
- if (!validateLatitude(*bottom) || !validateLatitude(*top) || top <= bottom){
- error = { "bounds latitude values must be between -90 and 90 with bottom less than top" };
+
+ bottom = util::clamp(*bottom, -90.0, 90.0);
+ top = util::clamp(*top, -90.0, 90.0);
+ if (top <= bottom){
+ error = { "bounds bottom latitude must be smaller than top latitude" };
return {};
}
+
if(*left >= *right) {
error = { "bounds left longitude should be less than right longitude" };
return {};
}
- *left = util::max(-180.0, *left);
- *right = util::min(180.0, *right);
+ left = util::max(-180.0, *left);
+ right = util::min(180.0, *right);
result.bounds = LatLngBounds::hull({ *bottom, *left }, { *top, *right });
}
diff --git a/src/mbgl/style/conversion/transition_options.cpp b/src/mbgl/style/conversion/transition_options.cpp
index 8a60c5bfd8..116d44f9d9 100644
--- a/src/mbgl/style/conversion/transition_options.cpp
+++ b/src/mbgl/style/conversion/transition_options.cpp
@@ -10,7 +10,7 @@ optional<TransitionOptions> Converter<TransitionOptions>::operator()(const Conve
return {};
}
- TransitionOptions result;
+ optional<TransitionOptions> result = TransitionOptions{};
auto duration = objectMember(value, "duration");
if (duration) {
@@ -19,7 +19,7 @@ optional<TransitionOptions> Converter<TransitionOptions>::operator()(const Conve
error = { "duration must be a number" };
return {};
}
- result.duration = { std::chrono::milliseconds(int64_t(*number)) };
+ result->duration = { std::chrono::milliseconds(int64_t(*number)) };
}
auto delay = objectMember(value, "delay");
@@ -29,7 +29,7 @@ optional<TransitionOptions> Converter<TransitionOptions>::operator()(const Conve
error = { "delay must be a number" };
return {};
}
- result.delay = { std::chrono::milliseconds(int64_t(*number)) };
+ result->delay = { std::chrono::milliseconds(int64_t(*number)) };
}
return result;
diff --git a/src/mbgl/style/expression/assertion.cpp b/src/mbgl/style/expression/assertion.cpp
index d6f3f1b584..2434d7a2f8 100644
--- a/src/mbgl/style/expression/assertion.cpp
+++ b/src/mbgl/style/expression/assertion.cpp
@@ -6,6 +6,14 @@ namespace style {
namespace expression {
using namespace mbgl::style::conversion;
+
+Assertion::Assertion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
+ Expression(Kind::Assertion, type_),
+ inputs(std::move(inputs_))
+{
+ assert(!inputs.empty());
+}
+
ParseResult Assertion::parse(const Convertible& value, ParsingContext& ctx) {
static std::unordered_map<std::string, type::Type> types {
{"string", type::String},
@@ -64,7 +72,8 @@ void Assertion::eachChild(const std::function<void(const Expression&)>& visit) c
};
bool Assertion::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Assertion*>(&e)) {
+ if (e.getKind() == Kind::Assertion) {
+ auto rhs = static_cast<const Assertion*>(&e);
return getType() == rhs->getType() && Expression::childrenEqual(inputs, rhs->inputs);
}
return false;
diff --git a/src/mbgl/style/expression/boolean_operator.cpp b/src/mbgl/style/expression/boolean_operator.cpp
index 8d277450ba..68e96129aa 100644
--- a/src/mbgl/style/expression/boolean_operator.cpp
+++ b/src/mbgl/style/expression/boolean_operator.cpp
@@ -20,7 +20,8 @@ void Any::eachChild(const std::function<void(const Expression&)>& visit) const {
}
bool Any::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Any*>(&e)) {
+ if (e.getKind() == Kind::Any) {
+ auto rhs = static_cast<const Any*>(&e);
return Expression::childrenEqual(inputs, rhs->inputs);
}
return false;
@@ -47,7 +48,8 @@ void All::eachChild(const std::function<void(const Expression&)>& visit) const {
}
bool All::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const All*>(&e)) {
+ if (e.getKind() == Kind::All) {
+ auto rhs = static_cast<const All*>(&e);
return Expression::childrenEqual(inputs, rhs->inputs);
}
return false;
diff --git a/src/mbgl/style/expression/case.cpp b/src/mbgl/style/expression/case.cpp
index 295e694189..e885c0ce6b 100644
--- a/src/mbgl/style/expression/case.cpp
+++ b/src/mbgl/style/expression/case.cpp
@@ -28,7 +28,8 @@ void Case::eachChild(const std::function<void(const Expression&)>& visit) const
}
bool Case::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Case*>(&e)) {
+ if (e.getKind() == Kind::Case) {
+ auto rhs = static_cast<const Case*>(&e);
return *otherwise == *(rhs->otherwise) && Expression::childrenEqual(branches, rhs->branches);
}
return false;
diff --git a/src/mbgl/style/expression/coalesce.cpp b/src/mbgl/style/expression/coalesce.cpp
index 872a9abbef..0090f16009 100644
--- a/src/mbgl/style/expression/coalesce.cpp
+++ b/src/mbgl/style/expression/coalesce.cpp
@@ -21,7 +21,8 @@ void Coalesce::eachChild(const std::function<void(const Expression&)>& visit) co
}
bool Coalesce::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Coalesce*>(&e)) {
+ if (e.getKind() == Kind::Coalesce) {
+ auto rhs = static_cast<const Coalesce*>(&e);
return Expression::childrenEqual(args, rhs->args);
}
return false;
diff --git a/src/mbgl/style/expression/coercion.cpp b/src/mbgl/style/expression/coercion.cpp
index d9cd3ffdc9..f5a4d70f66 100644
--- a/src/mbgl/style/expression/coercion.cpp
+++ b/src/mbgl/style/expression/coercion.cpp
@@ -13,7 +13,7 @@ EvaluationResult toNumber(const Value& v) {
[](const std::string& s) -> optional<double> {
try {
return util::stof(s);
- } catch(std::exception) {
+ } catch (const std::exception&) {
return optional<double>();
}
},
@@ -68,9 +68,10 @@ EvaluationResult toColor(const Value& colorValue) {
}
Coercion::Coercion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
- Expression(std::move(type_)),
+ Expression(Kind::Coercion, std::move(type_)),
inputs(std::move(inputs_))
{
+ assert(!inputs.empty());
type::Type t = getType();
if (t.is<type::NumberType>()) {
coerceSingleValue = toNumber;
@@ -137,7 +138,8 @@ void Coercion::eachChild(const std::function<void(const Expression&)>& visit) co
};
bool Coercion::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Coercion*>(&e)) {
+ if (e.getKind() == Kind::Coercion) {
+ auto rhs = static_cast<const Coercion*>(&e);
return getType() == rhs->getType() && Expression::childrenEqual(inputs, rhs->inputs);
}
return false;
diff --git a/src/mbgl/style/expression/collator_expression.cpp b/src/mbgl/style/expression/collator_expression.cpp
new file mode 100644
index 0000000000..b27eedbc76
--- /dev/null
+++ b/src/mbgl/style/expression/collator_expression.cpp
@@ -0,0 +1,121 @@
+#include <mbgl/style/expression/collator.hpp>
+#include <mbgl/style/expression/collator_expression.hpp>
+#include <mbgl/style/expression/literal.hpp>
+#include <mbgl/util/string.hpp>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+CollatorExpression::CollatorExpression(std::unique_ptr<Expression> caseSensitive_,
+ std::unique_ptr<Expression> diacriticSensitive_,
+ optional<std::unique_ptr<Expression>> locale_)
+ : Expression(Kind::CollatorExpression, type::Collator)
+ , caseSensitive(std::move(caseSensitive_))
+ , diacriticSensitive(std::move(diacriticSensitive_))
+ , locale(std::move(locale_))
+{}
+
+using namespace mbgl::style::conversion;
+
+ParseResult CollatorExpression::parse(const Convertible& value, ParsingContext& ctx) {
+ if (arrayLength(value) != 2) {
+ ctx.error("Expected one argument.");
+ return ParseResult();
+ }
+
+ auto options = arrayMember(value, 1);
+ if (!isObject(options)) {
+ ctx.error("Collator options argument must be an object.");
+ return ParseResult();
+ }
+
+ const optional<Convertible> caseSensitiveOption = objectMember(options, "case-sensitive");
+ ParseResult caseSensitive;
+ if (caseSensitiveOption) {
+ caseSensitive = ctx.parse(*caseSensitiveOption, 1, {type::Boolean});
+ } else {
+ caseSensitive = { std::make_unique<Literal>(false) };
+ }
+ if (!caseSensitive) {
+ return ParseResult();
+ }
+
+ const optional<Convertible> diacriticSensitiveOption = objectMember(options, "diacritic-sensitive");
+ ParseResult diacriticSensitive;
+ if (diacriticSensitiveOption) {
+ diacriticSensitive = ctx.parse(*diacriticSensitiveOption, 1, {type::Boolean});
+ } else {
+ diacriticSensitive = { std::make_unique<Literal>(false) };
+ }
+ if (!diacriticSensitive) {
+ return ParseResult();
+ }
+
+ const optional<Convertible> localeOption = objectMember(options, "locale");
+ ParseResult locale;
+ if (localeOption) {
+ locale = ctx.parse(*localeOption, 1, {type::String});
+ if (!locale) {
+ return ParseResult();
+ }
+ }
+
+ return ParseResult(std::make_unique<CollatorExpression>(std::move(*caseSensitive), std::move(*diacriticSensitive), std::move(locale)));
+}
+
+void CollatorExpression::eachChild(const std::function<void(const Expression&)>& fn) const {
+ fn(*caseSensitive);
+ fn(*diacriticSensitive);
+ if (locale) {
+ fn(**locale);
+ }
+}
+
+bool CollatorExpression::operator==(const Expression& e) const {
+ if (e.getKind() == Kind::CollatorExpression) {
+ auto rhs = static_cast<const CollatorExpression*>(&e);
+ if ((locale && (!rhs->locale || **locale != **(rhs->locale))) ||
+ (!locale && rhs->locale)) {
+ return false;
+ }
+ return *caseSensitive == *(rhs->caseSensitive) &&
+ *diacriticSensitive == *(rhs->diacriticSensitive);
+ }
+ return false;
+}
+
+mbgl::Value CollatorExpression::serialize() const {
+ std::unordered_map<std::string, mbgl::Value> options;
+ options["case-sensitive"] = caseSensitive->serialize();
+ options["diacritic-sensitive"] = diacriticSensitive->serialize();
+ if (locale) {
+ options["locale"] = (*locale)->serialize();
+ }
+ return std::vector<mbgl::Value>{{ std::string("collator"), options }};
+}
+
+EvaluationResult CollatorExpression::evaluate(const EvaluationContext& params) const {
+ auto caseSensitiveResult = caseSensitive->evaluate(params);
+ if (!caseSensitiveResult) {
+ return caseSensitiveResult.error();
+ }
+ auto diacriticSensitiveResult = diacriticSensitive->evaluate(params);
+ if (!diacriticSensitiveResult) {
+ return diacriticSensitiveResult.error();
+ }
+
+ if (locale) {
+ auto localeResult = (*locale)->evaluate(params);
+ if (!localeResult) {
+ return localeResult.error();
+ }
+ return Collator(caseSensitiveResult->get<bool>(), diacriticSensitiveResult->get<bool>(), localeResult->get<std::string>());
+ } else {
+ return Collator(caseSensitiveResult->get<bool>(), diacriticSensitiveResult->get<bool>());
+ }
+}
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp
index bcde09e1b6..46b0c7fe18 100644
--- a/src/mbgl/style/expression/compound_expression.cpp
+++ b/src/mbgl/style/expression/compound_expression.cpp
@@ -1,3 +1,5 @@
+#include <boost/algorithm/string/join.hpp>
+#include <mbgl/style/expression/collator.hpp>
#include <mbgl/style/expression/compound_expression.hpp>
#include <mbgl/style/expression/check_subtype.hpp>
#include <mbgl/style/expression/util.hpp>
@@ -19,7 +21,7 @@ namespace detail {
The Signature<Fn> structs are wrappers around an "evaluate()" function whose
purpose is to extract the necessary Type data from the evaluate function's
type. There are three key (partial) specializations:
-
+
Signature<R (Params...)>:
Wraps a simple evaluate function (const T0&, const T1&, ...) -> Result<U>
@@ -30,9 +32,9 @@ namespace detail {
Signature<R (const EvaluationContext&, Params...)>:
Wraps an evaluate function that needs to access the expression evaluation
parameters in addition to its subexpressions, i.e.,
- (const EvaluationParams& const T0&, const T1&, ...) -> Result<U>. Needed
+ (const EvaluationParams&, const T0&, const T1&, ...) -> Result<U>. Needed
for expressions like ["zoom"], ["get", key], etc.
-
+
In each of the above evaluate signatures, T0, T1, etc. are the types of
the successfully evaluated subexpressions.
*/
@@ -43,7 +45,7 @@ struct Signature;
template <class R, class... Params>
struct Signature<R (Params...)> : SignatureBase {
using Args = std::array<std::unique_ptr<Expression>, sizeof...(Params)>;
-
+
Signature(R (*evaluate_)(Params...), std::string name_) :
SignatureBase(
valueTypeToExpressionType<std::decay_t<typename R::Value>>(),
@@ -55,7 +57,7 @@ struct Signature<R (Params...)> : SignatureBase {
EvaluationResult apply(const EvaluationContext& evaluationParameters, const Args& args) const {
return applyImpl(evaluationParameters, args, std::index_sequence_for<Params...>{});
}
-
+
std::unique_ptr<Expression> makeExpression(std::vector<std::unique_ptr<Expression>> args) const override {
typename Signature::Args argsArray;
std::copy_n(std::make_move_iterator(args.begin()), sizeof...(Params), argsArray.begin());
@@ -80,7 +82,7 @@ private:
template <class R, typename T>
struct Signature<R (const Varargs<T>&)> : SignatureBase {
using Args = std::vector<std::unique_ptr<Expression>>;
-
+
Signature(R (*evaluate_)(const Varargs<T>&), std::string name_) :
SignatureBase(
valueTypeToExpressionType<std::decay_t<typename R::Value>>(),
@@ -89,11 +91,11 @@ struct Signature<R (const Varargs<T>&)> : SignatureBase {
),
evaluate(evaluate_)
{}
-
+
std::unique_ptr<Expression> makeExpression(std::vector<std::unique_ptr<Expression>> args) const override {
return std::make_unique<CompoundExpression<Signature>>(name, *this, std::move(args));
};
-
+
EvaluationResult apply(const EvaluationContext& evaluationParameters, const Args& args) const {
Varargs<T> evaluated;
evaluated.reserve(args.size());
@@ -115,7 +117,7 @@ struct Signature<R (const Varargs<T>&)> : SignatureBase {
template <class R, class... Params>
struct Signature<R (const EvaluationContext&, Params...)> : SignatureBase {
using Args = std::array<std::unique_ptr<Expression>, sizeof...(Params)>;
-
+
Signature(R (*evaluate_)(const EvaluationContext&, Params...), std::string name_) :
SignatureBase(
valueTypeToExpressionType<std::decay_t<typename R::Value>>(),
@@ -124,17 +126,17 @@ struct Signature<R (const EvaluationContext&, Params...)> : SignatureBase {
),
evaluate(evaluate_)
{}
-
+
std::unique_ptr<Expression> makeExpression(std::vector<std::unique_ptr<Expression>> args) const override {
typename Signature::Args argsArray;
std::copy_n(std::make_move_iterator(args.begin()), sizeof...(Params), argsArray.begin());
return std::make_unique<CompoundExpression<Signature>>(name, *this, std::move(argsArray));
}
-
+
EvaluationResult apply(const EvaluationContext& evaluationParameters, const Args& args) const {
return applyImpl(evaluationParameters, args, std::index_sequence_for<Params...>{});
}
-
+
private:
template <std::size_t ...I>
EvaluationResult applyImpl(const EvaluationContext& evaluationParameters, const Args& args, std::index_sequence<I...>) const {
@@ -150,6 +152,41 @@ private:
R (*evaluate)(const EvaluationContext&, Params...);
};
+
+// Evaluate function needing EvaluationContext and Varargs
+// (const EvaluationContext&, const Varargs<T>&) -> Result<U>
+template <class R, typename T>
+struct Signature<R (const EvaluationContext&, const Varargs<T>&)> : SignatureBase {
+ using Args = std::vector<std::unique_ptr<Expression>>;
+
+ Signature(R (*evaluate_)(const EvaluationContext&, const Varargs<T>&), std::string name_) :
+ SignatureBase(
+ valueTypeToExpressionType<std::decay_t<typename R::Value>>(),
+ VarargsType { valueTypeToExpressionType<T>() },
+ std::move(name_)
+ ),
+ evaluate(evaluate_)
+ {}
+
+ std::unique_ptr<Expression> makeExpression(std::vector<std::unique_ptr<Expression>> args) const override {
+ return std::make_unique<CompoundExpression<Signature>>(name, *this, std::move(args));
+ };
+
+ EvaluationResult apply(const EvaluationContext& evaluationParameters, const Args& args) const {
+ Varargs<T> evaluated;
+ evaluated.reserve(args.size());
+ for (const auto& arg : args) {
+ const EvaluationResult evaluatedArg = arg->evaluate(evaluationParameters);
+ if(!evaluatedArg) return evaluatedArg.error();
+ evaluated.push_back(*fromExpressionValue<std::decay_t<T>>(*evaluatedArg));
+ }
+ const R value = evaluate(evaluationParameters, evaluated);
+ if (!value) return value.error();
+ return *value;
+ }
+
+ R (*evaluate)(const EvaluationContext&, const Varargs<T>&);
+};
// Machinery to pull out function types from class methods, lambdas, etc.
template <class R, class... Params>
@@ -181,29 +218,104 @@ static std::unique_ptr<detail::SignatureBase> makeSignature(Fn evaluateFunction,
return std::make_unique<detail::Signature<Fn>>(evaluateFunction, std::move(name));
}
+Value featureIdAsExpressionValue(EvaluationContext params) {
+ assert(params.feature);
+ auto id = params.feature->getID();
+ if (!id) return Null;
+ return id->match([](const auto& idid) {
+ return toExpressionValue(mbgl::Value(idid));
+ });
+};
+
+optional<Value> featurePropertyAsExpressionValue(EvaluationContext params, const std::string& key) {
+ assert(params.feature);
+ auto property = params.feature->getValue(key);
+ return property ? toExpressionValue(*property) : optional<Value>();
+};
+
+optional<std::string> featureTypeAsString(FeatureType type) {
+ switch(type) {
+ case FeatureType::Point:
+ return optional<std::string>("Point");
+ case FeatureType::LineString:
+ return optional<std::string>("LineString");
+ case FeatureType::Polygon:
+ return optional<std::string>("Polygon");
+ case FeatureType::Unknown:
+ return optional<std::string>("Unknown");
+ default:
+ return {};
+ }
+};
+
+optional<double> featurePropertyAsDouble(EvaluationContext params, const std::string& key) {
+ assert(params.feature);
+ auto property = params.feature->getValue(key);
+ if (!property) return {};
+ return property->match(
+ [](double value) { return value; },
+ [](uint64_t value) { return optional<double>(static_cast<double>(value)); },
+ [](int64_t value) { return optional<double>(static_cast<double>(value)); },
+ [](auto) { return optional<double>(); }
+ );
+};
+
+optional<std::string> featurePropertyAsString(EvaluationContext params, const std::string& key) {
+ assert(params.feature);
+ auto property = params.feature->getValue(key);
+ if (!property) return {};
+ return property->match(
+ [](std::string value) { return value; },
+ [](auto) { return optional<std::string>(); }
+ );
+};
+
+optional<double> featureIdAsDouble(EvaluationContext params) {
+ assert(params.feature);
+ auto id = params.feature->getID();
+ if (!id) return optional<double>();
+ return id->match(
+ [](double value) { return value; },
+ [](uint64_t value) { return optional<double>(static_cast<double>(value)); },
+ [](int64_t value) { return optional<double>(static_cast<double>(value)); },
+ [](auto) { return optional<double>(); }
+ );
+};
+
+optional<std::string> featureIdAsString(EvaluationContext params) {
+ assert(params.feature);
+ auto id = params.feature->getID();
+ if (!id) return optional<std::string>();
+ return id->match(
+ [](std::string value) { return value; },
+ [](auto) { return optional<std::string>(); }
+ );
+};
+
std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initializeDefinitions() {
std::unordered_map<std::string, CompoundExpressionRegistry::Definition> definitions;
auto define = [&](std::string name, auto fn) {
definitions[name].push_back(makeSignature(fn, name));
};
-
+
define("e", []() -> Result<double> { return 2.718281828459045; });
define("pi", []() -> Result<double> { return 3.141592653589793; });
define("ln2", []() -> Result<double> { return 0.6931471805599453; });
define("typeof", [](const Value& v) -> Result<std::string> { return toString(typeOf(v)); });
-
+
define("to-string", [](const Value& value) -> Result<std::string> {
return value.match(
+ [](const NullValue&) -> Result<std::string> { return std::string(); },
[](const Color& c) -> Result<std::string> { return c.stringify(); }, // avoid quoting
[](const std::string& s) -> Result<std::string> { return s; }, // avoid quoting
[](const auto& v) -> Result<std::string> { return stringify(v); }
);
});
-
+
define("to-boolean", [](const Value& v) -> Result<bool> {
return v.match(
- [&] (double f) { return (bool)f; },
+ [&] (double f) { return static_cast<bool>(f); },
[&] (const std::string& s) { return s.length() > 0; },
[&] (bool b) { return b; },
[&] (const NullValue&) { return false; },
@@ -213,10 +325,10 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
define("to-rgba", [](const Color& color) -> Result<std::array<double, 4>> {
return color.toArray();
});
-
+
define("rgba", rgba);
define("rgb", [](double r, double g, double b) { return rgba(r, g, b, 1.0f); });
-
+
define("zoom", [](const EvaluationContext& params) -> Result<double> {
if (!params.zoom) {
return EvaluationError {
@@ -225,7 +337,7 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
}
return *(params.zoom);
});
-
+
define("heatmap-density", [](const EvaluationContext& params) -> Result<double> {
if (!params.heatmapDensity) {
return EvaluationError {
@@ -241,7 +353,7 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
"Feature data is unavailable in the current evaluation context."
};
}
-
+
return params.feature->getValue(key) ? true : false;
});
define("has", [](const std::string& key, const std::unordered_map<std::string, Value>& object) -> Result<bool> {
@@ -267,7 +379,7 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
}
return object.at(key);
});
-
+
define("properties", [](const EvaluationContext& params) -> Result<std::unordered_map<std::string, Value>> {
if (!params.feature) {
return EvaluationError {
@@ -281,14 +393,14 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
}
return result;
});
-
+
define("geometry-type", [](const EvaluationContext& params) -> Result<std::string> {
if (!params.feature) {
return EvaluationError {
"Feature data is unavailable in the current evaluation context."
};
}
-
+
auto type = params.feature->getType();
if (type == FeatureType::Point) {
return "Point";
@@ -300,14 +412,14 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
return "Unknown";
}
});
-
+
define("id", [](const EvaluationContext& params) -> Result<Value> {
if (!params.feature) {
return EvaluationError {
"Feature data is unavailable in the current evaluation context."
};
}
-
+
auto id = params.feature->getID();
if (!id) {
return Null;
@@ -318,7 +430,7 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
}
);
});
-
+
define("+", [](const Varargs<double>& args) -> Result<double> {
double sum = 0.0f;
for (auto arg : args) {
@@ -341,14 +453,14 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
define("sqrt", [](double x) -> Result<double> { return sqrt(x); });
define("log10", [](double x) -> Result<double> { return log10(x); });
define("ln", [](double x) -> Result<double> { return log(x); });
- define("log2", [](double x) -> Result<double> { return util::log2(x); });
+ define("log2", [](double x) -> Result<double> { return log2(x); });
define("sin", [](double x) -> Result<double> { return sin(x); });
define("cos", [](double x) -> Result<double> { return cos(x); });
define("tan", [](double x) -> Result<double> { return tan(x); });
define("asin", [](double x) -> Result<double> { return asin(x); });
define("acos", [](double x) -> Result<double> { return acos(x); });
define("atan", [](double x) -> Result<double> { return atan(x); });
-
+
define("min", [](const Varargs<double>& args) -> Result<double> {
double result = std::numeric_limits<double>::infinity();
for (double arg : args) {
@@ -371,13 +483,17 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
define(">", [](double lhs, double rhs) -> Result<bool> { return lhs > rhs; });
define(">", [](const std::string& lhs, const std::string& rhs) -> Result<bool> { return lhs > rhs; });
+ define(">", [](const std::string& lhs, const std::string& rhs, const Collator& c) -> Result<bool> { return c.compare(lhs, rhs) > 0; });
define(">=", [](double lhs, double rhs) -> Result<bool> { return lhs >= rhs; });
define(">=",[](const std::string& lhs, const std::string& rhs) -> Result<bool> { return lhs >= rhs; });
+ define(">=", [](const std::string& lhs, const std::string& rhs, const Collator& c) -> Result<bool> { return c.compare(lhs, rhs) >= 0; });
define("<", [](double lhs, double rhs) -> Result<bool> { return lhs < rhs; });
define("<", [](const std::string& lhs, const std::string& rhs) -> Result<bool> { return lhs < rhs; });
+ define("<", [](const std::string& lhs, const std::string& rhs, const Collator& c) -> Result<bool> { return c.compare(lhs, rhs) < 0; });
define("<=", [](double lhs, double rhs) -> Result<bool> { return lhs <= rhs; });
define("<=", [](const std::string& lhs, const std::string& rhs) -> Result<bool> { return lhs <= rhs; });
-
+ define("<=", [](const std::string& lhs, const std::string& rhs, const Collator& c) -> Result<bool> { return c.compare(lhs, rhs) <= 0; });
+
define("!", [](bool e) -> Result<bool> { return !e; });
define("is-supported-script", [](const std::string& x) -> Result<bool> {
@@ -397,89 +513,153 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
}
return s;
});
+ define("resolved-locale", [](const Collator& collator) -> Result<std::string> {
+ return collator.resolvedLocale();
+ });
+
define("error", [](const std::string& input) -> Result<type::ErrorType> {
return EvaluationError { input };
});
-
- return definitions;
-}
-std::unordered_map<std::string, Definition> CompoundExpressionRegistry::definitions = initializeDefinitions();
+ // Legacy Filters
+ define("filter-==", [](const EvaluationContext& params, const std::string& key, const Value &lhs) -> Result<bool> {
+ const auto rhs = featurePropertyAsExpressionValue(params, key);
+ return rhs ? lhs == *rhs : false;
+ });
-using namespace mbgl::style::conversion;
-ParseResult parseCompoundExpression(const std::string name, const Convertible& value, ParsingContext& ctx) {
- assert(isArray(value) && arrayLength(value) > 0);
+ define("filter-id-==", [](const EvaluationContext& params, const Value &lhs) -> Result<bool> {
+ return lhs == featureIdAsExpressionValue(params);
+ });
- auto it = CompoundExpressionRegistry::definitions.find(name);
- if (it == CompoundExpressionRegistry::definitions.end()) {
- ctx.error(
- R"(Unknown expression ")" + name + R"(". If you wanted a literal array, use ["literal", [...]].)",
- 0
- );
- return ParseResult();
- }
- const CompoundExpressionRegistry::Definition& definition = it->second;
+ define("filter-type-==", [](const EvaluationContext& params, const std::string &lhs) -> Result<bool> {
+ if (!params.feature) return false;
+ return featureTypeAsString(params.feature->getType()) == lhs;
+ });
+
+ define("filter-<", [](const EvaluationContext& params, const std::string& key, double lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsDouble(params, key);
+ return rhs ? rhs < lhs : false;
+ });
+
+ define("filter-<", [](const EvaluationContext& params, const std::string& key, std::string lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsString(params, key);
+ return rhs ? rhs < lhs : false;
+ });
+
+ define("filter-id-<", [](const EvaluationContext& params, double lhs) -> Result<bool> {
+ auto rhs = featureIdAsDouble(params);
+ return rhs ? rhs < lhs : false;
+ });
+
+ define("filter-id-<", [](const EvaluationContext& params, std::string lhs) -> Result<bool> {
+ auto rhs = featureIdAsString(params);
+ return rhs ? rhs < lhs : false;
+ });
+
+ define("filter->", [](const EvaluationContext& params, const std::string& key, double lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsDouble(params, key);
+ return rhs ? rhs > lhs : false;
+ });
+
+ define("filter->", [](const EvaluationContext& params, const std::string& key, std::string lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsString(params, key);
+ return rhs ? rhs > lhs : false;
+ });
+
+ define("filter-id->", [](const EvaluationContext& params, double lhs) -> Result<bool> {
+ auto rhs = featureIdAsDouble(params);
+ return rhs ? rhs > lhs : false;
+ });
+
+ define("filter-id->", [](const EvaluationContext& params, std::string lhs) -> Result<bool> {
+ auto rhs = featureIdAsString(params);
+ return rhs ? rhs > lhs : false;
+ });
+
+ define("filter-<=", [](const EvaluationContext& params, const std::string& key, double lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsDouble(params, key);
+ return rhs ? rhs <= lhs : false;
+ });
- auto length = arrayLength(value);
+ define("filter-<=", [](const EvaluationContext& params, const std::string& key, std::string lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsString(params, key);
+ return rhs ? rhs <= lhs : false;
+ });
- // Check if we have a single signature with the correct number of
- // parameters. If so, then use that signature's parameter types for parsing
- // (and inferring the types of) the arguments.
- optional<std::size_t> singleMatchingSignature;
- for (std::size_t j = 0; j < definition.size(); j++) {
- const std::unique_ptr<detail::SignatureBase>& signature = definition[j];
- if (
- signature->params.is<VarargsType>() ||
- signature->params.get<std::vector<type::Type>>().size() == length - 1
- ) {
- if (singleMatchingSignature) {
- singleMatchingSignature = {};
- } else {
- singleMatchingSignature = j;
- }
- }
- }
+ define("filter-id-<=", [](const EvaluationContext& params, double lhs) -> Result<bool> {
+ auto rhs = featureIdAsDouble(params);
+ return rhs ? rhs <= lhs : false;
+ });
+
+ define("filter-id-<=", [](const EvaluationContext& params, std::string lhs) -> Result<bool> {
+ auto rhs = featureIdAsString(params);
+ return rhs ? rhs <= lhs : false;
+ });
- // parse subexpressions first
- std::vector<std::unique_ptr<Expression>> args;
- args.reserve(length - 1);
- for (std::size_t i = 1; i < length; i++) {
- optional<type::Type> expected;
-
- if (singleMatchingSignature) {
- expected = definition[*singleMatchingSignature]->params.match(
- [](const VarargsType& varargs) { return varargs.type; },
- [&](const std::vector<type::Type>& params_) { return params_[i - 1]; }
- );
- }
+ define("filter->=", [](const EvaluationContext& params, const std::string& key, double lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsDouble(params, key);
+ return rhs ? rhs >= lhs : false;
+ });
- auto parsed = ctx.parse(arrayMember(value, i), i, expected);
- if (!parsed) {
- return parsed;
- }
- args.push_back(std::move(*parsed));
- }
- return createCompoundExpression(definition, std::move(args), ctx);
-}
+ define("filter->=", [](const EvaluationContext& params, const std::string& key, std::string lhs) -> Result<bool> {
+ auto rhs = featurePropertyAsString(params, key);
+ return rhs ? rhs >= lhs : false;
+ });
+ define("filter-id->=", [](const EvaluationContext& params, double lhs) -> Result<bool> {
+ auto rhs = featureIdAsDouble(params);
+ return rhs ? rhs >= lhs : false;
+ });
-ParseResult createCompoundExpression(const std::string& name,
- std::vector<std::unique_ptr<Expression>> args,
- ParsingContext& ctx)
-{
- return createCompoundExpression(CompoundExpressionRegistry::definitions.at(name), std::move(args), ctx);
+ define("filter-id->=", [](const EvaluationContext& params, std::string lhs) -> Result<bool> {
+ auto rhs = featureIdAsString(params);
+ return rhs ? rhs >= lhs : false;
+ });
+
+ define("filter-has", [](const EvaluationContext& params, const std::string& key) -> Result<bool> {
+ assert(params.feature);
+ return bool(params.feature->getValue(key));
+ });
+
+ define("filter-has-id", [](const EvaluationContext& params) -> Result<bool> {
+ assert(params.feature);
+ return bool(params.feature->getID());
+ });
+
+ define("filter-type-in", [](const EvaluationContext& params, const Varargs<std::string>& types) -> Result<bool> {
+ assert(params.feature);
+ optional<std::string> type = featureTypeAsString(params.feature->getType());
+ return std::find(types.begin(), types.end(), type) != types.end();
+ });
+
+ define("filter-id-in", [](const EvaluationContext& params, const Varargs<Value>& ids) -> Result<bool> {
+ auto id = featureIdAsExpressionValue(params);
+ return std::find(ids.begin(), ids.end(), id) != ids.end();
+ });
+
+ define("filter-in", [](const EvaluationContext& params, const Varargs<Value>& varargs) -> Result<bool> {
+ if (varargs.size() < 2) return false;
+ assert(varargs[0].is<std::string>());
+ auto value = featurePropertyAsExpressionValue(params, varargs[0].get<std::string>());
+ return value ? std::find(varargs.begin() + 1, varargs.end(), *value) != varargs.end() : false;
+ });
+
+ return definitions;
}
+std::unordered_map<std::string, Definition> CompoundExpressionRegistry::definitions = initializeDefinitions();
-ParseResult createCompoundExpression(const Definition& definition,
- std::vector<std::unique_ptr<Expression>> args,
- ParsingContext& ctx)
+using namespace mbgl::style::conversion;
+
+static ParseResult createCompoundExpression(const Definition& definition,
+ std::vector<std::unique_ptr<Expression>> args,
+ ParsingContext& ctx)
{
ParsingContext signatureContext(ctx.getKey());
-
+
for (const std::unique_ptr<detail::SignatureBase>& signature : definition) {
signatureContext.clearErrors();
-
+
if (signature->params.is<std::vector<type::Type>>()) {
const std::vector<type::Type>& params = signature->params.get<std::vector<type::Type>>();
if (params.size() != args.size()) {
@@ -507,35 +687,44 @@ ParseResult createCompoundExpression(const Definition& definition,
}
}
}
-
+
if (signatureContext.getErrors().size() == 0) {
return ParseResult(signature->makeExpression(std::move(args)));
}
}
-
+
if (definition.size() == 1) {
ctx.appendErrors(std::move(signatureContext));
} else {
- std::string signatures;
+ std::vector<std::string> availableOverloads; // Only used if there are no overloads with matching number of args
+ std::vector<std::string> overloads;
for (const auto& signature : definition) {
- signatures += (signatures.size() > 0 ? " | " : "");
signature->params.match(
[&](const VarargsType& varargs) {
- signatures += "(" + toString(varargs.type) + ")";
+ std::string overload = "(" + toString(varargs.type) + ")";
+ overloads.push_back(overload);
},
[&](const std::vector<type::Type>& params) {
- signatures += "(";
+ std::string overload = "(";
bool first = true;
for (const type::Type& param : params) {
- if (!first) signatures += ", ";
- signatures += toString(param);
+ if (!first) overload += ", ";
+ overload += toString(param);
first = false;
}
- signatures += ")";
+ overload += ")";
+ if (params.size() == args.size()) {
+ overloads.push_back(overload);
+ } else {
+ availableOverloads.push_back(overload);
+ }
}
);
-
+
}
+ std::string signatures = overloads.empty() ?
+ boost::algorithm::join(availableOverloads, " | ") :
+ boost::algorithm::join(overloads, " | ");
std::string actualTypes;
for (const auto& arg : args) {
if (actualTypes.size() > 0) {
@@ -545,10 +734,73 @@ ParseResult createCompoundExpression(const Definition& definition,
}
ctx.error("Expected arguments of type " + signatures + ", but found (" + actualTypes + ") instead.");
}
-
+
return ParseResult();
}
+ParseResult parseCompoundExpression(const std::string name, const Convertible& value, ParsingContext& ctx) {
+ assert(isArray(value) && arrayLength(value) > 0);
+
+ auto it = CompoundExpressionRegistry::definitions.find(name);
+ if (it == CompoundExpressionRegistry::definitions.end()) {
+ ctx.error(
+ R"(Unknown expression ")" + name + R"(". If you wanted a literal array, use ["literal", [...]].)",
+ 0
+ );
+ return ParseResult();
+ }
+ const CompoundExpressionRegistry::Definition& definition = it->second;
+
+ auto length = arrayLength(value);
+
+ // Check if we have a single signature with the correct number of
+ // parameters. If so, then use that signature's parameter types for parsing
+ // (and inferring the types of) the arguments.
+ optional<std::size_t> singleMatchingSignature;
+ for (std::size_t j = 0; j < definition.size(); j++) {
+ const std::unique_ptr<detail::SignatureBase>& signature = definition[j];
+ if (
+ signature->params.is<VarargsType>() ||
+ signature->params.get<std::vector<type::Type>>().size() == length - 1
+ ) {
+ if (singleMatchingSignature) {
+ singleMatchingSignature = {};
+ } else {
+ singleMatchingSignature = j;
+ }
+ }
+ }
+
+ // parse subexpressions first
+ std::vector<std::unique_ptr<Expression>> args;
+ args.reserve(length - 1);
+ for (std::size_t i = 1; i < length; i++) {
+ optional<type::Type> expected;
+
+ if (singleMatchingSignature) {
+ expected = definition[*singleMatchingSignature]->params.match(
+ [](const VarargsType& varargs) { return varargs.type; },
+ [&](const std::vector<type::Type>& params_) { return params_[i - 1]; }
+ );
+ }
+
+ auto parsed = ctx.parse(arrayMember(value, i), i, expected);
+ if (!parsed) {
+ return parsed;
+ }
+ args.push_back(std::move(*parsed));
+ }
+
+ return createCompoundExpression(definition, std::move(args), ctx);
+}
+
+ParseResult createCompoundExpression(const std::string& name,
+ std::vector<std::unique_ptr<Expression>> args,
+ ParsingContext& ctx)
+{
+ return createCompoundExpression(CompoundExpressionRegistry::definitions.at(name), std::move(args), ctx);
+}
+
} // namespace expression
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/expression/dsl.cpp b/src/mbgl/style/expression/dsl.cpp
new file mode 100644
index 0000000000..a851d82e16
--- /dev/null
+++ b/src/mbgl/style/expression/dsl.cpp
@@ -0,0 +1,183 @@
+#include <mbgl/style/expression/dsl.hpp>
+#include <mbgl/style/expression/error.hpp>
+#include <mbgl/style/expression/literal.hpp>
+#include <mbgl/style/expression/assertion.hpp>
+#include <mbgl/style/expression/coercion.hpp>
+#include <mbgl/style/expression/equals.hpp>
+#include <mbgl/style/expression/step.hpp>
+#include <mbgl/style/expression/interpolate.hpp>
+#include <mbgl/style/expression/compound_expression.hpp>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+namespace dsl {
+
+static std::unique_ptr<Expression> compound(const char* op, std::vector<std::unique_ptr<Expression>> args) {
+ ParsingContext ctx;
+ ParseResult result = createCompoundExpression(op, std::move(args), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+template <class... Args>
+static std::unique_ptr<Expression> compound(const char* op, Args... args) {
+ return compound(op, vec(std::move(args)...));
+}
+
+std::unique_ptr<Expression> error(std::string message) {
+ return std::make_unique<Error>(std::move(message));
+}
+
+std::unique_ptr<Expression> literal(const char* value) {
+ return literal(std::string(value));
+}
+
+std::unique_ptr<Expression> literal(Value value) {
+ return std::make_unique<Literal>(value);
+}
+
+std::unique_ptr<Expression> literal(std::initializer_list<double> value) {
+ std::vector<Value> values;
+ for (auto i : value) {
+ values.push_back(i);
+ }
+ return literal(values);
+}
+
+std::unique_ptr<Expression> literal(std::initializer_list<const char *> value) {
+ std::vector<Value> values;
+ for (auto i : value) {
+ values.push_back(std::string(i));
+ }
+ return literal(values);
+}
+
+std::unique_ptr<Expression> number(std::unique_ptr<Expression> value) {
+ return std::make_unique<Assertion>(type::Number, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> string(std::unique_ptr<Expression> value) {
+ return std::make_unique<Assertion>(type::String, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> boolean(std::unique_ptr<Expression> value) {
+ return std::make_unique<Assertion>(type::Boolean, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> toColor(std::unique_ptr<Expression> value) {
+ return std::make_unique<Coercion>(type::Color, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> toString(std::unique_ptr<Expression> value) {
+ return compound("to-string", std::move(value));
+}
+
+std::unique_ptr<Expression> get(const char* value) {
+ return get(literal(value));
+}
+
+std::unique_ptr<Expression> get(std::unique_ptr<Expression> property) {
+ return compound("get", std::move(property));
+}
+
+std::unique_ptr<Expression> id() {
+ return compound("id");
+}
+
+std::unique_ptr<Expression> zoom() {
+ return compound("zoom");
+}
+
+std::unique_ptr<Expression> eq(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return std::make_unique<Equals>(std::move(lhs), std::move(rhs), nullopt, false);
+}
+
+std::unique_ptr<Expression> ne(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return std::make_unique<Equals>(std::move(lhs), std::move(rhs), nullopt, true);
+}
+
+std::unique_ptr<Expression> gt(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return compound(">", std::move(lhs), std::move(rhs));
+}
+
+std::unique_ptr<Expression> lt(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return compound("<", std::move(lhs), std::move(rhs));
+}
+
+std::unique_ptr<Expression> step(std::unique_ptr<Expression> input,
+ std::unique_ptr<Expression> output0,
+ double input1, std::unique_ptr<Expression> output1) {
+ type::Type type = output0->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[-std::numeric_limits<double>::infinity()] = std::move(output0);
+ stops[input1] = std::move(output1);
+ return std::make_unique<Step>(type, std::move(input), std::move(stops));
+}
+
+Interpolator linear() {
+ return ExponentialInterpolator(1.0);
+}
+
+Interpolator exponential(double base) {
+ return ExponentialInterpolator(base);
+}
+
+Interpolator cubicBezier(double x1, double y1, double x2, double y2) {
+ return CubicBezierInterpolator(x1, y1, x2, y2);
+}
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1) {
+ type::Type type = output1->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[input1] = std::move(output1);
+ ParsingContext ctx;
+ ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2) {
+ type::Type type = output1->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[input1] = std::move(output1);
+ stops[input2] = std::move(output2);
+ ParsingContext ctx;
+ ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2,
+ double input3, std::unique_ptr<Expression> output3) {
+ type::Type type = output1->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[input1] = std::move(output1);
+ stops[input2] = std::move(output2);
+ stops[input3] = std::move(output3);
+ ParsingContext ctx;
+ ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inputs) {
+ return compound("concat", std::move(inputs));
+}
+
+} // namespace dsl
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/expression/equals.cpp b/src/mbgl/style/expression/equals.cpp
index 6d963cc1d8..73e2baf71b 100644
--- a/src/mbgl/style/expression/equals.cpp
+++ b/src/mbgl/style/expression/equals.cpp
@@ -1,14 +1,25 @@
+#include <mbgl/style/expression/collator.hpp>
#include <mbgl/style/expression/equals.hpp>
namespace mbgl {
namespace style {
namespace expression {
-Equals::Equals(std::unique_ptr<Expression> lhs_, std::unique_ptr<Expression> rhs_, bool negate_)
- : Expression(type::Boolean),
+static bool isComparableType(const type::Type& type) {
+ return type == type::String ||
+ type == type::Number ||
+ type == type::Boolean ||
+ type == type::Null;
+}
+
+Equals::Equals(std::unique_ptr<Expression> lhs_, std::unique_ptr<Expression> rhs_, optional<std::unique_ptr<Expression>> collator_, bool negate_)
+ : Expression(Kind::Equals, type::Boolean),
lhs(std::move(lhs_)),
rhs(std::move(rhs_)),
+ collator(std::move(collator_)),
negate(negate_) {
+ assert(isComparableType(lhs->getType()) || isComparableType(rhs->getType()));
+ assert(lhs->getType() == rhs->getType() || lhs->getType() == type::Value || rhs->getType() == type::Value);
}
EvaluationResult Equals::evaluate(const EvaluationContext& params) const {
@@ -18,7 +29,15 @@ EvaluationResult Equals::evaluate(const EvaluationContext& params) const {
EvaluationResult rhsResult = rhs->evaluate(params);
if (!rhsResult) return lhsResult;
- bool result = *lhsResult == *rhsResult;
+ bool result;
+
+ if (collator) {
+ auto collatorResult = (*collator)->evaluate(params);
+ const Collator& c = collatorResult->get<Collator>();
+ result = c.compare(lhsResult->get<std::string>(), rhsResult->get<std::string>()) == 0;
+ } else {
+ result = *lhsResult == *rhsResult;
+ }
if (negate) {
result = !result;
}
@@ -28,10 +47,14 @@ EvaluationResult Equals::evaluate(const EvaluationContext& params) const {
void Equals::eachChild(const std::function<void(const Expression&)>& visit) const {
visit(*lhs);
visit(*rhs);
+ if (collator) {
+ visit(**collator);
+ }
}
bool Equals::operator==(const Expression& e) const {
- if (auto eq = dynamic_cast<const Equals*>(&e)) {
+ if (e.getKind() == Kind::Equals) {
+ auto eq = static_cast<const Equals*>(&e);
return eq->negate == negate && *eq->lhs == *lhs && *eq->rhs == *rhs;
}
return false;
@@ -41,19 +64,12 @@ std::vector<optional<Value>> Equals::possibleOutputs() const {
return {{ true }, { false }};
}
-static bool isComparableType(const type::Type& type) {
- return type == type::String ||
- type == type::Number ||
- type == type::Boolean ||
- type == type::Null;
-}
-
using namespace mbgl::style::conversion;
ParseResult Equals::parse(const Convertible& value, ParsingContext& ctx) {
std::size_t length = arrayLength(value);
- if (length != 3) {
- ctx.error("Expected two arguments.");
+ if (length != 3 && length != 4) {
+ ctx.error("Expected two or three arguments.");
return ParseResult();
}
@@ -78,8 +94,18 @@ ParseResult Equals::parse(const Convertible& value, ParsingContext& ctx) {
ctx.error("Cannot compare " + toString(lhsType) + " and " + toString(rhsType) + ".");
return ParseResult();
}
+
+ ParseResult collatorParseResult;
+ if (length == 4) {
+ if (lhsType != type::String && rhsType != type::String) {
+ ctx.error("Cannot use collator to compare non-string types.");
+ return ParseResult();
+ }
+ collatorParseResult = ctx.parse(arrayMember(value, 3), 3, {type::Collator});
+ if (!collatorParseResult) return ParseResult();
+ }
- return ParseResult(std::make_unique<Equals>(std::move(*lhs), std::move(*rhs), negate));
+ return ParseResult(std::make_unique<Equals>(std::move(*lhs), std::move(*rhs), std::move(collatorParseResult), negate));
}
} // namespace expression
diff --git a/src/mbgl/style/function/expression.cpp b/src/mbgl/style/expression/expression.cpp
index d9dbbfa1d3..d9dbbfa1d3 100644
--- a/src/mbgl/style/function/expression.cpp
+++ b/src/mbgl/style/expression/expression.cpp
diff --git a/src/mbgl/style/expression/find_zoom_curve.cpp b/src/mbgl/style/expression/find_zoom_curve.cpp
index 5d39e0791e..a27f8560ef 100644
--- a/src/mbgl/style/expression/find_zoom_curve.cpp
+++ b/src/mbgl/style/expression/find_zoom_curve.cpp
@@ -2,6 +2,7 @@
#include <mbgl/style/expression/compound_expression.hpp>
#include <mbgl/style/expression/let.hpp>
#include <mbgl/style/expression/coalesce.hpp>
+#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/util/variant.hpp>
#include <mbgl/util/optional.hpp>
@@ -10,12 +11,17 @@ namespace mbgl {
namespace style {
namespace expression {
-optional<variant<const InterpolateBase*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e) {
- optional<variant<const InterpolateBase*, const Step*, ParsingError>> result;
+optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e) {
+ optional<variant<const Interpolate*, const Step*, ParsingError>> result;
- if (auto let = dynamic_cast<const Let*>(e)) {
+ switch (e->getKind()) {
+ case Kind::Let: {
+ auto let = static_cast<const Let*>(e);
result = findZoomCurve(let->getResult());
- } else if (auto coalesce = dynamic_cast<const Coalesce*>(e)) {
+ break;
+ }
+ case Kind::Coalesce: {
+ auto coalesce = static_cast<const Coalesce*>(e);
std::size_t length = coalesce->getLength();
for (std::size_t i = 0; i < length; i++) {
result = findZoomCurve(coalesce->getChild(i));
@@ -23,16 +29,30 @@ optional<variant<const InterpolateBase*, const Step*, ParsingError>> findZoomCur
break;
}
}
- } else if (auto curve = dynamic_cast<const InterpolateBase*>(e)) {
- auto z = dynamic_cast<CompoundExpressionBase*>(curve->getInput().get());
- if (z && z->getName() == "zoom") {
- result = {curve};
+ break;
+ }
+ case Kind::Interpolate: {
+ auto curve = static_cast<const Interpolate*>(e);
+ if (curve->getInput()->getKind() == Kind::CompoundExpression) {
+ auto z = static_cast<CompoundExpressionBase*>(curve->getInput().get());
+ if (z && z->getName() == "zoom") {
+ result = {curve};
+ }
}
- } else if (auto step = dynamic_cast<const Step*>(e)) {
- auto z = dynamic_cast<CompoundExpressionBase*>(step->getInput().get());
- if (z && z->getName() == "zoom") {
- result = {step};
+ break;
+ }
+ case Kind::Step: {
+ auto step = static_cast<const Step*>(e);
+ if (step->getInput()->getKind() == Kind::CompoundExpression) {
+ auto z = static_cast<CompoundExpressionBase*>(step->getInput().get());
+ if (z && z->getName() == "zoom") {
+ result = {step};
+ }
}
+ break;
+ }
+ default:
+ break;
}
if (result && result->is<ParsingError>()) {
@@ -40,7 +60,7 @@ optional<variant<const InterpolateBase*, const Step*, ParsingError>> findZoomCur
}
e->eachChild([&](const Expression& child) {
- optional<variant<const InterpolateBase*, const Step*, ParsingError>> childResult(findZoomCurve(&child));
+ optional<variant<const Interpolate*, const Step*, ParsingError>> childResult(findZoomCurve(&child));
if (childResult) {
if (childResult->is<ParsingError>()) {
result = childResult;
@@ -59,14 +79,17 @@ optional<variant<const InterpolateBase*, const Step*, ParsingError>> findZoomCur
return result;
}
-variant<const InterpolateBase*, const Step*> findZoomCurveChecked(const expression::Expression* e) {
+variant<std::nullptr_t, const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e) {
+ if (isZoomConstant(*e)) {
+ return nullptr;
+ }
return findZoomCurve(e)->match(
- [](const ParsingError&) -> variant<const InterpolateBase*, const Step*> {
+ [](const ParsingError&) -> variant<std::nullptr_t, const Interpolate*, const Step*> {
assert(false);
- return {};
+ return nullptr;
},
- [](auto zoomCurve) -> variant<const InterpolateBase*, const Step*> {
- return {std::move(zoomCurve)};
+ [](auto zoomCurve) -> variant<std::nullptr_t, const Interpolate*, const Step*> {
+ return zoomCurve;
}
);
}
diff --git a/src/mbgl/style/expression/interpolate.cpp b/src/mbgl/style/expression/interpolate.cpp
index daad8523f2..54fbc6e1d7 100644
--- a/src/mbgl/style/expression/interpolate.cpp
+++ b/src/mbgl/style/expression/interpolate.cpp
@@ -5,11 +5,77 @@ namespace mbgl {
namespace style {
namespace expression {
-using Interpolator = variant<ExponentialInterpolator,
- CubicBezierInterpolator>;
-
using namespace mbgl::style::conversion;
+template <typename T>
+class InterpolateImpl : public Interpolate {
+public:
+ InterpolateImpl(type::Type type_,
+ Interpolator interpolator_,
+ std::unique_ptr<Expression> input_,
+ std::map<double, std::unique_ptr<Expression>> stops_
+ ) : Interpolate(std::move(type_), std::move(interpolator_), std::move(input_), std::move(stops_))
+ {
+ static_assert(util::Interpolatable<T>::value, "Interpolate expression requires an interpolatable value type.");
+ }
+
+ EvaluationResult evaluate(const EvaluationContext& params) const override {
+ const EvaluationResult evaluatedInput = input->evaluate(params);
+ if (!evaluatedInput) {
+ return evaluatedInput.error();
+ }
+
+ float x = *fromExpressionValue<float>(*evaluatedInput);
+ if (std::isnan(x)) {
+ return EvaluationError { "Input is not a number." };
+ }
+
+ if (stops.empty()) {
+ return EvaluationError { "No stops in exponential curve." };
+ }
+
+ auto it = stops.upper_bound(x);
+ if (it == stops.end()) {
+ return stops.rbegin()->second->evaluate(params);
+ } else if (it == stops.begin()) {
+ return stops.begin()->second->evaluate(params);
+ } else {
+ float t = interpolationFactor({ std::prev(it)->first, it->first }, x);
+
+ if (t == 0.0f) {
+ return std::prev(it)->second->evaluate(params);
+ }
+ if (t == 1.0f) {
+ return it->second->evaluate(params);
+ }
+
+ EvaluationResult lower = std::prev(it)->second->evaluate(params);
+ if (!lower) {
+ return lower.error();
+ }
+ EvaluationResult upper = it->second->evaluate(params);
+ if (!upper) {
+ return upper.error();
+ }
+
+ if (!lower->is<T>()) {
+ return EvaluationError {
+ "Expected value to be of type " + toString(valueTypeToExpressionType<T>()) +
+ ", but found " + toString(typeOf(*lower)) + " instead."
+ };
+ }
+
+ if (!upper->is<T>()) {
+ return EvaluationError {
+ "Expected value to be of type " + toString(valueTypeToExpressionType<T>()) +
+ ", but found " + toString(typeOf(*upper)) + " instead."
+ };
+ }
+ return util::interpolate(lower->get<T>(), upper->get<T>(), t);
+ }
+ }
+};
+
ParseResult parseInterpolate(const Convertible& value, ParsingContext& ctx) {
assert(isArray(value));
@@ -104,23 +170,23 @@ ParseResult parseInterpolate(const Convertible& value, ParsingContext& ctx) {
labelValue->match(
[&](uint64_t n) {
if (n > std::numeric_limits<double>::max()) {
- label = {std::numeric_limits<double>::infinity()};
+ label = optional<double>{std::numeric_limits<double>::infinity()};
} else {
- label = {static_cast<double>(n)};
+ label = optional<double>{static_cast<double>(n)};
}
},
[&](int64_t n) {
if (n > std::numeric_limits<double>::max()) {
- label = {std::numeric_limits<double>::infinity()};
+ label = optional<double>{std::numeric_limits<double>::infinity()};
} else {
- label = {static_cast<double>(n)};
+ label = optional<double>{static_cast<double>(n)};
}
},
[&](double n) {
if (n > std::numeric_limits<double>::max()) {
- label = {std::numeric_limits<double>::infinity()};
+ label = optional<double>{std::numeric_limits<double>::infinity()};
} else {
- label = {static_cast<double>(n)};
+ label = optional<double>{n};
}
},
[&](const auto&) {}
@@ -154,59 +220,58 @@ ParseResult parseInterpolate(const Convertible& value, ParsingContext& ctx) {
}
assert(outputType);
-
- if (
- *outputType != type::Number &&
- *outputType != type::Color &&
- !(
- outputType->is<type::Array>() &&
- outputType->get<type::Array>().itemType == type::Number &&
- outputType->get<type::Array>().N
- )
- )
- {
- ctx.error("Type " + toString(*outputType) + " is not interpolatable.");
- return ParseResult();
- }
-
- return outputType->match(
+
+ return createInterpolate(*outputType,
+ *interpolator,
+ std::move(*input),
+ std::move(stops),
+ ctx);
+}
+
+ParseResult createInterpolate(type::Type type,
+ Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ std::map<double, std::unique_ptr<Expression>> stops,
+ ParsingContext& ctx) {
+ return type.match(
[&](const type::NumberType&) -> ParseResult {
- return interpolator->match([&](const auto& interpolator_) {
- return ParseResult(std::make_unique<Interpolate<double>>(
- *outputType, interpolator_, std::move(*input), std::move(stops)
- ));
- });
+ return ParseResult(std::make_unique<InterpolateImpl<double>>(
+ type, interpolator, std::move(input), std::move(stops)
+ ));
},
[&](const type::ColorType&) -> ParseResult {
- return interpolator->match([&](const auto& interpolator_) {
- return ParseResult(std::make_unique<Interpolate<Color>>(
- *outputType, interpolator_, std::move(*input), std::move(stops)
- ));
- });
+ return ParseResult(std::make_unique<InterpolateImpl<Color>>(
+ type, interpolator, std::move(input), std::move(stops)
+ ));
},
[&](const type::Array& arrayType) -> ParseResult {
- return interpolator->match(
- [&](const auto& continuousInterpolator) {
- if (arrayType.itemType != type::Number || !arrayType.N) {
- assert(false); // interpolability already checked above.
- return ParseResult();
- }
- return ParseResult(std::make_unique<Interpolate<std::vector<Value>>>(
- *outputType, continuousInterpolator, std::move(*input), std::move(stops)
- ));
- }
- );
+ if (arrayType.itemType != type::Number || !arrayType.N) {
+ ctx.error("Type " + toString(type) + " is not interpolatable.");
+ return ParseResult();
+ }
+ return ParseResult(std::make_unique<InterpolateImpl<std::vector<Value>>>(
+ type, interpolator, std::move(input), std::move(stops)
+ ));
},
[&](const auto&) {
- // unreachable: Null, Boolean, String, Object, Value output types
- // are not interpolatable, and interpolability was already checked above
- assert(false);
+ ctx.error("Type " + toString(type) + " is not interpolatable.");
return ParseResult();
}
);
}
-std::vector<optional<Value>> InterpolateBase::possibleOutputs() const {
+Interpolate::Interpolate(const type::Type& type_,
+ Interpolator interpolator_,
+ std::unique_ptr<Expression> input_,
+ std::map<double, std::unique_ptr<Expression>> stops_)
+ : Expression(Kind::Interpolate, type_),
+ interpolator(std::move(interpolator_)),
+ input(std::move(input_)),
+ stops(std::move(stops_)) {
+ assert(input->getType() == type::Number);
+}
+
+std::vector<optional<Value>> Interpolate::possibleOutputs() const {
std::vector<optional<Value>> result;
for (const auto& stop : stops) {
for (auto& output : stop.second->possibleOutputs()) {
@@ -216,8 +281,7 @@ std::vector<optional<Value>> InterpolateBase::possibleOutputs() const {
return result;
}
-template <typename T>
-mbgl::Value Interpolate<T>::serialize() const {
+mbgl::Value Interpolate::serialize() const {
std::vector<mbgl::Value> serialized;
serialized.emplace_back(getOperator());
diff --git a/src/mbgl/style/expression/is_constant.cpp b/src/mbgl/style/expression/is_constant.cpp
index 0ebb37faa9..3b1f1aba8c 100644
--- a/src/mbgl/style/expression/is_constant.cpp
+++ b/src/mbgl/style/expression/is_constant.cpp
@@ -1,17 +1,25 @@
#include <mbgl/style/expression/is_constant.hpp>
+#include <mbgl/style/expression/collator_expression.hpp>
+
namespace mbgl {
namespace style {
namespace expression {
+constexpr static const char filter[] = "filter-";
+
bool isFeatureConstant(const Expression& expression) {
- if (auto e = dynamic_cast<const CompoundExpressionBase*>(&expression)) {
+ if (expression.getKind() == Kind::CompoundExpression) {
+ auto e = static_cast<const CompoundExpressionBase*>(&expression);
const std::string name = e->getName();
optional<std::size_t> parameterCount = e->getParameterCount();
if (name == "get" && parameterCount && *parameterCount == 1) {
return false;
} else if (name == "has" && parameterCount && *parameterCount == 1) {
return false;
+ } else if (std::equal(std::begin(filter), std::end(filter) - 1, name.begin())) {
+ // Legacy filters begin with "filter-" and are never constant.
+ return false;
} else if (
name == "properties" ||
name == "geometry-type" ||
@@ -20,6 +28,13 @@ bool isFeatureConstant(const Expression& expression) {
return false;
}
}
+
+ if (expression.getKind() == Kind::CollatorExpression) {
+ // Although the results of a Collator expression with fixed arguments
+ // generally shouldn't change between executions, we can't serialize them
+ // as constant expressions because results change based on environment.
+ return false;
+ }
bool featureConstant = true;
expression.eachChild([&](const Expression& e) {
diff --git a/src/mbgl/style/expression/length.cpp b/src/mbgl/style/expression/length.cpp
index 258353ae4e..ad7a15675a 100644
--- a/src/mbgl/style/expression/length.cpp
+++ b/src/mbgl/style/expression/length.cpp
@@ -6,7 +6,7 @@ namespace style {
namespace expression {
Length::Length(std::unique_ptr<Expression> input_)
- : Expression(type::Number),
+ : Expression(Kind::Length, type::Number),
input(std::move(input_)) {
}
@@ -30,7 +30,8 @@ void Length::eachChild(const std::function<void(const Expression&)>& visit) cons
}
bool Length::operator==(const Expression& e) const {
- if (auto eq = dynamic_cast<const Length*>(&e)) {
+ if (e.getKind() == Kind::Length) {
+ auto eq = static_cast<const Length*>(&e);
return *eq->input == *input;
}
return false;
diff --git a/src/mbgl/style/expression/literal.cpp b/src/mbgl/style/expression/literal.cpp
index 8a63980dba..345a52de9b 100644
--- a/src/mbgl/style/expression/literal.cpp
+++ b/src/mbgl/style/expression/literal.cpp
@@ -113,4 +113,3 @@ mbgl::Value Literal::serialize() const {
} // namespace expression
} // namespace style
} // namespace mbgl
-
diff --git a/src/mbgl/style/expression/match.cpp b/src/mbgl/style/expression/match.cpp
index 3d41f0bdd3..4b4984811f 100644
--- a/src/mbgl/style/expression/match.cpp
+++ b/src/mbgl/style/expression/match.cpp
@@ -18,7 +18,8 @@ void Match<T>::eachChild(const std::function<void(const Expression&)>& visit) co
template <typename T>
bool Match<T>::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Match*>(&e)) {
+ if (e.getKind() == Kind::Match) {
+ auto rhs = static_cast<const Match*>(&e);
return (*input == *(rhs->input) &&
*otherwise == *(rhs->otherwise) &&
Expression::childrenEqual(branches, rhs->branches));
@@ -83,6 +84,10 @@ template<> EvaluationResult Match<std::string>::evaluate(const EvaluationContext
return inputValue.error();
}
+ if (!inputValue->is<std::string>()) {
+ return otherwise->evaluate(params);
+ }
+
auto it = branches.find(inputValue->get<std::string>());
if (it != branches.end()) {
return (*it).second->evaluate(params);
@@ -96,7 +101,11 @@ template<> EvaluationResult Match<int64_t>::evaluate(const EvaluationContext& pa
if (!inputValue) {
return inputValue.error();
}
-
+
+ if (!inputValue->is<double>()) {
+ return otherwise->evaluate(params);
+ }
+
const auto numeric = inputValue->get<double>();
int64_t rounded = std::floor(numeric);
if (numeric == rounded) {
@@ -129,7 +138,7 @@ optional<InputType> parseInputValue(const Convertible& input, ParsingContext& pa
parentContext.error("Branch labels must be integers no larger than " + util::toString(Value::maxSafeInteger()) + ".", index);
} else {
type = {type::Number};
- result = {static_cast<int64_t>(n)};
+ result = optional<InputType>{static_cast<int64_t>(n)};
}
},
[&] (int64_t n) {
@@ -137,7 +146,7 @@ optional<InputType> parseInputValue(const Convertible& input, ParsingContext& pa
parentContext.error("Branch labels must be integers no larger than " + util::toString(Value::maxSafeInteger()) + ".", index);
} else {
type = {type::Number};
- result = {n};
+ result = optional<InputType>{n};
}
},
[&] (double n) {
@@ -147,7 +156,7 @@ optional<InputType> parseInputValue(const Convertible& input, ParsingContext& pa
parentContext.error("Numeric branch labels must be integer values.", index);
} else {
type = {type::Number};
- result = {static_cast<int64_t>(n)};
+ result = optional<InputType>{static_cast<int64_t>(n)};
}
},
[&] (const std::string& s) {
@@ -280,7 +289,7 @@ ParseResult parseMatch(const Convertible& value, ParsingContext& ctx) {
branches.push_back(std::make_pair(std::move(labels), std::move(*output)));
}
- auto input = ctx.parse(arrayMember(value, 1), 1, inputType);
+ auto input = ctx.parse(arrayMember(value, 1), 1, {type::Value});
if (!input) {
return ParseResult();
}
@@ -292,6 +301,12 @@ ParseResult parseMatch(const Convertible& value, ParsingContext& ctx) {
assert(inputType && outputType);
+ optional<std::string> err;
+ if ((*input)->getType() != type::Value && (err = type::checkSubtype(*inputType, (*input)->getType()))) {
+ ctx.error(*err, 1);
+ return ParseResult();
+ }
+
return inputType->match(
[&](const type::NumberType&) {
return create<int64_t>(*outputType, std::move(*input), std::move(branches), std::move(*otherwise), ctx);
diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp
index b522aeff9a..a4c04b03b1 100644
--- a/src/mbgl/style/expression/parsing_context.cpp
+++ b/src/mbgl/style/expression/parsing_context.cpp
@@ -32,19 +32,21 @@ namespace style {
namespace expression {
bool isConstant(const Expression& expression) {
- if (auto varExpression = dynamic_cast<const Var*>(&expression)) {
+ if (expression.getKind() == Kind::Var) {
+ auto varExpression = static_cast<const Var*>(&expression);
return isConstant(*varExpression->getBoundExpression());
}
- if (auto compound = dynamic_cast<const CompoundExpressionBase*>(&expression)) {
+ if (expression.getKind() == Kind::CompoundExpression) {
+ auto compound = static_cast<const CompoundExpressionBase*>(&expression);
if (compound->getName() == "error") {
return false;
}
}
- bool isTypeAnnotation = dynamic_cast<const Coercion*>(&expression) ||
- dynamic_cast<const Assertion*>(&expression) ||
- dynamic_cast<const ArrayAssertion*>(&expression);
+ bool isTypeAnnotation = expression.getKind() == Kind::Coercion ||
+ expression.getKind() == Kind::Assertion ||
+ expression.getKind() == Kind::ArrayAssertion;
bool childrenConstant = true;
expression.eachChild([&](const Expression& child) {
@@ -58,7 +60,7 @@ bool isConstant(const Expression& expression) {
if (isTypeAnnotation) {
childrenConstant = childrenConstant && isConstant(child);
} else {
- childrenConstant = childrenConstant && dynamic_cast<const Literal*>(&child);
+ childrenConstant = childrenConstant && child.getKind() == Kind::Literal;
}
});
if (!childrenConstant) {
@@ -102,6 +104,7 @@ const ExpressionRegistry& getExpressionRegistry() {
{"boolean", Assertion::parse},
{"case", Case::parse},
{"coalesce", Coalesce::parse},
+ {"collator", CollatorExpression::parse},
{"interpolate", parseInterpolate},
{"length", Length::parse},
{"let", Let::parse},
@@ -185,7 +188,7 @@ ParseResult ParsingContext::parse(const Convertible& value, TypeAnnotationOption
// If an expression's arguments are all constant, we can evaluate
// it immediately and replace it with a literal value in the
// parsed result.
- if (!dynamic_cast<Literal *>(parsed->get()) && isConstant(**parsed)) {
+ if ((*parsed)->getKind() != Kind::Literal && isConstant(**parsed)) {
EvaluationContext params(nullptr);
EvaluationResult evaluated((*parsed)->evaluate(params));
if (!evaluated) {
@@ -216,7 +219,7 @@ ParseResult ParsingContext::parseExpression(const Convertible& value, TypeAnnota
ParseResult ParsingContext::parseLayerPropertyExpression(const Convertible& value, TypeAnnotationOption typeAnnotationOption) {
ParseResult parsed = parse(value, typeAnnotationOption);
if (parsed && !isZoomConstant(**parsed)) {
- optional<variant<const InterpolateBase*, const Step*, ParsingError>> zoomCurve = findZoomCurve(parsed->get());
+ optional<variant<const Interpolate*, const Step*, ParsingError>> zoomCurve = findZoomCurve(parsed->get());
if (!zoomCurve) {
error(R"("zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.)");
return ParseResult();
diff --git a/src/mbgl/style/expression/step.cpp b/src/mbgl/style/expression/step.cpp
index ddaf9417cb..a1ca0a702e 100644
--- a/src/mbgl/style/expression/step.cpp
+++ b/src/mbgl/style/expression/step.cpp
@@ -8,6 +8,16 @@ namespace mbgl {
namespace style {
namespace expression {
+Step::Step(const type::Type& type_,
+ std::unique_ptr<Expression> input_,
+ std::map<double, std::unique_ptr<Expression>> stops_)
+ : Expression(Kind::Step, type_),
+ input(std::move(input_)),
+ stops(std::move(stops_))
+{
+ assert(input->getType() == type::Number);
+}
+
EvaluationResult Step::evaluate(const EvaluationContext& params) const {
const EvaluationResult evaluatedInput = input->evaluate(params);
if (!evaluatedInput) {
@@ -47,7 +57,8 @@ void Step::eachStop(const std::function<void(double, const Expression&)>& visit)
}
bool Step::operator==(const Expression& e) const {
- if (auto rhs = dynamic_cast<const Step*>(&e)) {
+ if (e.getKind() == Kind::Step) {
+ auto rhs = static_cast<const Step*>(&e);
return *input == *(rhs->input) && Expression::childrenEqual(stops, rhs->stops);
}
return false;
@@ -116,23 +127,23 @@ ParseResult Step::parse(const mbgl::style::conversion::Convertible& value, Parsi
labelValue->match(
[&](uint64_t n) {
if (n > std::numeric_limits<double>::max()) {
- label = {std::numeric_limits<double>::infinity()};
+ label = optional<double>{std::numeric_limits<double>::infinity()};
} else {
- label = {static_cast<double>(n)};
+ label = optional<double>{static_cast<double>(n)};
}
},
[&](int64_t n) {
if (n > std::numeric_limits<double>::max()) {
- label = {std::numeric_limits<double>::infinity()};
+ label = optional<double>{std::numeric_limits<double>::infinity()};
} else {
- label = {static_cast<double>(n)};
+ label = optional<double>{static_cast<double>(n)};
}
},
[&](double n) {
if (n > std::numeric_limits<double>::max()) {
- label = {std::numeric_limits<double>::infinity()};
+ label = optional<double>{std::numeric_limits<double>::infinity()};
} else {
- label = {static_cast<double>(n)};
+ label = optional<double>{n};
}
},
[&](const auto&) {}
diff --git a/src/mbgl/style/expression/value.cpp b/src/mbgl/style/expression/value.cpp
index 1b3257c755..ddf1ff0ca4 100644
--- a/src/mbgl/style/expression/value.cpp
+++ b/src/mbgl/style/expression/value.cpp
@@ -12,6 +12,7 @@ type::Type typeOf(const Value& value) {
[&](double) -> type::Type { return type::Number; },
[&](const std::string&) -> type::Type { return type::String; },
[&](const Color&) -> type::Type { return type::Color; },
+ [&](const Collator&) -> type::Type { return type::Collator; },
[&](const NullValue&) -> type::Type { return type::Null; },
[&](const std::unordered_map<std::string, Value>&) -> type::Type { return type::Object; },
[&](const std::vector<Value>& arr) -> type::Type {
@@ -43,6 +44,11 @@ void writeJSON(rapidjson::Writer<rapidjson::StringBuffer>& writer, const Value&
},
[&] (const std::string& s) { writer.String(s); },
[&] (const Color& c) { writer.String(c.stringify()); },
+ [&] (const Collator&) {
+ // Collators are excluded from constant folding and there's no Literal parser
+ // for them so there shouldn't be any way to serialize this value.
+ assert(false);
+ },
[&] (const std::vector<Value>& arr) {
writer.StartArray();
for(const auto& item : arr) {
@@ -115,6 +121,12 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value)
array[3],
};
},
+ [&](const Collator&)->mbgl::Value {
+ // fromExpressionValue can't be used for Collator values,
+ // because they have no meaningful representation as an mbgl::Value
+ assert(false);
+ return mbgl::Value();
+ },
[&](const std::vector<Value>& values)->mbgl::Value {
std::vector<mbgl::Value> converted;
converted.reserve(values.size());
@@ -229,27 +241,6 @@ optional<T> ValueConverter<T, std::enable_if_t< std::is_enum<T>::value >>::fromE
);
}
-
-Value toExpressionValue(const Value& v) {
- return v;
-}
-
-template <typename T, typename Enable>
-Value toExpressionValue(const T& value) {
- return ValueConverter<T>::toExpressionValue(value);
-}
-
-optional<Value> fromExpressionValue(const Value& v) {
- return optional<Value>(v);
-}
-
-template <typename T>
-std::enable_if_t< !std::is_convertible<T, Value>::value,
-optional<T>> fromExpressionValue(const Value& v)
-{
- return ValueConverter<T>::fromExpressionValue(v);
-}
-
template <typename T>
type::Type valueTypeToExpressionType() {
return ValueConverter<T>::expressionType();
@@ -261,6 +252,7 @@ template <> type::Type valueTypeToExpressionType<bool>() { return type::Boolean;
template <> type::Type valueTypeToExpressionType<double>() { return type::Number; }
template <> type::Type valueTypeToExpressionType<std::string>() { return type::String; }
template <> type::Type valueTypeToExpressionType<Color>() { return type::Color; }
+template <> type::Type valueTypeToExpressionType<Collator>() { return type::Collator; }
template <> type::Type valueTypeToExpressionType<std::unordered_map<std::string, Value>>() { return type::Object; }
template <> type::Type valueTypeToExpressionType<std::vector<Value>>() { return type::Array(type::Value); }
@@ -268,86 +260,64 @@ template <> type::Type valueTypeToExpressionType<std::vector<Value>>() { return
template <> type::Type valueTypeToExpressionType<type::ErrorType>() { return type::Error; }
-template Value toExpressionValue(const mbgl::Value&);
-template optional<mbgl::Value> fromExpressionValue<mbgl::Value>(const Value&);
-
// for to_rgba expression
template type::Type valueTypeToExpressionType<std::array<double, 4>>();
-template optional<std::array<double, 4>> fromExpressionValue<std::array<double, 4>>(const Value&);
-template Value toExpressionValue(const std::array<double, 4>&);
+template struct ValueConverter<std::array<double, 4>>;
// layout/paint property types
template type::Type valueTypeToExpressionType<float>();
-template optional<float> fromExpressionValue<float>(const Value&);
-template Value toExpressionValue(const float&);
+template type::Type valueTypeToExpressionType<Position>();
template type::Type valueTypeToExpressionType<std::array<float, 2>>();
-template optional<std::array<float, 2>> fromExpressionValue<std::array<float, 2>>(const Value&);
-template Value toExpressionValue(const std::array<float, 2>&);
+template struct ValueConverter<std::array<float, 2>>;
template type::Type valueTypeToExpressionType<std::array<float, 4>>();
-template optional<std::array<float, 4>> fromExpressionValue<std::array<float, 4>>(const Value&);
-template Value toExpressionValue(const std::array<float, 4>&);
+template struct ValueConverter<std::array<float, 4>>;
template type::Type valueTypeToExpressionType<std::vector<float>>();
-template optional<std::vector<float>> fromExpressionValue<std::vector<float>>(const Value&);
-template Value toExpressionValue(const std::vector<float>&);
+template struct ValueConverter<std::vector<float>>;
template type::Type valueTypeToExpressionType<std::vector<std::string>>();
-template optional<std::vector<std::string>> fromExpressionValue<std::vector<std::string>>(const Value&);
-template Value toExpressionValue(const std::vector<std::string>&);
+template struct ValueConverter<std::vector<std::string>>;
template type::Type valueTypeToExpressionType<AlignmentType>();
-template optional<AlignmentType> fromExpressionValue<AlignmentType>(const Value&);
-template Value toExpressionValue(const AlignmentType&);
+template struct ValueConverter<AlignmentType>;
template type::Type valueTypeToExpressionType<CirclePitchScaleType>();
-template optional<CirclePitchScaleType> fromExpressionValue<CirclePitchScaleType>(const Value&);
-template Value toExpressionValue(const CirclePitchScaleType&);
+template struct ValueConverter<CirclePitchScaleType>;
template type::Type valueTypeToExpressionType<IconTextFitType>();
-template optional<IconTextFitType> fromExpressionValue<IconTextFitType>(const Value&);
-template Value toExpressionValue(const IconTextFitType&);
+template struct ValueConverter<IconTextFitType>;
template type::Type valueTypeToExpressionType<LineCapType>();
-template optional<LineCapType> fromExpressionValue<LineCapType>(const Value&);
-template Value toExpressionValue(const LineCapType&);
+template struct ValueConverter<LineCapType>;
template type::Type valueTypeToExpressionType<LineJoinType>();
-template optional<LineJoinType> fromExpressionValue<LineJoinType>(const Value&);
-template Value toExpressionValue(const LineJoinType&);
+template struct ValueConverter<LineJoinType>;
template type::Type valueTypeToExpressionType<SymbolPlacementType>();
-template optional<SymbolPlacementType> fromExpressionValue<SymbolPlacementType>(const Value&);
-template Value toExpressionValue(const SymbolPlacementType&);
+template struct ValueConverter<SymbolPlacementType>;
template type::Type valueTypeToExpressionType<SymbolAnchorType>();
-template optional<SymbolAnchorType> fromExpressionValue<SymbolAnchorType>(const Value&);
-template Value toExpressionValue(const SymbolAnchorType&);
+template struct ValueConverter<SymbolAnchorType>;
template type::Type valueTypeToExpressionType<TextJustifyType>();
-template optional<TextJustifyType> fromExpressionValue<TextJustifyType>(const Value&);
-template Value toExpressionValue(const TextJustifyType&);
+template struct ValueConverter<TextJustifyType>;
template type::Type valueTypeToExpressionType<TextTransformType>();
-template optional<TextTransformType> fromExpressionValue<TextTransformType>(const Value&);
-template Value toExpressionValue(const TextTransformType&);
+template struct ValueConverter<TextTransformType>;
template type::Type valueTypeToExpressionType<TranslateAnchorType>();
-template optional<TranslateAnchorType> fromExpressionValue<TranslateAnchorType>(const Value&);
-template Value toExpressionValue(const TranslateAnchorType&);
+template struct ValueConverter<TranslateAnchorType>;
+
+template type::Type valueTypeToExpressionType<RasterResamplingType>();
+template struct ValueConverter<RasterResamplingType>;
template type::Type valueTypeToExpressionType<HillshadeIlluminationAnchorType>();
-template optional<HillshadeIlluminationAnchorType> fromExpressionValue<HillshadeIlluminationAnchorType>(const Value&);
-template Value toExpressionValue(const HillshadeIlluminationAnchorType&);
+template struct ValueConverter<HillshadeIlluminationAnchorType>;
template type::Type valueTypeToExpressionType<LightAnchorType>();
-template optional<LightAnchorType> fromExpressionValue<LightAnchorType>(const Value&);
-template Value toExpressionValue(const LightAnchorType&);
-
-template type::Type valueTypeToExpressionType<Position>();
-template optional<Position> fromExpressionValue<Position>(const Value&);
-template Value toExpressionValue(const Position&);
+template struct ValueConverter<LightAnchorType>;
} // namespace expression
} // namespace style
diff --git a/src/mbgl/style/filter.cpp b/src/mbgl/style/filter.cpp
index 51aa6bcf82..18b8b0a7f4 100644
--- a/src/mbgl/style/filter.cpp
+++ b/src/mbgl/style/filter.cpp
@@ -1,12 +1,20 @@
#include <mbgl/style/filter.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
namespace mbgl {
namespace style {
bool Filter::operator()(const expression::EvaluationContext &context) const {
- return FilterBase::visit(*this, FilterEvaluator { context });
+
+ if (!this->expression) return true;
+
+ const expression::EvaluationResult result = (*this->expression)->evaluate(context);
+ if (result) {
+ const optional<bool> typed = expression::fromExpressionValue<bool>(*result);
+ return typed ? *typed : false;
+ } else {
+ return false;
+ }
}
} // namespace style
diff --git a/src/mbgl/style/filter_evaluator.cpp b/src/mbgl/style/filter_evaluator.cpp
deleted file mode 100644
index 72022172f4..0000000000
--- a/src/mbgl/style/filter_evaluator.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#include <mbgl/style/filter.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
-
-namespace mbgl {
-namespace style {
-
-template <class Op>
-struct Comparator {
- const Op& op;
-
- template <class T>
- bool operator()(const T& lhs, const T& rhs) const {
- return op(lhs, rhs);
- }
-
- template <class T0, class T1>
- auto operator()(const T0& lhs, const T1& rhs) const
- -> typename std::enable_if_t<std::is_arithmetic<T0>::value && !std::is_same<T0, bool>::value &&
- std::is_arithmetic<T1>::value && !std::is_same<T1, bool>::value, bool> {
- return op(double(lhs), double(rhs));
- }
-
- template <class T0, class T1>
- auto operator()(const T0&, const T1&) const
- -> typename std::enable_if_t<!std::is_arithmetic<T0>::value || std::is_same<T0, bool>::value ||
- !std::is_arithmetic<T1>::value || std::is_same<T1, bool>::value, bool> {
- return false;
- }
-
- bool operator()(const NullValue&,
- const NullValue&) const {
- // Should be unreachable; null is not currently allowed by the style specification.
- assert(false);
- return false;
- }
-
- bool operator()(const std::vector<Value>&,
- const std::vector<Value>&) const {
- // Should be unreachable; nested values are not currently allowed by the style specification.
- assert(false);
- return false;
- }
-
- bool operator()(const PropertyMap&,
- const PropertyMap&) const {
- // Should be unreachable; nested values are not currently allowed by the style specification.
- assert(false);
- return false;
- }
-};
-
-template <class Op>
-bool compare(const Value& lhs, const Value& rhs, const Op& op) {
- return Value::binary_visit(lhs, rhs, Comparator<Op> { op });
-}
-
-bool equal(const Value& lhs, const Value& rhs) {
- return compare(lhs, rhs, [] (const auto& lhs_, const auto& rhs_) { return lhs_ == rhs_; });
-}
-
-bool FilterEvaluator::operator()(const NullFilter&) const {
- return true;
-}
-
-bool FilterEvaluator::operator()(const EqualsFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- return actual && equal(*actual, filter.value);
-}
-
-bool FilterEvaluator::operator()(const NotEqualsFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- return !actual || !equal(*actual, filter.value);
-}
-
-bool FilterEvaluator::operator()(const LessThanFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ < rhs_; });
-}
-
-bool FilterEvaluator::operator()(const LessThanEqualsFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ <= rhs_; });
-}
-
-bool FilterEvaluator::operator()(const GreaterThanFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ > rhs_; });
-}
-
-bool FilterEvaluator::operator()(const GreaterThanEqualsFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ >= rhs_; });
-}
-
-bool FilterEvaluator::operator()(const InFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- if (!actual)
- return false;
- for (const auto& v: filter.values) {
- if (equal(*actual, v)) {
- return true;
- }
- }
- return false;
-}
-
-bool FilterEvaluator::operator()(const NotInFilter& filter) const {
- optional<Value> actual = context.feature->getValue(filter.key);
- if (!actual)
- return true;
- for (const auto& v: filter.values) {
- if (equal(*actual, v)) {
- return false;
- }
- }
- return true;
-}
-
-bool FilterEvaluator::operator()(const AnyFilter& filter) const {
- for (const auto& f: filter.filters) {
- if (Filter::visit(f, *this)) {
- return true;
- }
- }
- return false;
-}
-
-bool FilterEvaluator::operator()(const AllFilter& filter) const {
- for (const auto& f: filter.filters) {
- if (!Filter::visit(f, *this)) {
- return false;
- }
- }
- return true;
-}
-
-bool FilterEvaluator::operator()(const NoneFilter& filter) const {
- for (const auto& f: filter.filters) {
- if (Filter::visit(f, *this)) {
- return false;
- }
- }
- return true;
-}
-
-bool FilterEvaluator::operator()(const HasFilter& filter) const {
- return bool(context.feature->getValue(filter.key));
-}
-
-bool FilterEvaluator::operator()(const NotHasFilter& filter) const {
- return !context.feature->getValue(filter.key);
-}
-
-bool FilterEvaluator::operator()(const TypeEqualsFilter& filter) const {
- return context.feature->getType() == filter.value;
-}
-
-bool FilterEvaluator::operator()(const TypeNotEqualsFilter& filter) const {
- return context.feature->getType() != filter.value;
-}
-
-bool FilterEvaluator::operator()(const TypeInFilter& filter) const {
- for (const auto& v: filter.values) {
- if (context.feature->getType() == v) {
- return true;
- }
- }
- return false;
-}
-
-bool FilterEvaluator::operator()(const TypeNotInFilter& filter) const {
- for (const auto& v: filter.values) {
- if (context.feature->getType() == v) {
- return false;
- }
- }
- return true;
-}
-
-bool FilterEvaluator::operator()(const IdentifierEqualsFilter& filter) const {
- return context.feature->getID() == filter.value;
-}
-
-bool FilterEvaluator::operator()(const IdentifierNotEqualsFilter& filter) const {
- return context.feature->getID() != filter.value;
-}
-
-bool FilterEvaluator::operator()(const IdentifierInFilter& filter) const {
- for (const auto& v: filter.values) {
- if (context.feature->getID() == v) {
- return true;
- }
- }
- return false;
-}
-
-bool FilterEvaluator::operator()(const IdentifierNotInFilter& filter) const {
- for (const auto& v: filter.values) {
- if (context.feature->getID() == v) {
- return false;
- }
- }
- return true;
-}
-
-bool FilterEvaluator::operator()(const HasIdentifierFilter&) const {
- return bool(context.feature->getID());
-}
-
-bool FilterEvaluator::operator()(const NotHasIdentifierFilter&) const {
- return !context.feature->getID();
-}
-
-bool FilterEvaluator::operator()(const ExpressionFilter& filter) const {
- const expression::EvaluationResult result = filter.expression->evaluate(context);
- if (result) {
- const optional<bool> typed = expression::fromExpressionValue<bool>(*result);
- return typed ? *typed : false;
- }
- return false;
-}
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/style/function/categorical_stops.cpp b/src/mbgl/style/function/categorical_stops.cpp
deleted file mode 100644
index dd179f5376..0000000000
--- a/src/mbgl/style/function/categorical_stops.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <mbgl/style/function/categorical_stops.hpp>
-#include <mbgl/style/types.hpp>
-#include <mbgl/util/color.hpp>
-
-#include <array>
-
-namespace mbgl {
-namespace style {
-
-optional<CategoricalValue> categoricalValue(const Value& value) {
- return value.match(
- [] (bool t) { return optional<CategoricalValue>(t); },
- [] (uint64_t t) { return optional<CategoricalValue>(int64_t(t)); },
- [] (int64_t t) { return optional<CategoricalValue>(t); },
- [] (double t) { return optional<CategoricalValue>(int64_t(t)); },
- [] (const std::string& t) { return optional<CategoricalValue>(t); },
- [] (const auto&) { return optional<CategoricalValue>(); }
- );
-}
-
-template <class T>
-optional<T> CategoricalStops<T>::evaluate(const Value& value) const {
- auto v = categoricalValue(value);
- if (!v) {
- return {};
- }
- auto it = stops.find(*v);
- return it == stops.end() ? optional<T>() : it->second;
-}
-
-template class CategoricalStops<float>;
-template class CategoricalStops<Color>;
-template class CategoricalStops<std::array<float, 2>>;
-template class CategoricalStops<std::string>;
-template class CategoricalStops<TextTransformType>;
-template class CategoricalStops<TextJustifyType>;
-template class CategoricalStops<SymbolAnchorType>;
-template class CategoricalStops<LineJoinType>;
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/style/function/identity_stops.cpp b/src/mbgl/style/function/identity_stops.cpp
deleted file mode 100644
index 0ac6fda846..0000000000
--- a/src/mbgl/style/function/identity_stops.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-#include <mbgl/style/function/identity_stops.hpp>
-#include <mbgl/style/types.hpp>
-#include <mbgl/util/enum.hpp>
-#include <mbgl/util/color.hpp>
-
-#include <array>
-
-namespace mbgl {
-namespace style {
-
-template <>
-optional<float> IdentityStops<float>::evaluate(const Value& value) const {
- return numericValue<float>(value);
-}
-
-template <>
-optional<std::string> IdentityStops<std::string>::evaluate(const Value& value) const {
- if (!value.is<std::string>()) {
- return {};
- }
-
- return value.get<std::string>();
-}
-
-template <>
-optional<Color> IdentityStops<Color>::evaluate(const Value& value) const {
- if (!value.is<std::string>()) {
- return {};
- }
-
- return Color::parse(value.get<std::string>());
-}
-
-template <>
-optional<TextTransformType> IdentityStops<TextTransformType>::evaluate(const Value& value) const {
- if (!value.is<std::string>()) {
- return {};
- }
-
- return Enum<TextTransformType>::toEnum(value.get<std::string>());
-}
-
-template <>
-optional<TextJustifyType> IdentityStops<TextJustifyType>::evaluate(const Value& value) const {
- if (!value.is<std::string>()) {
- return {};
- }
-
- return Enum<TextJustifyType>::toEnum(value.get<std::string>());
-}
-
-template <>
-optional<SymbolAnchorType> IdentityStops<SymbolAnchorType>::evaluate(const Value& value) const {
- if (!value.is<std::string>()) {
- return {};
- }
-
- return Enum<SymbolAnchorType>::toEnum(value.get<std::string>());
-}
-
-template <>
-optional<LineJoinType> IdentityStops<LineJoinType>::evaluate(const Value& value) const {
- if (!value.is<std::string>()) {
- return {};
- }
-
- return Enum<LineJoinType>::toEnum(value.get<std::string>());
-}
-
-template <>
-optional<std::array<float, 2>> IdentityStops<std::array<float, 2>>::evaluate(const Value& value) const {
- if (!value.is<std::vector<Value>>()) {
- return {};
- }
-
- const auto& vector = value.get<std::vector<Value>>();
- if (vector.size() != 2 || !numericValue<float>(vector[0]) || !numericValue<float>(vector[1])) {
- return {};
- }
-
- std::array<float, 2> array {{
- *numericValue<float>(vector[0]),
- *numericValue<float>(vector[1])
- }};
- return array;
-}
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp
index 3f7881ddd3..c2a1545a00 100644
--- a/src/mbgl/style/layers/heatmap_layer.cpp
+++ b/src/mbgl/style/layers/heatmap_layer.cpp
@@ -5,8 +5,8 @@
#include <mbgl/style/layer_observer.hpp>
// for constructing default heatmap-color ramp expression from style JSON
#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/color_ramp_property_value.hpp>
#include <mbgl/style/conversion/json.hpp>
-#include <mbgl/style/conversion/heatmap_color_property_value.hpp>
namespace mbgl {
namespace style {
@@ -181,17 +181,17 @@ TransitionOptions HeatmapLayer::getHeatmapIntensityTransition() const {
return impl().paint.template get<HeatmapIntensity>().options;
}
-HeatmapColorPropertyValue HeatmapLayer::getDefaultHeatmapColor() {
+ColorRampPropertyValue HeatmapLayer::getDefaultHeatmapColor() {
conversion::Error error;
std::string rawValue = R"JSON(["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",0.1,"royalblue",0.3,"cyan",0.5,"lime",0.7,"yellow",1,"red"])JSON";
- return *conversion::convertJSON<HeatmapColorPropertyValue>(rawValue, error);
+ return *conversion::convertJSON<ColorRampPropertyValue>(rawValue, error);
}
-HeatmapColorPropertyValue HeatmapLayer::getHeatmapColor() const {
+ColorRampPropertyValue HeatmapLayer::getHeatmapColor() const {
return impl().paint.template get<HeatmapColor>().value;
}
-void HeatmapLayer::setHeatmapColor(HeatmapColorPropertyValue value) {
+void HeatmapLayer::setHeatmapColor(ColorRampPropertyValue value) {
if (value == getHeatmapColor())
return;
auto impl_ = mutableImpl();
diff --git a/src/mbgl/style/layers/heatmap_layer_properties.hpp b/src/mbgl/style/layers/heatmap_layer_properties.hpp
index f7afa5fbeb..fe7257a78a 100644
--- a/src/mbgl/style/layers/heatmap_layer_properties.hpp
+++ b/src/mbgl/style/layers/heatmap_layer_properties.hpp
@@ -24,6 +24,8 @@ struct HeatmapIntensity : PaintProperty<float> {
static float defaultValue() { return 1; }
};
+using HeatmapColor = ColorRampProperty;
+
struct HeatmapOpacity : PaintProperty<float> {
static float defaultValue() { return 1; }
};
diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs
new file mode 100644
index 0000000000..a9b6d9d02d
--- /dev/null
+++ b/src/mbgl/style/layers/layer.cpp.ejs
@@ -0,0 +1,179 @@
+<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_impl.hpp>
+#include <mbgl/style/layer_observer.hpp>
+<% if (type === 'heatmap') { -%>
+// for constructing default heatmap-color ramp expression from style JSON
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/color_ramp_property_value.hpp>
+#include <mbgl/style/conversion/json.hpp>
+<% } -%>
+
+namespace mbgl {
+namespace style {
+
+<% if (type === 'background') { -%>
+<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID)
+ : Layer(makeMutable<Impl>(LayerType::<%- camelize(type) %>, layerID, std::string())) {
+}
+<% } else { -%>
+<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID, const std::string& sourceID)
+ : Layer(makeMutable<Impl>(LayerType::<%- camelize(type) %>, layerID, sourceID)) {
+}
+<% } -%>
+
+<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(Immutable<Impl> impl_)
+ : Layer(std::move(impl_)) {
+}
+
+<%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default;
+
+const <%- camelize(type) %>Layer::Impl& <%- camelize(type) %>Layer::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+Mutable<<%- camelize(type) %>Layer::Impl> <%- camelize(type) %>Layer::mutableImpl() const {
+ return makeMutable<Impl>(impl());
+}
+
+std::unique_ptr<Layer> <%- camelize(type) %>Layer::cloneRef(const std::string& id_) const {
+ auto impl_ = mutableImpl();
+ impl_->id = id_;
+ impl_->paint = <%- camelize(type) %>PaintProperties::Transitionable();
+ return std::make_unique<<%- camelize(type) %>Layer>(std::move(impl_));
+}
+
+<% if (layoutProperties.length) { -%>
+void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const {
+ layout.stringify(writer);
+}
+<% } else { -%>
+void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
+}
+<% } -%>
+
+<% if (type !== 'background') { -%>
+// Source
+
+const std::string& <%- camelize(type) %>Layer::getSourceID() const {
+ return impl().source;
+}
+
+<% if (type !== 'raster' && type !== 'hillshade') { -%>
+void <%- camelize(type) %>Layer::setSourceLayer(const std::string& sourceLayer) {
+ auto impl_ = mutableImpl();
+ impl_->sourceLayer = sourceLayer;
+ baseImpl = std::move(impl_);
+}
+
+const std::string& <%- camelize(type) %>Layer::getSourceLayer() const {
+ return impl().sourceLayer;
+}
+
+// Filter
+
+void <%- camelize(type) %>Layer::setFilter(const Filter& filter) {
+ auto impl_ = mutableImpl();
+ impl_->filter = filter;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+
+const Filter& <%- camelize(type) %>Layer::getFilter() const {
+ return impl().filter;
+}
+<% } -%>
+<% } -%>
+
+// Visibility
+
+void <%- camelize(type) %>Layer::setVisibility(VisibilityType value) {
+ if (value == getVisibility())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->visibility = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+
+// Zoom range
+
+void <%- camelize(type) %>Layer::setMinZoom(float minZoom) {
+ auto impl_ = mutableImpl();
+ impl_->minZoom = minZoom;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+
+void <%- camelize(type) %>Layer::setMaxZoom(float maxZoom) {
+ auto impl_ = mutableImpl();
+ impl_->maxZoom = maxZoom;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+
+// Layout properties
+
+<% for (const property of layoutProperties) { -%>
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
+ return <%- camelize(property.name) %>::defaultValue();
+}
+
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
+ return impl().layout.get<<%- camelize(property.name) %>>();
+}
+
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) {
+ if (value == get<%- camelize(property.name) %>())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->layout.get<<%- camelize(property.name) %>>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+<% } -%>
+
+// Paint properties
+<% for (const property of paintProperties) { %>
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
+<% if (property.name === 'heatmap-color') { -%>
+ conversion::Error error;
+ std::string rawValue = R"JSON(<%- JSON.stringify(property.default) %>)JSON";
+ return *conversion::convertJSON<<%- propertyValueType(property)%>>(rawValue, error);
+<% } else { -%>
+ return { <%- defaultValue(property) %> };
+<% } -%>
+}
+
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
+ return impl().paint.template get<<%- camelize(property.name) %>>().value;
+}
+
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) {
+ if (value == get<%- camelize(property.name) %>())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->paint.template get<<%- camelize(property.name) %>>().value = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>Transition(const TransitionOptions& options) {
+ auto impl_ = mutableImpl();
+ impl_->paint.template get<<%- camelize(property.name) %>>().options = options;
+ baseImpl = std::move(impl_);
+}
+
+TransitionOptions <%- camelize(type) %>Layer::get<%- camelize(property.name) %>Transition() const {
+ return impl().paint.template get<<%- camelize(property.name) %>>().options;
+}
+<% } -%>
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/layer_properties.cpp.ejs b/src/mbgl/style/layers/layer_properties.cpp.ejs
new file mode 100644
index 0000000000..e5523e5439
--- /dev/null
+++ b/src/mbgl/style/layers/layer_properties.cpp.ejs
@@ -0,0 +1,14 @@
+<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs
new file mode 100644
index 0000000000..5b774933a6
--- /dev/null
+++ b/src/mbgl/style/layers/layer_properties.hpp.ejs
@@ -0,0 +1,54 @@
+<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/types.hpp>
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+#include <mbgl/style/properties.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+
+namespace mbgl {
+namespace style {
+
+<% for (const property of layoutProperties) { -%>
+struct <%- camelize(property.name) %> : <%- layoutPropertyType(property, type) %> {
+ static constexpr const char * key = "<%- property.name %>";
+ static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
+};
+
+<% } -%>
+<% for (const property of paintProperties) { -%>
+<% if (property['property-type'] === 'color-ramp') { -%>
+using <%- camelize(property.name) %> = ColorRampProperty;
+<% } else { -%>
+struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> {
+ static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
+};
+<% } -%>
+
+<% } -%>
+<% if (layoutProperties.length) { -%>
+class <%- camelize(type) %>LayoutProperties : public Properties<
+<% for (const property of layoutProperties.slice(0, -1)) { -%>
+ <%- camelize(property.name) %>,
+<% } -%>
+ <%- camelize(layoutProperties.slice(-1)[0].name) %>
+> {};
+
+<% } -%>
+class <%- camelize(type) %>PaintProperties : public Properties<
+<% for (const property of paintProperties.slice(0, -1)) { -%>
+ <%- camelize(property.name) %>,
+<% } -%>
+ <%- camelize(paintProperties.slice(-1)[0].name) %>
+> {};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp
index 36b2e3e027..e5b03df0f6 100644
--- a/src/mbgl/style/layers/raster_layer.cpp
+++ b/src/mbgl/style/layers/raster_layer.cpp
@@ -236,6 +236,33 @@ TransitionOptions RasterLayer::getRasterContrastTransition() const {
return impl().paint.template get<RasterContrast>().options;
}
+PropertyValue<RasterResamplingType> RasterLayer::getDefaultRasterResampling() {
+ return { RasterResamplingType::Linear };
+}
+
+PropertyValue<RasterResamplingType> RasterLayer::getRasterResampling() const {
+ return impl().paint.template get<RasterResampling>().value;
+}
+
+void RasterLayer::setRasterResampling(PropertyValue<RasterResamplingType> value) {
+ if (value == getRasterResampling())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->paint.template get<RasterResampling>().value = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
+
+void RasterLayer::setRasterResamplingTransition(const TransitionOptions& options) {
+ auto impl_ = mutableImpl();
+ impl_->paint.template get<RasterResampling>().options = options;
+ baseImpl = std::move(impl_);
+}
+
+TransitionOptions RasterLayer::getRasterResamplingTransition() const {
+ return impl().paint.template get<RasterResampling>().options;
+}
+
PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() {
return { 300 };
}
diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp
index 12df09f32c..08818c9fb3 100644
--- a/src/mbgl/style/layers/raster_layer_properties.hpp
+++ b/src/mbgl/style/layers/raster_layer_properties.hpp
@@ -36,6 +36,10 @@ struct RasterContrast : PaintProperty<float> {
static float defaultValue() { return 0; }
};
+struct RasterResampling : PaintProperty<RasterResamplingType> {
+ static RasterResamplingType defaultValue() { return RasterResamplingType::Linear; }
+};
+
struct RasterFadeDuration : PaintProperty<float> {
static float defaultValue() { return 300; }
};
@@ -47,6 +51,7 @@ class RasterPaintProperties : public Properties<
RasterBrightnessMax,
RasterSaturation,
RasterContrast,
+ RasterResampling,
RasterFadeDuration
> {};
diff --git a/src/mbgl/style/light.cpp.ejs b/src/mbgl/style/light.cpp.ejs
new file mode 100644
index 0000000000..45241c60fd
--- /dev/null
+++ b/src/mbgl/style/light.cpp.ejs
@@ -0,0 +1,60 @@
+<%
+ const properties = locals.properties;
+-%>
+// This file is generated. Do not edit.
+
+#include <mbgl/style/light.hpp>
+#include <mbgl/style/light_impl.hpp>
+#include <mbgl/style/light_observer.hpp>
+
+namespace mbgl {
+namespace style {
+
+static LightObserver nullObserver;
+
+Light::Light()
+ : impl(makeMutable<Impl>()),
+ observer(&nullObserver) {
+}
+
+Light::~Light() = default;
+
+void Light::setObserver(LightObserver* observer_) {
+ observer = observer_ ? observer_ : &nullObserver;
+}
+
+Mutable<Light::Impl> Light::mutableImpl() const {
+ return makeMutable<Impl>(*impl);
+}
+
+<% for (const property of properties) { -%>
+<%- evaluatedType(property) %> Light::getDefault<%- camelize(property.name) %>() {
+ return Light<%- camelize(property.name) %>::defaultValue();
+}
+
+<%- propertyValueType(property) %> Light::get<%- camelize(property.name) %>() const {
+ return impl->properties.template get<Light<%- camelize(property.name) %>>().value;
+}
+
+void Light::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> property) {
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<Light<%- camelize(property.name) %>>().value = property;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
+}
+
+void Light::set<%- camelize(property.name) %>Transition(const TransitionOptions& options) {
+ auto impl_ = mutableImpl();
+ impl_->properties.template get<Light<%- camelize(property.name) %>>().options = options;
+ impl = std::move(impl_);
+ observer->onLightChanged(*this);
+}
+
+TransitionOptions Light::get<%- camelize(property.name) %>Transition() const {
+ return impl->properties.template get<Light<%- camelize(property.name) %>>().options;
+}
+
+<% } -%>
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp
index 195eb645a9..d51a6760c5 100644
--- a/src/mbgl/style/paint_property.hpp
+++ b/src/mbgl/style/paint_property.hpp
@@ -1,8 +1,8 @@
#pragma once
+#include <mbgl/style/color_ramp_property_value.hpp>
#include <mbgl/style/properties.hpp>
#include <mbgl/style/property_value.hpp>
-#include <mbgl/style/heatmap_color_property_value.hpp>
#include <mbgl/style/data_driven_property_value.hpp>
#include <mbgl/renderer/property_evaluator.hpp>
#include <mbgl/renderer/cross_faded_property_evaluator.hpp>
@@ -50,19 +50,19 @@ public:
};
/*
- * Special-case paint property traits for heatmap-color, needed because
- * heatmap-color values do not fit into the
+ * Special-case paint property traits for heatmap-color and line-gradient,
+ * needed because these values do not fit into the
* Undefined | Value | {Camera,Source,Composite}Function taxonomy that applies
* to all other paint properties.
*
- * These traits are provided here--despite the fact that heatmap-color
+ * These traits are provided here--despite the fact that color ramps
* is not used like other paint properties--to allow the parameter-pack-based
* batch evaluation of paint properties to compile properly.
*/
-class HeatmapColor {
+class ColorRampProperty {
public:
- using TransitionableType = Transitionable<HeatmapColorPropertyValue>;
- using UnevaluatedType = Transitioning<HeatmapColorPropertyValue>;
+ using TransitionableType = Transitionable<ColorRampPropertyValue>;
+ using UnevaluatedType = Transitioning<ColorRampPropertyValue>;
using EvaluatorType = PropertyEvaluator<Color>;
using PossiblyEvaluatedType = Color;
using Type = Color;
diff --git a/src/mbgl/style/properties.hpp b/src/mbgl/style/properties.hpp
index dfcf7993a7..9206e96982 100644
--- a/src/mbgl/style/properties.hpp
+++ b/src/mbgl/style/properties.hpp
@@ -154,10 +154,7 @@ public:
[&] (const T& t) {
return t;
},
- [&] (const SourceFunction<T>& t) {
- return t.evaluate(feature, defaultValue);
- },
- [&] (const CompositeFunction<T>& t) {
+ [&] (const PropertyExpression<T>& t) {
return t.evaluate(z, feature, defaultValue);
});
}
diff --git a/src/mbgl/style/sources/custom_geometry_source.cpp b/src/mbgl/style/sources/custom_geometry_source.cpp
index b37490a5ce..6ce7c1be11 100644
--- a/src/mbgl/style/sources/custom_geometry_source.cpp
+++ b/src/mbgl/style/sources/custom_geometry_source.cpp
@@ -30,15 +30,15 @@ void CustomGeometrySource::loadDescription(FileSource&) {
void CustomGeometrySource::setTileData(const CanonicalTileID& tileID,
const GeoJSON& data) {
- loader->invoke(&CustomTileLoader::setTileData, tileID, data);
+ loader->self().invoke(&CustomTileLoader::setTileData, tileID, data);
}
void CustomGeometrySource::invalidateTile(const CanonicalTileID& tileID) {
- loader->invoke(&CustomTileLoader::invalidateTile, tileID);
+ loader->self().invoke(&CustomTileLoader::invalidateTile, tileID);
}
void CustomGeometrySource::invalidateRegion(const LatLngBounds& bounds) {
- loader->invoke(&CustomTileLoader::invalidateRegion, bounds, impl().getZoomRange());
+ loader->self().invoke(&CustomTileLoader::invalidateRegion, bounds, impl().getZoomRange());
}
} // namespace style
diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp
index bdfa20a047..46de0173de 100644
--- a/src/mbgl/style/types.cpp
+++ b/src/mbgl/style/types.cpp
@@ -25,6 +25,11 @@ MBGL_DEFINE_ENUM(TranslateAnchorType, {
{ TranslateAnchorType::Viewport, "viewport" },
});
+MBGL_DEFINE_ENUM(RasterResamplingType, {
+ { RasterResamplingType::Linear, "linear" },
+ { RasterResamplingType::Nearest, "nearest" },
+});
+
MBGL_DEFINE_ENUM(HillshadeIlluminationAnchorType, {
{ HillshadeIlluminationAnchorType::Map, "map" },
{ HillshadeIlluminationAnchorType::Viewport, "viewport" },
@@ -57,6 +62,7 @@ MBGL_DEFINE_ENUM(LineJoinType, {
MBGL_DEFINE_ENUM(SymbolPlacementType, {
{ SymbolPlacementType::Point, "point" },
{ SymbolPlacementType::Line, "line" },
+ { SymbolPlacementType::LineCenter, "line-center" },
});
MBGL_DEFINE_ENUM(SymbolAnchorType, {
diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp
index 6d6f2aabc7..ac4dbff2af 100644
--- a/src/mbgl/text/collision_feature.cpp
+++ b/src/mbgl/text/collision_feature.cpp
@@ -1,5 +1,6 @@
#include <mbgl/text/collision_feature.hpp>
#include <mbgl/util/math.hpp>
+#include <mbgl/math/log2.hpp>
namespace mbgl {
@@ -15,7 +16,7 @@ CollisionFeature::CollisionFeature(const GeometryCoordinates& line,
IndexedSubfeature indexedFeature_,
const float overscaling)
: indexedFeature(std::move(indexedFeature_))
- , alongLine(placement == style::SymbolPlacementType::Line) {
+ , alongLine(placement != style::SymbolPlacementType::Point) {
if (top == 0 && bottom == 0 && left == 0 && right == 0) return;
const float y1 = top * boxScale - padding;
@@ -41,7 +42,8 @@ CollisionFeature::CollisionFeature(const GeometryCoordinates& line,
void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoordinate& anchorPoint,
const int segment, const float labelLength, const float boxSize, const float overscaling) {
const float step = boxSize / 2;
- const int nBoxes = std::floor(labelLength / step);
+ const int nBoxes = std::max(static_cast<int>(std::floor(labelLength / step)), 1);
+
// We calculate line collision circles out to 300% of what would normally be our
// max size, to allow collision detection to work on labels that expand as
// they move into the distance
@@ -50,7 +52,7 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoo
// symbol spacing will put labels very close together in a pitched map.
// To reduce the cost of adding extra collision circles, we slowly increase
// them for overscaled tiles.
- const float overscalingPaddingFactor = 1 + .4 * std::log(overscaling) / std::log(2);
+ const float overscalingPaddingFactor = 1 + .4 * ::log2(static_cast<double>(overscaling));
const int nPitchPaddingBoxes = std::floor(nBoxes * overscalingPaddingFactor / 2);
// offset the center of the first box by half a box so that the edge of the
diff --git a/src/mbgl/text/cross_tile_symbol_index.cpp b/src/mbgl/text/cross_tile_symbol_index.cpp
index b0c3511ce3..98b9af1f94 100644
--- a/src/mbgl/text/cross_tile_symbol_index.cpp
+++ b/src/mbgl/text/cross_tile_symbol_index.cpp
@@ -61,6 +61,32 @@ void TileLayerIndex::findMatches(std::vector<SymbolInstance>& symbolInstances, c
CrossTileSymbolLayerIndex::CrossTileSymbolLayerIndex() {
}
+/*
+ * Sometimes when a user pans across the antimeridian the longitude value gets wrapped.
+ * To prevent labels from flashing out and in we adjust the tileID values in the indexes
+ * so that they match the new wrapped version of the map.
+ */
+void CrossTileSymbolLayerIndex::handleWrapJump(float newLng) {
+
+ const int wrapDelta = ::round((newLng - lng) / 360);
+ if (wrapDelta != 0) {
+ std::map<uint8_t, std::map<OverscaledTileID,TileLayerIndex>> newIndexes;
+ for (auto& zoomIndex : indexes) {
+ std::map<OverscaledTileID,TileLayerIndex> newZoomIndex;
+ for (auto& index : zoomIndex.second) {
+ // change the tileID's wrap and move its index
+ index.second.coord = index.second.coord.unwrapTo(index.second.coord.wrap + wrapDelta);
+ newZoomIndex.emplace(index.second.coord, std::move(index.second));
+ }
+ newIndexes.emplace(zoomIndex.first, std::move(newZoomIndex));
+ }
+
+ indexes = std::move(newIndexes);
+ }
+
+ lng = newLng;
+}
+
bool CrossTileSymbolLayerIndex::addBucket(const OverscaledTileID& tileID, SymbolBucket& bucket, uint32_t& maxCrossTileID) {
const auto& thisZoomIndexes = indexes[tileID.overscaledZ];
auto previousIndex = thisZoomIndexes.find(tileID);
@@ -138,21 +164,26 @@ bool CrossTileSymbolLayerIndex::removeStaleBuckets(const std::unordered_set<uint
CrossTileSymbolIndex::CrossTileSymbolIndex() {}
-bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer) {
+bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer, float lng) {
auto& layerIndex = layerIndexes[symbolLayer.getID()];
bool symbolBucketsChanged = false;
std::unordered_set<uint32_t> currentBucketIDs;
+ layerIndex.handleWrapJump(lng);
+
for (RenderTile& renderTile : symbolLayer.renderTiles) {
if (!renderTile.tile.isRenderable()) {
continue;
}
- auto bucket = renderTile.tile.getBucket(*symbolLayer.baseImpl);
- assert(dynamic_cast<SymbolBucket*>(bucket));
- SymbolBucket& symbolBucket = *reinterpret_cast<SymbolBucket*>(bucket);
+ auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl);
+ if (!bucket) {
+ continue;
+ }
+ SymbolBucket& symbolBucket = *bucket;
+
if (symbolBucket.bucketLeaderID != symbolLayer.getID()) {
// Only add this layer if it's the "group leader" for the bucket
continue;
diff --git a/src/mbgl/text/cross_tile_symbol_index.hpp b/src/mbgl/text/cross_tile_symbol_index.hpp
index 541c2e3661..051573e1d2 100644
--- a/src/mbgl/text/cross_tile_symbol_index.hpp
+++ b/src/mbgl/text/cross_tile_symbol_index.hpp
@@ -45,18 +45,20 @@ public:
CrossTileSymbolLayerIndex();
bool addBucket(const OverscaledTileID&, SymbolBucket&, uint32_t& maxCrossTileID);
bool removeStaleBuckets(const std::unordered_set<uint32_t>& currentIDs);
+ void handleWrapJump(float newLng);
private:
void removeBucketCrossTileIDs(uint8_t zoom, const TileLayerIndex& removedBucket);
std::map<uint8_t, std::map<OverscaledTileID,TileLayerIndex>> indexes;
std::map<uint8_t, std::set<uint32_t>> usedCrossTileIDs;
+ float lng = 0;
};
class CrossTileSymbolIndex {
public:
CrossTileSymbolIndex();
- bool addLayer(RenderSymbolLayer&);
+ bool addLayer(RenderSymbolLayer&, float lng);
void pruneUnusedLayers(const std::set<std::string>&);
void reset();
diff --git a/src/mbgl/text/get_anchors.cpp b/src/mbgl/text/get_anchors.cpp
index d41faf2a71..160ee21edf 100644
--- a/src/mbgl/text/get_anchors.cpp
+++ b/src/mbgl/text/get_anchors.cpp
@@ -7,6 +7,20 @@
#include <cmath>
namespace mbgl {
+
+float getAngleWindowSize(const float textLeft, const float textRight, const float glyphSize, const float boxScale) {
+ return (textLeft - textRight) != 0.0f ?
+ 3.0f / 5.0f * glyphSize * boxScale :
+ 0;
+}
+
+float getLineLength(const GeometryCoordinates& line) {
+ float lineLength = 0;
+ for (auto it = line.begin(), end = line.end() - 1; it != end; it++) {
+ lineLength += util::dist<float>(*(it), *(it + 1));
+ }
+ return lineLength;
+}
static Anchors resample(const GeometryCoordinates& line,
const float offset,
@@ -17,10 +31,7 @@ static Anchors resample(const GeometryCoordinates& line,
const bool continuedLine,
const bool placeAtMiddle) {
const float halfLabelLength = labelLength / 2.0f;
- float lineLength = 0;
- for (auto it = line.begin(), end = line.end() - 1; it != end; it++) {
- lineLength += util::dist<float>(*(it), *(it + 1));
- }
+ const float lineLength = getLineLength(line);
float distance = 0;
float markedDistance = offset - spacing;
@@ -91,19 +102,18 @@ Anchors getAnchors(const GeometryCoordinates& line,
// potential label passes text-max-angle check and has enough froom to fit
// on the line.
- const float angleWindowSize = (textLeft - textRight) != 0.0f ?
- 3.0f / 5.0f * glyphSize * boxScale :
- 0;
+ const float angleWindowSize = getAngleWindowSize(textLeft, textRight, glyphSize, boxScale);
- const float labelLength = fmax(textRight - textLeft, iconRight - iconLeft);
+ const float shapedLabelLength = fmax(textRight - textLeft, iconRight - iconLeft);
+ const float labelLength = shapedLabelLength * boxScale;
// Is the line continued from outside the tile boundary?
const bool continuedLine = (line[0].x == 0 || line[0].x == util::EXTENT || line[0].y == 0 || line[0].y == util::EXTENT);
// Is the label long, relative to the spacing?
// If so, adjust the spacing so there is always a minimum space of `spacing / 4` between label edges.
- if (spacing - labelLength * boxScale < spacing / 4) {
- spacing = labelLength * boxScale + spacing / 4;
+ if (spacing - labelLength < spacing / 4) {
+ spacing = labelLength + spacing / 4;
}
// Offset the first anchor by:
@@ -114,10 +124,53 @@ Anchors getAnchors(const GeometryCoordinates& line,
const float fixedExtraOffset = glyphSize * 2;
const float offset = !continuedLine ?
- std::fmod((labelLength / 2 + fixedExtraOffset) * boxScale * overscaling, spacing) :
+ std::fmod((shapedLabelLength / 2 + fixedExtraOffset) * boxScale * overscaling, spacing) :
std::fmod(spacing / 2 * overscaling, spacing);
- return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength * boxScale, continuedLine, false);
+ return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, continuedLine, false);
+}
+
+optional<Anchor> getCenterAnchor(const GeometryCoordinates& line,
+ const float maxAngle,
+ const float textLeft,
+ const float textRight,
+ const float iconLeft,
+ const float iconRight,
+ const float glyphSize,
+ const float boxScale) {
+ if (line.empty()) {
+ return {};
+ }
+
+ const float angleWindowSize = getAngleWindowSize(textLeft, textRight, glyphSize, boxScale);
+ const float labelLength = fmax(textRight - textLeft, iconRight - iconLeft) * boxScale;
+
+ float prevDistance = 0;
+ const float centerDistance = getLineLength(line) / 2;
+
+ int i = 0;
+ for (auto it = line.begin(), end = line.end() - 1; it != end; it++, i++) {
+ const GeometryCoordinate& a = *(it);
+ const GeometryCoordinate& b = *(it + 1);
+
+ const auto segmentDistance = util::dist<float>(a, b);
+
+ if (prevDistance + segmentDistance > centerDistance) {
+ // The center is on this segment
+ float t = (centerDistance - prevDistance) / segmentDistance,
+ x = util::interpolate(float(a.x), float(b.x), t),
+ y = util::interpolate(float(a.y), float(b.y), t);
+
+ Anchor anchor(::round(x), ::round(y), util::angle_to(b, a), 0.5f, i);
+
+ if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
+ return anchor;
+ }
+ }
+
+ prevDistance += segmentDistance;
+ }
+ return {};
}
} // namespace mbgl
diff --git a/src/mbgl/text/get_anchors.hpp b/src/mbgl/text/get_anchors.hpp
index 48f3013093..8fd22051a4 100644
--- a/src/mbgl/text/get_anchors.hpp
+++ b/src/mbgl/text/get_anchors.hpp
@@ -17,4 +17,14 @@ Anchors getAnchors(const GeometryCoordinates& line,
const float boxScale,
const float overscaling);
+optional<Anchor> getCenterAnchor(const GeometryCoordinates& line,
+ const float maxAngle,
+ const float textLeft,
+ const float textRight,
+ const float iconLeft,
+ const float iconRight,
+ const float glyphSize,
+ const float boxScale);
+
+
} // namespace mbgl
diff --git a/src/mbgl/text/language_tag.cpp b/src/mbgl/text/language_tag.cpp
new file mode 100644
index 0000000000..4c2712f103
--- /dev/null
+++ b/src/mbgl/text/language_tag.cpp
@@ -0,0 +1,237 @@
+#include <mbgl/text/language_tag.hpp>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunknown-pragmas"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wshorten-64-to-32"
+#pragma clang diagnostic ignored "-Wtautological-constant-compare"
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#pragma clang diagnostic pop
+#pragma GCC diagnostic pop
+
+#include <sstream>
+
+/*
+ ABNF for BCP 47 from: https://tools.ietf.org/html/bcp47
+
+ Language-Tag = langtag ; normal language tags
+ / privateuse ; private use tag
+ / grandfathered ; grandfathered tags NOT IMPLEMENTED
+
+ langtag = language
+ ["-" script]
+ ["-" region]
+ *("-" variant)
+ *("-" extension)
+ ["-" privateuse]
+
+ language = 2*3ALPHA ; shortest ISO 639 code
+ ["-" extlang] ; sometimes followed by
+ ; extended language subtags
+ / 4ALPHA ; or reserved for future use
+ / 5*8ALPHA ; or registered language subtag
+
+ extlang = 3ALPHA ; selected ISO 639 codes
+ *2("-" 3ALPHA) ; permanently reserved
+
+ script = 4ALPHA ; ISO 15924 code
+
+ region = 2ALPHA ; ISO 3166-1 code
+ / 3DIGIT ; UN M.49 code
+
+ variant = 5*8alphanum ; registered variants
+ / (DIGIT 3alphanum)
+
+ extension = singleton 1*("-" (2*8alphanum))
+
+ ; Single alphanumerics
+ ; "x" reserved for private use
+ singleton = DIGIT ; 0 - 9
+ / %x41-57 ; A - W
+ / %x59-5A ; Y - Z
+ / %x61-77 ; a - w
+ / %x79-7A ; y - z
+
+ privateuse = "x" 1*("-" (1*8alphanum))
+
+ grandfathered = irregular ; non-redundant tags registered
+ / regular ; during the RFC 3066 era
+
+ irregular = "en-GB-oed" ; irregular tags do not match
+ / "i-ami" ; the 'langtag' production and
+ / "i-bnn" ; would not otherwise be
+ / "i-default" ; considered 'well-formed'
+ / "i-enochian" ; These tags are all valid,
+ / "i-hak" ; but most are deprecated
+ / "i-klingon" ; in favor of more modern
+ / "i-lux" ; subtags or subtag
+ / "i-mingo" ; combination
+ / "i-navajo"
+ / "i-pwn"
+ / "i-tao"
+ / "i-tay"
+ / "i-tsu"
+ / "sgn-BE-FR"
+ / "sgn-BE-NL"
+ / "sgn-CH-DE"
+
+ regular = "art-lojban" ; these tags match the 'langtag'
+ / "cel-gaulish" ; production, but their subtags
+ / "no-bok" ; are not extended language
+ / "no-nyn" ; or variant subtags: their meaning
+ / "zh-guoyu" ; is defined by their registration
+ / "zh-hakka" ; and all of these are deprecated
+ / "zh-min" ; in favor of a more modern
+ / "zh-min-nan" ; subtag or sequence of subtags
+ / "zh-xiang"
+
+ alphanum = (ALPHA / DIGIT) ; letters and numbers
+
+*/
+
+namespace mbgl {
+
+namespace qi = boost::spirit::qi;
+namespace phoenix = boost::phoenix;
+namespace ascii = boost::spirit::ascii;
+
+template <typename Iterator>
+struct bcp47_parser : qi::grammar<Iterator>
+{
+ bcp47_parser() : bcp47_parser::base_type(start)
+ {
+ using qi::lit;
+ using qi::repeat;
+ using qi::inf;
+ using qi::eoi;
+ using ascii::char_;
+ using ascii::no_case;
+ using ascii::digit;
+ using ascii::alnum;
+ using ascii::alpha;
+
+ using boost::spirit::qi::_1;
+
+ start %= no_case[langtag | privateuse | grandfathered];
+
+ langtag %= (language) [phoenix::ref(languageTag.language) = _1]
+ >> -("-" >> (script)[phoenix::ref(languageTag.script) = _1])
+ >> -("-" >> (region)[phoenix::ref(languageTag.region) = _1])
+ >> *("-" >> variant)
+ >> *("-" >> extension)
+ >> -("-" >> privateuse);
+
+ language %= (repeat(2,3)[alpha] >> -("-" >> extlang)) // shortest ISO 639 code
+ // sometimes followed by extended language subtags
+ | repeat(4)[alpha] // or reserved for future use
+ | repeat(5,8)[alpha]; // or registered language subtag
+
+ // We add lookaheads for "-"/eoi so that spurious matches on subtags don't prevent backtracking
+ extlang = repeat(3)[alpha] >> (&lit('-') | eoi) >> repeat(0,2)["-" >> repeat(3)[alpha] >> (&lit('-') | eoi)];
+
+ script = repeat(4)[alpha] >> (&lit('-') | eoi);
+
+ region = (repeat(2)[alpha] | repeat(3)[digit]) >> (&lit('-') | eoi);
+
+ variant = (repeat(5,8)[alnum] | (digit >> repeat(3,inf)[alnum])) >> (&lit('-') | eoi);
+
+ extension = singleton >> +("-" >> repeat(2,8)[alnum]) >> (&lit('-') | eoi);
+
+ singleton = digit | char_('a','w') | char_('y','z'); // "no-case" handles A-W and Y-Z
+
+ privateuse = "x" >> +("-" >> repeat(1,8)[alnum]) >> (&lit('-') | eoi);
+
+ grandfathered = regular | irregular;
+
+ irregular = lit("en-GB-oed")
+ | "i-ami"
+ | "i-bnn"
+ | "i-default"
+ | "i-enochian"
+ | "i-hak"
+ | "i-klingon"
+ | "i-lux"
+ | "i-mingo"
+ | "i-navajo"
+ | "i-pwn"
+ | "i-tao"
+ | "i-tay"
+ | "i-tsu"
+ | "sgn-BE-FR"
+ | "sgn-BE-NL"
+ | "sgn-CH-DE";
+
+ regular = lit("art-lojban")
+ | "cel-gaulish"
+ | "no-bok"
+ | "no-nyn"
+ | "zh-guoyu"
+ | "zh-hakka"
+ | "zh-min"
+ | "zh-min-nan"
+ | "zh-xiang";
+ }
+
+ qi::rule<Iterator> start;
+ qi::rule<Iterator> langtag;
+ qi::rule<Iterator, std::string()> language;
+ qi::rule<Iterator> extlang;
+ qi::rule<Iterator, std::string()> script;
+ qi::rule<Iterator, std::string()> region;
+ qi::rule<Iterator> variant;
+ qi::rule<Iterator> extension;
+ qi::rule<Iterator> singleton;
+ qi::rule<Iterator> privateuse;
+ qi::rule<Iterator> grandfathered;
+ qi::rule<Iterator> irregular;
+ qi::rule<Iterator> regular;
+
+ LanguageTag languageTag;
+};
+
+LanguageTag LanguageTag::fromBCP47(const std::string& bcp47Tag) {
+ typedef std::string::const_iterator iterator_type;
+ typedef bcp47_parser<iterator_type> bcp47_parser;
+
+ bcp47_parser parser;
+ std::string::const_iterator iter = bcp47Tag.begin();
+ std::string::const_iterator end = bcp47Tag.end();
+ bool r = parse(iter, end, parser);
+ if (r && iter == end) {
+ return parser.languageTag;
+ } else {
+ // Invalid tags are treated as empty/"default"
+ return LanguageTag();
+ }
+}
+
+LanguageTag::LanguageTag(optional<std::string> language_, optional<std::string> script_, optional<std::string> region_)
+ : language(std::move(language_))
+ , script(std::move(script_))
+ , region(std::move(region_))
+{}
+
+std::string LanguageTag::toBCP47() const {
+ std::stringstream bcp47;
+ if (!language) {
+ // BCP 47 requires a language, but we're matching implementations that accept ""
+ // to mean something like "default"
+ return bcp47.str();
+ } else {
+ bcp47 << *language;
+ }
+
+ if (script) {
+ bcp47 << "-" << *script;
+ }
+
+ if (region) {
+ bcp47 << "-" << *region;
+ }
+ return bcp47.str();
+}
+} // end namespace mbgl
diff --git a/src/mbgl/text/language_tag.hpp b/src/mbgl/text/language_tag.hpp
new file mode 100644
index 0000000000..7a6a16531f
--- /dev/null
+++ b/src/mbgl/text/language_tag.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <mbgl/util/optional.hpp>
+
+#include <string>
+
+/*
+ Use LanguageTag to go back and forth between BCP 47 language tags
+ and their component language/script/region.
+
+ This implementation accepts but will not round-trip additional
+ variant/extension/privateuse/grandfathered information in a BCP 47 tag.
+
+ Why implement this?
+ Mapbox Style Spec specifies locales with BCP 47
+ Android and Intl.Collator implementations speak BCP 47 out of the box
+ Darwin implementation requires translation to "Language Identifier"
+ We're OK with not supporting extensions, but we want to succesfully
+ parse any valid BCP 47 tag and get out the base language/script/region.
+
+ Mozilla's version: https://dxr.mozilla.org/mozilla-central/source/intl/locale/MozLocale.cpp
+ Looks like it actually supports a subset of BCP 47.
+ See https://bugzilla.mozilla.org/show_bug.cgi?id=bcp47
+
+ Chromium is based on ICU version: https://ssl.icu-project.org/apiref/icu4c/uloc_8h.html
+ Getting all the locale information is overkill for us, we just want
+ language/script/region.
+ */
+
+namespace mbgl {
+
+struct LanguageTag {
+ LanguageTag() = default;
+ LanguageTag(optional<std::string> language_, optional<std::string> script_, optional<std::string> region_);
+
+ static LanguageTag fromBCP47(const std::string& bcp47Tag);
+ std::string toBCP47() const;
+
+ optional<std::string> language; // ISO 639
+ optional<std::string> script; // ISO 15924
+ optional<std::string> region; // ISO 3316-1 || UN M.49
+};
+
+} // end namespace mbgl
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 9883a1f456..16dd94b374 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -38,7 +38,6 @@ Placement::Placement(const TransformState& state_, MapMode mapMode_)
: collisionIndex(state_)
, state(state_)
, mapMode(mapMode_)
- , recentUntil(TimePoint::min())
{}
void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatrix, bool showCollisionBoxes) {
@@ -51,12 +50,13 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri
}
assert(dynamic_cast<GeometryTile*>(&renderTile.tile));
GeometryTile& geometryTile = static_cast<GeometryTile&>(renderTile.tile);
-
-
- auto bucket = geometryTile.getBucket(*symbolLayer.baseImpl);
- assert(dynamic_cast<SymbolBucket*>(bucket));
- SymbolBucket& symbolBucket = *reinterpret_cast<SymbolBucket*>(bucket);
-
+
+ auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl);
+ if (!bucket) {
+ continue;
+ }
+ SymbolBucket& symbolBucket = *bucket;
+
if (symbolBucket.bucketLeaderID != symbolLayer.getID()) {
// Only place this layer if it's the "group leader" for the bucket
continue;
@@ -188,7 +188,7 @@ void Placement::placeLayerBucket(
bucket.justReloaded = false;
}
-bool Placement::commit(const Placement& prevPlacement, TimePoint now) {
+void Placement::commit(const Placement& prevPlacement, TimePoint now) {
commitTime = now;
bool placementChanged = false;
@@ -222,7 +222,7 @@ bool Placement::commit(const Placement& prevPlacement, TimePoint now) {
}
}
- return placementChanged;
+ fadeStartTime = placementChanged ? commitTime : prevPlacement.fadeStartTime;
}
void Placement::updateLayerOpacities(RenderSymbolLayer& symbolLayer) {
@@ -232,9 +232,12 @@ void Placement::updateLayerOpacities(RenderSymbolLayer& symbolLayer) {
continue;
}
- auto bucket = renderTile.tile.getBucket(*symbolLayer.baseImpl);
- assert(dynamic_cast<SymbolBucket*>(bucket));
- SymbolBucket& symbolBucket = *reinterpret_cast<SymbolBucket*>(bucket);
+ auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl);
+ if (!bucket) {
+ continue;
+ }
+ SymbolBucket& symbolBucket = *bucket;
+
if (symbolBucket.bucketLeaderID != symbolLayer.getID()) {
// Only update opacities this layer if it's the "group leader" for the bucket
continue;
@@ -302,24 +305,36 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
}
auto updateCollisionBox = [&](const auto& feature, const bool placed) {
+ if (feature.alongLine) {
+ return;
+ }
+ auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(placed, false);
+ for (size_t i = 0; i < feature.boxes.size() * 4; i++) {
+ bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex);
+ }
+ };
+
+ auto updateCollisionCircles = [&](const auto& feature, const bool placed) {
+ if (!feature.alongLine) {
+ return;
+ }
for (const CollisionBox& box : feature.boxes) {
- if (feature.alongLine) {
- auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(placed, !box.used);
- bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
- } else {
- auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(placed, false);
- bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex);
- }
+ auto dynamicVertex = CollisionBoxDynamicAttributes::vertex(placed, !box.used);
+ bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
+ bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
+ bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
+ bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex);
}
};
- updateCollisionBox(symbolInstance.textCollisionFeature, opacityState.text.placed);
- updateCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed);
+
+ if (bucket.hasCollisionBoxData()) {
+ updateCollisionBox(symbolInstance.textCollisionFeature, opacityState.text.placed);
+ updateCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed);
+ }
+ if (bucket.hasCollisionCircleData()) {
+ updateCollisionCircles(symbolInstance.textCollisionFeature, opacityState.text.placed);
+ updateCollisionCircles(symbolInstance.iconCollisionFeature, opacityState.icon.placed);
+ }
}
bucket.updateOpacity();
@@ -339,18 +354,15 @@ float Placement::symbolFadeChange(TimePoint now) const {
}
bool Placement::hasTransitions(TimePoint now) const {
- return symbolFadeChange(now) < 1.0 || stale;
+ if (mapMode == MapMode::Continuous) {
+ return stale || std::chrono::duration<float>(now - fadeStartTime) < Duration(std::chrono::milliseconds(300));
+ } else {
+ return false;
+ }
}
bool Placement::stillRecent(TimePoint now) const {
- return mapMode == MapMode::Continuous && recentUntil > now;
-}
-void Placement::setRecent(TimePoint now) {
- stale = false;
- if (mapMode == MapMode::Continuous) {
- // Only set in continuous mode because "now" isn't defined in still mode
- recentUntil = now + Duration(std::chrono::milliseconds(300));
- }
+ return mapMode == MapMode::Continuous && commitTime + Duration(std::chrono::milliseconds(300)) > now;
}
void Placement::setStale() {
diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp
index 0e1751b127..24de4c054a 100644
--- a/src/mbgl/text/placement.hpp
+++ b/src/mbgl/text/placement.hpp
@@ -63,7 +63,7 @@ class Placement {
public:
Placement(const TransformState&, MapMode mapMode);
void placeLayer(RenderSymbolLayer&, const mat4&, bool showCollisionBoxes);
- bool commit(const Placement& prevPlacement, TimePoint);
+ void commit(const Placement& prevPlacement, TimePoint);
void updateLayerOpacities(RenderSymbolLayer&);
float symbolFadeChange(TimePoint now) const;
bool hasTransitions(TimePoint now) const;
@@ -94,12 +94,12 @@ private:
TransformState state;
MapMode mapMode;
+ TimePoint fadeStartTime;
TimePoint commitTime;
std::unordered_map<uint32_t, JointPlacement> placements;
std::unordered_map<uint32_t, JointOpacityState> opacities;
- TimePoint recentUntil;
bool stale = false;
std::unordered_map<uint32_t, RetainedQueryData> retainedQueryData;
diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp
index 0014ae8d01..ec4461ac6d 100644
--- a/src/mbgl/text/quads.cpp
+++ b/src/mbgl/text/quads.cpp
@@ -117,7 +117,7 @@ SymbolQuads getGlyphQuads(const Shaping& shapedText,
const float rectBuffer = 3.0f + glyphPadding;
const float halfAdvance = glyph.metrics.advance / 2.0;
- const bool alongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && placement == SymbolPlacementType::Line;
+ const bool alongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && placement != SymbolPlacementType::Point;
const Point<float> glyphOffset = alongLine ?
Point<float>{ positionedGlyph.x + halfAdvance, positionedGlyph.y } :
diff --git a/src/mbgl/tile/custom_geometry_tile.cpp b/src/mbgl/tile/custom_geometry_tile.cpp
index a2fefcfa9f..24f3526184 100644
--- a/src/mbgl/tile/custom_geometry_tile.cpp
+++ b/src/mbgl/tile/custom_geometry_tile.cpp
@@ -3,7 +3,6 @@
#include <mbgl/renderer/query.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/actor/scheduler.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/tile/tile_observer.hpp>
#include <mbgl/style/custom_tile_loader.hpp>
@@ -39,9 +38,9 @@ void CustomGeometryTile::setTileData(const GeoJSON& geoJSON) {
vtOptions.extent = util::EXTENT;
vtOptions.buffer = ::round(scale * options.buffer);
vtOptions.tolerance = scale * options.tolerance;
- featureData = mapbox::geojsonvt::geoJSONToTile(geoJSON, id.canonical.z, id.canonical.x, id.canonical.y, vtOptions, options.wrap, options.clip).features;
- } else {
- setNecessity(TileNecessity::Optional);
+ featureData = mapbox::geojsonvt::geoJSONToTile(geoJSON,
+ id.canonical.z, id.canonical.x, id.canonical.y,
+ vtOptions, options.wrap, options.clip).features;
}
setData(std::make_unique<GeoJSONTileData>(std::move(featureData)));
}
diff --git a/src/mbgl/tile/geojson_tile.cpp b/src/mbgl/tile/geojson_tile.cpp
index f211c03569..7a83da2267 100644
--- a/src/mbgl/tile/geojson_tile.cpp
+++ b/src/mbgl/tile/geojson_tile.cpp
@@ -2,7 +2,6 @@
#include <mbgl/tile/geojson_tile_data.hpp>
#include <mbgl/renderer/query.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
namespace mbgl {
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 8efe12d54f..d686d8440b 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -16,7 +16,6 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/map/transform_state.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/actor/scheduler.hpp>
@@ -87,7 +86,7 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) {
pending = true;
++correlationID;
- worker.invoke(&GeometryTileWorker::setData, std::move(data_), correlationID);
+ worker.self().invoke(&GeometryTileWorker::setData, std::move(data_), correlationID);
}
@@ -113,14 +112,14 @@ void GeometryTile::setLayers(const std::vector<Immutable<Layer::Impl>>& layers)
}
++correlationID;
- worker.invoke(&GeometryTileWorker::setLayers, std::move(impls), correlationID);
+ worker.self().invoke(&GeometryTileWorker::setLayers, std::move(impls), correlationID);
}
void GeometryTile::setShowCollisionBoxes(const bool showCollisionBoxes_) {
if (showCollisionBoxes != showCollisionBoxes_) {
showCollisionBoxes = showCollisionBoxes_;
++correlationID;
- worker.invoke(&GeometryTileWorker::setShowCollisionBoxes, showCollisionBoxes, correlationID);
+ worker.self().invoke(&GeometryTileWorker::setShowCollisionBoxes, showCollisionBoxes, correlationID);
}
}
@@ -154,7 +153,7 @@ void GeometryTile::onError(std::exception_ptr err, const uint64_t resultCorrelat
}
void GeometryTile::onGlyphsAvailable(GlyphMap glyphs) {
- worker.invoke(&GeometryTileWorker::onGlyphsAvailable, std::move(glyphs));
+ worker.self().invoke(&GeometryTileWorker::onGlyphsAvailable, std::move(glyphs));
}
void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) {
@@ -162,7 +161,7 @@ void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) {
}
void GeometryTile::onImagesAvailable(ImageMap images, uint64_t imageCorrelationID) {
- worker.invoke(&GeometryTileWorker::onImagesAvailable, std::move(images), imageCorrelationID);
+ worker.self().invoke(&GeometryTileWorker::onImagesAvailable, std::move(images), imageCorrelationID);
}
void GeometryTile::getImages(ImageRequestPair pair) {
diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp
index 449d8cab28..bd64a1d153 100644
--- a/src/mbgl/tile/geometry_tile_data.hpp
+++ b/src/mbgl/tile/geometry_tile_data.hpp
@@ -22,19 +22,19 @@ class GeometryCoordinates : public std::vector<GeometryCoordinate> {
public:
using coordinate_type = int16_t;
- GeometryCoordinates() = default;
- GeometryCoordinates(const std::vector<GeometryCoordinate>& v)
- : std::vector<GeometryCoordinate>(v) {}
- GeometryCoordinates(std::vector<GeometryCoordinate>&& v)
- : std::vector<GeometryCoordinate>(std::move(v)) {}
-
- using std::vector<GeometryCoordinate>::vector;
+ template <class... Args>
+ GeometryCoordinates(Args&&... args) : std::vector<GeometryCoordinate>(std::forward<Args>(args)...) {}
+ GeometryCoordinates(std::initializer_list<GeometryCoordinate> args)
+ : std::vector<GeometryCoordinate>(std::move(args)) {}
};
class GeometryCollection : public std::vector<GeometryCoordinates> {
public:
using coordinate_type = int16_t;
- using std::vector<GeometryCoordinates>::vector;
+ template <class... Args>
+ GeometryCollection(Args&&... args) : std::vector<GeometryCoordinates>(std::forward<Args>(args)...) {}
+ GeometryCollection(std::initializer_list<GeometryCoordinates> args)
+ : std::vector<GeometryCoordinates>(std::move(args)) {}
};
class GeometryTileFeature {
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index 2e7d588d9b..31f4b89801 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -5,7 +5,6 @@
#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/group_by_layout.hpp>
#include <mbgl/style/filter.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
@@ -13,6 +12,7 @@
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/exception.hpp>
+#include <mbgl/util/stopwatch.hpp>
#include <unordered_set>
@@ -320,6 +320,7 @@ void GeometryTileWorker::parse() {
return;
}
+ MBGL_TIMING_START(watch)
std::vector<std::string> symbolOrder;
for (auto it = layers->rbegin(); it != layers->rend(); it++) {
if ((*it)->type == LayerType::Symbol) {
@@ -404,6 +405,11 @@ void GeometryTileWorker::parse() {
requestNewGlyphs(glyphDependencies);
requestNewImages(imageDependencies);
+ MBGL_TIMING_FINISH(watch,
+ " Action: " << "Parsing," <<
+ " SourceID: " << sourceID.c_str() <<
+ " Canonical: " << static_cast<int>(id.canonical.z) << "/" << id.canonical.x << "/" << id.canonical.y <<
+ " Time");
performSymbolLayout();
}
@@ -425,6 +431,7 @@ void GeometryTileWorker::performSymbolLayout() {
return;
}
+ MBGL_TIMING_START(watch)
optional<AlphaImage> glyphAtlasImage;
optional<PremultipliedImage> iconAtlasImage;
@@ -467,6 +474,11 @@ void GeometryTileWorker::performSymbolLayout() {
firstLoad = false;
+ MBGL_TIMING_FINISH(watch,
+ " Action: " << "SymbolLayout," <<
+ " SourceID: " << sourceID.c_str() <<
+ " Canonical: " << static_cast<int>(id.canonical.z) << "/" << id.canonical.x << "/" << id.canonical.y <<
+ " Time");
parent.invoke(&GeometryTile::onLayout, GeometryTile::LayoutResult {
std::move(buckets),
std::move(featureIndex),
diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp
index 5db298cf4c..f29861ee71 100644
--- a/src/mbgl/tile/raster_dem_tile.cpp
+++ b/src/mbgl/tile/raster_dem_tile.cpp
@@ -48,7 +48,7 @@ void RasterDEMTile::setMetadata(optional<Timestamp> modified_, optional<Timestam
void RasterDEMTile::setData(std::shared_ptr<const std::string> data) {
pending = true;
++correlationID;
- worker.invoke(&RasterDEMTileWorker::parse, data, correlationID, encoding);
+ worker.self().invoke(&RasterDEMTileWorker::parse, data, correlationID, encoding);
}
void RasterDEMTile::onParsed(std::unique_ptr<HillshadeBucket> result, const uint64_t resultCorrelationID) {
diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp
index ff23d4493e..cc71c04ba1 100644
--- a/src/mbgl/tile/raster_tile.cpp
+++ b/src/mbgl/tile/raster_tile.cpp
@@ -37,7 +37,7 @@ void RasterTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp>
void RasterTile::setData(std::shared_ptr<const std::string> data) {
pending = true;
++correlationID;
- worker.invoke(&RasterTileWorker::parse, data, correlationID);
+ worker.self().invoke(&RasterTileWorker::parse, data, correlationID);
}
void RasterTile::onParsed(std::unique_ptr<RasterBucket> result, const uint64_t resultCorrelationID) {
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index 23d6864205..5cf74abff5 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -48,6 +48,12 @@ public:
virtual void upload(gl::Context&) = 0;
virtual Bucket* getBucket(const style::Layer::Impl&) const = 0;
+ template <class T>
+ T* getBucket(const style::Layer::Impl& layer) const {
+ Bucket* bucket = getBucket(layer);
+ return bucket ? bucket->as<T>() : nullptr;
+ }
+
virtual void setShowCollisionBoxes(const bool) {}
virtual void setLayers(const std::vector<Immutable<style::Layer::Impl>>&) {}
virtual void setMask(TileMask&&) {}
@@ -113,7 +119,7 @@ public:
void dumpDebugLogs() const;
- const OverscaledTileID id;
+ OverscaledTileID id;
optional<Timestamp> modified;
optional<Timestamp> expires;
diff --git a/src/mbgl/util/chrono.cpp b/src/mbgl/util/chrono.cpp
index a880093b74..c304548cf1 100644
--- a/src/mbgl/util/chrono.cpp
+++ b/src/mbgl/util/chrono.cpp
@@ -1,6 +1,6 @@
#include <mbgl/util/chrono.hpp>
-#include <parsedate/parsedate.h>
+#include <parsedate/parsedate.hpp>
#include <cstdio>
#include <ctime>
diff --git a/src/mbgl/util/event.cpp b/src/mbgl/util/event.cpp
index 3a3be20f5c..0c08d72a8c 100644
--- a/src/mbgl/util/event.cpp
+++ b/src/mbgl/util/event.cpp
@@ -28,6 +28,7 @@ MBGL_DEFINE_ENUM(Event, {
{ Event::Android, "Android" },
{ Event::Crash, "Crash" },
{ Event::Glyph, "Glyph" },
+ { Event::Timing, "Timing" },
{ Event(-1), "Unknown" },
});
diff --git a/src/mbgl/util/http_header.cpp b/src/mbgl/util/http_header.cpp
index 5921edfb14..4d9e2bf84c 100644
--- a/src/mbgl/util/http_header.cpp
+++ b/src/mbgl/util/http_header.cpp
@@ -7,7 +7,10 @@
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma clang diagnostic push
+
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
+#pragma clang diagnostic ignored "-Wunknown-warning-option"
+#pragma clang diagnostic ignored "-Wtautological-constant-compare"
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
diff --git a/src/mbgl/util/interpolate.cpp b/src/mbgl/util/interpolate.cpp
index 066fa9c462..6b5736f15f 100644
--- a/src/mbgl/util/interpolate.cpp
+++ b/src/mbgl/util/interpolate.cpp
@@ -13,7 +13,8 @@ float interpolationFactor(float base, Range<float> range, float z) {
} else if (base == 1.0f) {
return zoomProgress / zoomDiff;
} else {
- return (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
+ return (std::pow(static_cast<double>(base), zoomProgress) - 1) /
+ (std::pow(static_cast<double>(base), zoomDiff) - 1);
}
}
diff --git a/src/mbgl/util/io.cpp b/src/mbgl/util/io.cpp
index 6a6ed7b250..c84634ac88 100644
--- a/src/mbgl/util/io.cpp
+++ b/src/mbgl/util/io.cpp
@@ -2,6 +2,7 @@
#include <cstdio>
#include <cerrno>
+#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
@@ -9,6 +10,10 @@
namespace mbgl {
namespace util {
+IOException::IOException(int err, const std::string& msg)
+ : std::runtime_error(msg + ": " + std::strerror(errno)), code(err) {
+}
+
void write_file(const std::string &filename, const std::string &data) {
FILE *fd = fopen(filename.c_str(), "wb");
if (fd) {
@@ -20,7 +25,7 @@ void write_file(const std::string &filename, const std::string &data) {
}
std::string read_file(const std::string &filename) {
- std::ifstream file(filename);
+ std::ifstream file(filename, std::ios::binary);
if (file.good()) {
std::stringstream data;
data << file.rdbuf();
@@ -31,7 +36,7 @@ std::string read_file(const std::string &filename) {
}
optional<std::string> readFile(const std::string &filename) {
- std::ifstream file(filename);
+ std::ifstream file(filename, std::ios::binary);
if (file.good()) {
std::stringstream data;
data << file.rdbuf();
@@ -42,9 +47,21 @@ optional<std::string> readFile(const std::string &filename) {
void deleteFile(const std::string& filename) {
const int ret = std::remove(filename.c_str());
- if (ret != 0) {
- throw IOException(errno, "failed to unlink file");
+ if (ret != 0 && errno != ENOENT) {
+ throw IOException(errno, "Could not delete file " + filename);
+ }
+}
+
+void copyFile(const std::string& destination, const std::string& source) {
+ std::ifstream src(source, std::ios::binary);
+ if (!src.good()) {
+ throw IOException(errno, "Cannot read file " + destination);
+ }
+ std::ofstream dst(destination, std::ios::binary);
+ if (!dst.good()) {
+ throw IOException(errno, "Cannot write file " + destination);
}
+ dst << src.rdbuf();
}
} // namespace util
diff --git a/src/mbgl/util/io.hpp b/src/mbgl/util/io.hpp
index 847271acf0..e628e82124 100644
--- a/src/mbgl/util/io.hpp
+++ b/src/mbgl/util/io.hpp
@@ -9,8 +9,7 @@ namespace mbgl {
namespace util {
struct IOException : std::runtime_error {
- IOException(int err, const char* msg) : std::runtime_error(msg), code(err) {
- }
+ IOException(int err, const std::string& msg);
const int code = 0;
};
@@ -19,6 +18,7 @@ std::string read_file(const std::string &filename);
optional<std::string> readFile(const std::string &filename);
void deleteFile(const std::string& filename);
+void copyFile(const std::string& destination, const std::string& source);
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/logging.cpp b/src/mbgl/util/logging.cpp
index 0552eb36cb..d322bd3670 100644
--- a/src/mbgl/util/logging.cpp
+++ b/src/mbgl/util/logging.cpp
@@ -38,8 +38,14 @@ void Log::record(EventSeverity severity, Event event, const char* format, ...) {
record(severity, event, -1, msg);
}
-void Log::record(EventSeverity severity, Event event, int64_t code) {
- record(severity, event, code, std::string());
+void Log::record(EventSeverity severity, Event event, int64_t code, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ char msg[4096];
+ vsnprintf(msg, sizeof(msg), format, args);
+ va_end(args);
+
+ record(severity, event, code, std::string{ msg });
}
void Log::record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
diff --git a/src/mbgl/util/stopwatch.hpp b/src/mbgl/util/stopwatch.hpp
index 6214dae958..0c91342a57 100644
--- a/src/mbgl/util/stopwatch.hpp
+++ b/src/mbgl/util/stopwatch.hpp
@@ -4,9 +4,24 @@
#include <mbgl/util/chrono.hpp>
#include <string>
+#include <sstream>
namespace mbgl {
namespace util {
+
+#ifdef MBGL_TIMING
+// Declare 'watch' as a shared_ptr so it can be captured by value in a lambda function
+#define MBGL_TIMING_START(watch) std::shared_ptr<util::stopwatch> watch = std::make_unique<util::stopwatch>(Event::Timing);
+#define MBGL_TIMING_FINISH(watch, message) \
+ do { \
+ std::stringstream messageStream; \
+ messageStream << message; \
+ watch->report(messageStream.str()); \
+ } while (0);
+#else
+#define MBGL_TIMING_START(watch)
+#define MBGL_TIMING_FINISH(watch, message)
+#endif
#ifndef DISABLE_STOPWATCH
class stopwatch {
diff --git a/src/mbgl/util/tile_coordinate.hpp b/src/mbgl/util/tile_coordinate.hpp
index bcd1c8444f..b6bdc5f590 100644
--- a/src/mbgl/util/tile_coordinate.hpp
+++ b/src/mbgl/util/tile_coordinate.hpp
@@ -20,7 +20,7 @@ public:
static TileCoordinate fromLatLng(double zoom, const LatLng& latLng) {
const double scale = std::pow(2.0, zoom);
- return { Projection::project(latLng, scale) / double(util::tileSize), zoom };
+ return { Projection::project(latLng, scale) / util::tileSize, zoom };
}
static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& screenCoordinate) {
diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp
index 488e6b88ce..3f39e53d40 100644
--- a/src/mbgl/util/tile_cover.cpp
+++ b/src/mbgl/util/tile_cover.cpp
@@ -130,7 +130,7 @@ std::vector<UnwrappedTileID> tileCover(const Point<double>& tl,
} // namespace
int32_t coveringZoomLevel(double zoom, style::SourceType type, uint16_t size) {
- zoom += std::log(util::tileSize / size) / std::log(2);
+ zoom += ::log2(util::tileSize / size);
if (type == style::SourceType::Raster || type == style::SourceType::Video) {
return ::round(zoom);
} else {
diff --git a/src/mbgl/util/tile_cover_impl.cpp b/src/mbgl/util/tile_cover_impl.cpp
index b3fc07f7dd..799ff2666a 100644
--- a/src/mbgl/util/tile_cover_impl.cpp
+++ b/src/mbgl/util/tile_cover_impl.cpp
@@ -17,8 +17,7 @@ struct TileSpan {
bool winding;
};
-
-// Find the first local minimum going forward in the list.
+// Reorder a ring of points such that it starts at a point with a local minimum y-coordinate
void start_list_on_local_minimum(PointList& points) {
auto prev_pt = std::prev(points.end(), 2);
auto pt = points.begin();
@@ -33,6 +32,8 @@ void start_list_on_local_minimum(PointList& points) {
next_pt++;
if (next_pt == points.end()) { next_pt = std::next(points.begin()); }
}
+ if (pt == points.end())
+ return;
//Re-close linear rings with first_pt = last_pt
if (points.back() == points.front()) {
points.pop_back();
@@ -42,37 +43,25 @@ void start_list_on_local_minimum(PointList& points) {
}
//Create a bound towards a local maximum point, starting from pt.
+// Traverse from current pt until the next pt changes y-direction, and copy
+// all points from start to end (inclusive) into a Bound.
Bound create_bound_towards_maximum(PointList& points, PointList::iterator& pt) {
if (std::distance(pt, points.end()) < 2) { return {}; }
- if (std::distance(pt, points.end()) == 2) {
- Bound bnd;
- if (pt->y < std::next(pt)->y) {
- std::copy(pt, points.end(), std::back_inserter(bnd.points));
- bnd.winding = true;
- }
- else {
- std::reverse_copy(pt, points.end(), std::back_inserter(bnd.points));
- bnd.winding = false;
- }
- pt = points.end();
- return bnd;
- }
+
const auto begin = pt;
- auto prev_pt = pt == points.begin() ? std::prev(points.end(), 2) : std::prev(pt);
- auto next_pt = std::next(pt) == points.end() ? std::next(points.begin()) : std::next(pt);
- while (pt != points.end()) {
- if ((pt->y >= prev_pt->y) &&
- (pt->y > next_pt->y )) {
- break;
- }
- prev_pt = pt;
+ auto next_pt = std::next(begin);
+ while (pt->y <= next_pt->y) {
pt++;
next_pt++;
- if (next_pt == points.end()) { next_pt = std::next(points.begin()); }
+ if (next_pt == points.end()) { pt++; break; }
+ }
+
+ const auto pt_distance = std::distance(begin, next_pt);
+ if (pt_distance < 2) {
+ return {};
}
Bound bnd;
- if (std::next(pt) == points.end()) { next_pt = points.end(); pt++; };
bnd.points.reserve(static_cast<std::size_t>(std::distance(begin, next_pt)));
std::copy(begin, next_pt, std::back_inserter(bnd.points));
bnd.winding = true;
@@ -80,37 +69,24 @@ Bound create_bound_towards_maximum(PointList& points, PointList::iterator& pt) {
}
//Create a bound towards a local minimum point, starting from pt.
+// Traverse from current pt until the next pt changes y-direction, and copy
+// all points from start to end (inclusive) into a Bound.
Bound create_bound_towards_minimum(PointList& points, PointList::iterator& pt) {
if (std::distance(pt, points.end()) < 2) { return {}; }
- if (std::distance(pt, points.end()) == 2) {
- Bound bnd;
- if (pt->y < std::next(pt)->y) {
- std::copy(pt, points.end(), std::back_inserter(bnd.points));
- bnd.winding = true;
- }
- else {
- std::reverse_copy(pt, points.end(), std::back_inserter(bnd.points));
- bnd.winding = false;
- }
- pt = points.end();
- return bnd;
- }
+
auto begin = pt;
- auto prev_pt = pt == points.begin() ? std::prev(points.end(), 2) : std::prev(pt);
- auto next_pt = std::next(pt) == points.end() ? std::next(points.begin()) : std::next(pt);
- while (pt != points.end()) {
- if ((pt->y <= prev_pt->y) &&
- (pt->y < next_pt->y)) {
- break;
- }
- prev_pt = pt;
+ auto next_pt = std::next(begin);
+ while (pt->y > next_pt->y) {
pt++;
next_pt++;
- if (next_pt == points.end()) { next_pt = std::next(points.begin()); }
+ if (next_pt == points.end()) { pt++; break; }
}
+ const auto pt_distance = std::distance(begin, next_pt);
+ if (pt_distance < 2) {
+ return {};
+ }
Bound bnd;
- if (std::next(pt) == points.end()) { next_pt = points.end(); pt++; };
bnd.points.reserve(static_cast<std::size_t>(std::distance(begin, next_pt)));
//For bounds that start at a max, reverse copy so that all bounds start at a min
std::reverse_copy(begin, next_pt, std::back_inserter(bnd.points));
@@ -118,10 +94,14 @@ Bound create_bound_towards_minimum(PointList& points, PointList::iterator& pt) {
return bnd;
}
-//Build a map of bounds and their starting Y tile coordinate.
+// Given a set of points (ring or list) representing a shape, compute a set of
+// Bounds, where each Bound represents edges going from a local minima to a local
+// maxima point. The BoundsMap is an edge table indexed on the starting Y-tile
+// of each Bound.
void build_bounds_map(PointList& points, uint32_t maxTile, BoundsMap& et, bool closed = false) {
if (points.size() < 2) return;
- //While traversing closed rings, start the bounds at a local minimum
+ //While traversing closed rings, start the bounds at a local minimum.
+ // (For linestrings the starting point is always a local maxima/minima)
if (closed) {
start_list_on_local_minimum(points);
}
@@ -131,12 +111,12 @@ void build_bounds_map(PointList& points, uint32_t maxTile, BoundsMap& et, bool c
Bound to_max = create_bound_towards_maximum(points, pointsIter);
Bound to_min = create_bound_towards_minimum(points, pointsIter);
- if (to_max.points.size() > 0) {
+ if (to_max.points.size() >= 2) {
// Projections may result in values beyond the bounds, clamp to max tile coordinates
const auto y = static_cast<uint32_t>(std::floor(clamp(to_max.points.front().y, 0.0, (double)maxTile)));
et[y].push_back(to_max);
}
- if (to_min.points.size() > 0) {
+ if (to_min.points.size() >= 2) {
const auto y = static_cast<uint32_t>(std::floor(clamp(to_min.points.front().y, 0.0, (double)maxTile)));
et[y].push_back(to_min);
}
@@ -149,16 +129,19 @@ void update_span(TileSpan& xp, double x) {
xp.xmax = std::max(xp.xmax, static_cast<int32_t>(std::ceil(x)));
}
-//Build a vector of X tile-coordinates spanned by each bound.
-std::vector<TileSpan> scan_row(uint32_t y, Bounds& aet) {
+// Use the active bounds, an accumulation of all bounds that enter the y tile row,
+// or start in that row.
+// Iterate all points of a bound until it exits the row (or ends) and compute the
+// set of X tiles it spans across. The winding direction of the bound is also
+// captured for each span to later fill tiles between bounds for polygons
+std::vector<TileSpan> scan_row(uint32_t y, Bounds& activeBounds) {
std::vector<TileSpan> tile_range;
- tile_range.reserve(aet.size());
+ tile_range.reserve(activeBounds.size());
- for(Bound& b: aet) {
+ for(Bound& b: activeBounds) {
TileSpan xp = { INT_MAX, 0, b.winding };
double x;
const auto numEdges = b.points.size() - 1;
- assert(numEdges >= 1);
while (b.currentPoint < numEdges) {
x = b.interpolate(y);
update_span(xp, x);
@@ -170,7 +153,7 @@ std::vector<TileSpan> scan_row(uint32_t y, Bounds& aet) {
x = b.interpolate(y+1);
update_span(xp, x);
break;
- } else if(b.currentPoint == numEdges - 1) {
+ } else if (b.currentPoint == numEdges - 1) {
// For last edge, consider x-intercept at the end of the edge.
x = p1.x;
update_span(xp, x);
@@ -181,11 +164,11 @@ std::vector<TileSpan> scan_row(uint32_t y, Bounds& aet) {
}
// Erase bounds in the active table whose current edge ends inside this row,
// or there are no more edges
- auto bound = aet.begin();
- while (bound != aet.end()) {
+ auto bound = activeBounds.begin();
+ while (bound != activeBounds.end()) {
if ( bound->currentPoint == bound->points.size() - 1 &&
bound->points[bound->currentPoint].y <= y+1) {
- bound = aet.erase(bound);
+ bound = activeBounds.erase(bound);
} else {
bound++;
}
@@ -225,7 +208,7 @@ struct BuildBoundsMap {
BoundsMap operator()(const Point<double>&p) const {
Bound bnd;
auto point = p;
- if(project) {
+ if (project) {
point = Projection::project(LatLng{p.y, p.x}, zoom);
}
bnd.points.insert(bnd.points.end(), 2, point);
@@ -241,7 +224,7 @@ struct BuildBoundsMap {
for (const Point<double>& p: points) {
Bound bnd;
auto point = p;
- if(project) {
+ if (project) {
point = Projection::project(LatLng{p.y, p.x}, zoom);
}
bnd.points.insert(bnd.points.end(), 2, point);
@@ -302,20 +285,26 @@ TileCover::Impl::Impl(int32_t z, const Geometry<double>& geom, bool project)
tileX = tileXSpans.front().first;
}
+// Aggregate all Bounds that start in or enter into the next tileY row. Multi-geoms
+// may have discontinuity in the BoundMap, so skip forward to the next tileY row
+// when the current/next row has no more bounds in it.
+// Use scan_row to generate the tileX spans. Merge spans to avoid duplicate tiles
+// in TileCoverImpl::next(). For closed geometry, use the non-zero rule to expand
+// (fill) tiles between pairs of spans.
void TileCover::Impl::nextRow() {
- // Update AET for next row
+ // Update activeBounds for next row
if (currentBounds != boundsMap.end()) {
if (activeBounds.size() == 0 && currentBounds->first > tileY) {
//For multi-geoms: use the next row with an edge table starting point
tileY = currentBounds->first;
}
if (tileY == currentBounds->first) {
-
- std::move(currentBounds->second.begin(), currentBounds->second.end(), std::back_inserter(activeBounds));
+ std::move(currentBounds->second.begin(), currentBounds->second.end(),
+ std::back_inserter(activeBounds));
currentBounds++;
}
}
- //Scan aet and update currenRange with x_min, x_max pairs
+ //Scan the active bounds and update currentRange with x_min, x_max pairs
auto xps = util::scan_row(tileY, activeBounds);
if (xps.size() == 0) {
return;
@@ -339,7 +328,9 @@ void TileCover::Impl::nextRow() {
}
bool TileCover::Impl::hasNext() const {
- return (!tileXSpans.empty() && tileX < tileXSpans.front().second && tileY < (1u << zoom));
+ return (!tileXSpans.empty()
+ && tileX < tileXSpans.front().second
+ && tileY < (1u << zoom));
}
optional<UnwrappedTileID> TileCover::Impl::next() {
@@ -350,7 +341,7 @@ optional<UnwrappedTileID> TileCover::Impl::next() {
tileX++;
if (tileX >= tileXSpans.front().second) {
tileXSpans.pop();
- if(tileXSpans.empty()) {
+ if (tileXSpans.empty()) {
tileY++;
nextRow();
}
diff --git a/src/mbgl/util/tile_cover_impl.hpp b/src/mbgl/util/tile_cover_impl.hpp
index 7c16718984..e9c06e44aa 100644
--- a/src/mbgl/util/tile_cover_impl.hpp
+++ b/src/mbgl/util/tile_cover_impl.hpp
@@ -60,6 +60,22 @@ struct Bound {
}
};
+// Implements a modified scan-line algorithm to provide a streaming interface for
+// tile cover on arbitrary shapes.
+// A `BoundsMap` is genereted from the input geometry where each tuple indicates
+// the set of Bounds that start at a y tile coordinate. Each bound represents
+// a chain of edges from a local y-minima to a local y-maxima.
+// For each row, the activeBounds list aggregates all bounds that enter into or
+// begin in that row. This running list of bounds is scanned, capturing the
+// x-coordinates spanned by edges in a bound until the bound exits the row (or
+// ends). The result is a set of (possibly overlapping) min,max pairs of x coordinates
+// (spans). In the simplest case a span represents the x-coordinates at which a
+// single edge intersects the top and bottom of a tile row. Interior tiles of a
+// polygon are captured by merging spans using the non-zero rule.
+// The result of a scan using `nextRow()` is a list of spans (tileXSpans) of x-coordinates
+// that includes edges and interiors of polygons.
+// next() returns a tileID for each x-coordinate from (first, second] in each
+// span in tileXSpans.
class TileCover::Impl {
public:
Impl(int32_t z, const Geometry<double>& geom, bool project = true);
diff --git a/src/mbgl/util/token.hpp b/src/mbgl/util/token.hpp
index 149661e47e..dea12f9412 100644
--- a/src/mbgl/util/token.hpp
+++ b/src/mbgl/util/token.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/optional.hpp>
+
#include <map>
#include <string>
#include <algorithm>
@@ -25,7 +27,14 @@ std::string replaceTokens(const std::string &source, const Lookup &lookup) {
if (pos != end) {
for (brace++; brace != end && tokenReservedChars.find(*brace) == std::string::npos; brace++);
if (brace != end && *brace == '}') {
- result.append(lookup({ pos + 1, brace }));
+ std::string key { pos + 1, brace };
+ if (optional<std::string> replacement = lookup(key)) {
+ result.append(*replacement);
+ } else {
+ result.append("{");
+ result.append(key);
+ result.append("}");
+ }
pos = brace + 1;
} else {
result.append(pos, brace);
diff --git a/src/mbgl/util/url.cpp b/src/mbgl/util/url.cpp
index 1f6dab9639..a4263502ef 100644
--- a/src/mbgl/util/url.cpp
+++ b/src/mbgl/util/url.cpp
@@ -130,7 +130,7 @@ Path::Path(const std::string& str, const size_t pos, const size_t count)
}
std::string transformURL(const std::string& tpl, const std::string& str, const URL& url) {
- auto result = util::replaceTokens(tpl, [&](const std::string& token) -> std::string {
+ auto result = util::replaceTokens(tpl, [&](const std::string& token) -> optional<std::string> {
if (token == "path") {
return str.substr(url.path.first, url.path.second);
} else if (token == "domain") {
@@ -146,8 +146,9 @@ std::string transformURL(const std::string& tpl, const std::string& str, const U
} else if (token == "extension") {
const Path path(str, url.path.first, url.path.second);
return str.substr(path.extension.first, path.extension.second);
+ } else {
+ return {};
}
- return "";
});
// Append the query string if it exists.
diff --git a/src/parsedate/parsedate.c b/src/parsedate/parsedate.cpp
index 7228c4edbc..ff945589bb 100644
--- a/src/parsedate/parsedate.c
+++ b/src/parsedate/parsedate.cpp
@@ -73,7 +73,7 @@
*/
-#include "parsedate.h"
+#include "parsedate.hpp"
@@ -671,7 +671,7 @@ static int parsedate(const char *date, time_t *output)
time_t parse_date(const char *p)
{
- time_t parsed;
+ time_t parsed = -1;
int rc = parsedate(p, &parsed);
switch(rc) {
diff --git a/src/parsedate/parsedate.h b/src/parsedate/parsedate.hpp
index 6905e361d4..6905e361d4 100644
--- a/src/parsedate/parsedate.h
+++ b/src/parsedate/parsedate.hpp
diff --git a/vendor/nunicode/LICENSE b/vendor/nunicode/LICENSE
new file mode 100644
index 0000000000..1cf5af29d2
--- /dev/null
+++ b/vendor/nunicode/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Aleksey Tulinov <aleksey.tulinov@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/nunicode/files.txt b/vendor/nunicode/files.txt
new file mode 100644
index 0000000000..03b92272aa
--- /dev/null
+++ b/vendor/nunicode/files.txt
@@ -0,0 +1,20 @@
+include/libnu/casemap.h
+include/libnu/casemap_internal.h
+include/libnu/config.h
+include/libnu/defines.h
+include/libnu/ducet.h
+include/libnu/mph.h
+include/libnu/strcoll.h
+include/libnu/strcoll_internal.h
+include/libnu/strings.h
+include/libnu/udb.h
+include/libnu/unaccent.h
+include/libnu/utf8.h
+include/libnu/utf8_internal.h
+src/libnu/ducet.c
+src/libnu/strcoll.c
+src/libnu/strings.c
+src/libnu/tolower.c
+src/libnu/tounaccent.c
+src/libnu/toupper.c
+src/libnu/utf8.c
diff --git a/vendor/nunicode/include/libnu/casemap.h b/vendor/nunicode/include/libnu/casemap.h
new file mode 100644
index 0000000000..e851ab40ca
--- /dev/null
+++ b/vendor/nunicode/include/libnu/casemap.h
@@ -0,0 +1,140 @@
+#ifndef NU_TOUPPER_H
+#define NU_TOUPPER_H
+
+#include <stdint.h>
+
+#include <libnu/config.h>
+#include <libnu/defines.h>
+#include <libnu/strings.h>
+#include <libnu/udb.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+/**
+ * @example folding.c
+ * @example special_casing.c
+ */
+
+/** Synonim to nu_casemap_read. It is recommended to use
+ * nu_casemap_read instead.
+ */
+#define NU_CASEMAP_DECODING_FUNCTION NU_UDB_DECODING_FUNCTION
+/** Read (decoding) function for use with transformation results of
+ * casemapping functions. E.g. nu_casemap_read(nu_tolower(0x0041));
+ * will read first codepoint of 'A' transformed to lower case.
+ */
+#define nu_casemap_read (nu_udb_read)
+
+/** Casemap codepoint
+ *
+ * @ingroup transformations
+ */
+typedef nu_transformation_t nu_casemapping_t;
+
+#ifdef NU_WITH_TOUPPER
+
+/** Return uppercase value of codepoint. Uncoditional casemapping.
+ *
+ * @ingroup transformations
+ * @param codepoint unicode codepoint
+ * @return uppercase codepoint or 0 if mapping doesn't exist
+ */
+NU_EXPORT
+const char* nu_toupper(uint32_t codepoint);
+
+/** Return uppercase value of codepoint. Context-sensitivity is not
+ * implemented internally, returned result is equal to calling nu_toupper()
+ * on corresponding codepoint.
+ *
+ * @ingroup transformations_internal
+ * @param encoded pointer to encoded string
+ * @param limit memory limit of encoded string or NU_UNLIMITED
+ * @param read read (decoding) function
+ * @param u (optional) codepoint which was (or wasn't) transformed
+ * @param transform output value of codepoint transformed into uppercase or 0
+ * if mapping doesn't exist. Can't be NULL, supposed to be decoded with
+ * nu_casemap_read
+ * @param context not used
+ * @return pointer to the next codepoint in string
+ */
+NU_EXPORT
+const char* _nu_toupper(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context);
+
+#endif /* NU_WITH_TOUPPER */
+
+#ifdef NU_WITH_TOLOWER
+
+/** Return lowercase value of codepoint. Unconditional casemapping.
+ *
+ * @ingroup transformations
+ * @param codepoint unicode codepoint
+ * @return lowercase codepoint or 0 if mapping doesn't exist
+ */
+NU_EXPORT
+const char* nu_tolower(uint32_t codepoint);
+
+/** Return lowercase value of codepoint. Will transform uppercase
+ * Sigma ('Σ') into final sigma ('ς') if it occurs at string boundary or
+ * followed by U+0000. Might require single read-ahead when
+ * encountering Sigma.
+ *
+ * @ingroup transformations_internal
+ * @param encoded pointer to encoded string
+ * @param limit memory limit of encoded string or NU_UNLIMITED
+ * @param read read (decoding) function
+ * @param u (optional) codepoint which was (or wasn't) transformed
+ * @param transform output value of codepoint transformed into lowercase or 0
+ * if mapping doesn't exist. Can't be NULL, supposed to be decoded with
+ * nu_casemap_read
+ * @param context not used
+ * @return pointer to the next codepoint in string
+ */
+NU_EXPORT
+const char* _nu_tolower(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context);
+
+#endif /* NU_WITH_TOLOWER */
+
+#ifdef NU_WITH_TOFOLD
+
+/** Return value of codepoint with case differences eliminated
+ *
+ * @ingroup transformations
+ * @param codepoint unicode codepoint
+ * @return casefolded codepoint or 0 if mapping doesn't exist
+ */
+NU_EXPORT
+const char* nu_tofold(uint32_t codepoint);
+
+/** Return value of codepoint with case differences eliminated.
+ * Context-sensitivity is not implemented internally, returned result is equal
+ * to calling nu_tofold() on corresponding codepoint.
+ *
+ * @ingroup transformations_internal
+ * @param encoded pointer to encoded string
+ * @param limit memory limit of encoded string or NU_UNLIMITED
+ * @param read read (decoding) function
+ * @param u (optional) codepoint which was (or wasn't) transformed
+ * @param transform output value of casefolded codepoint or 0
+ * if mapping doesn't exist. Can't be NULL, supposed to be decoded with
+ * nu_casemap_read
+ * @param context not used
+ * @return pointer to the next codepoint in string
+ */
+NU_EXPORT
+const char* _nu_tofold(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context);
+
+#endif /* NU_WITH_TOFOLD */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_TOUPPER_H */
diff --git a/vendor/nunicode/include/libnu/casemap_internal.h b/vendor/nunicode/include/libnu/casemap_internal.h
new file mode 100644
index 0000000000..b97f37c6bf
--- /dev/null
+++ b/vendor/nunicode/include/libnu/casemap_internal.h
@@ -0,0 +1,21 @@
+#ifndef NU_CASEMAP_INTERNAL_H
+#define NU_CASEMAP_INTERNAL_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <libnu/udb.h>
+
+/** Casemap codepoint
+ *
+ * @ingroup transformations_internal
+ */
+static inline
+const char* _nu_to_something(uint32_t codepoint,
+ const int16_t *G, size_t G_SIZE,
+ const uint32_t *VALUES_C, const uint16_t *VALUES_I, const uint8_t *COMBINED) {
+
+ return nu_udb_lookup(codepoint, G, G_SIZE, VALUES_C, VALUES_I, COMBINED);
+}
+
+#endif /* NU_CASEMAP_INTERNAL_H */
diff --git a/vendor/nunicode/include/libnu/config.h b/vendor/nunicode/include/libnu/config.h
new file mode 100644
index 0000000000..6948815b6c
--- /dev/null
+++ b/vendor/nunicode/include/libnu/config.h
@@ -0,0 +1,201 @@
+#ifndef NU_BUILD_CONFIG_H
+#define NU_BUILD_CONFIG_H
+
+// Hardcoded defines for vendored copy
+#define NU_WITH_UTF8
+#define NU_WITH_TOUPPER
+#define NU_WITH_TOLOWER
+#define NU_WITH_UNACCENT
+#define NU_WITH_Z_COLLATION
+
+/** @file config.h
+ *
+ * This file list available build options and provide some shortcuts,
+ * like NU_WITH_UTF16 will enable NU_WITH_UTF16LE + NU_WITH_UTF16BE.
+ *
+ * At build time you might set either particular option or shortcut. Either
+ * way you don't have to and shouldn't modify this file, just set build flags
+ * at the environment.
+ *
+ * This file will also enable several dependencies for you: case-mapping
+ * depends on NU_WITH_UDB, NU_UTF8_READER and so.
+ */
+
+/* Definitions not covered in this file which should be defined
+ * externally.
+ *
+ * NU_BUILD_STATIC: will change functions visibility to "hidden" (GCC).
+ * @see defines.h
+ *
+ * NU_DISABLE_CONTRACTIONS: disables forward-reading during collation,
+ * only weights of a single codepoints will be compared (enabled in release build)
+ */
+
+/* Enable everything, see below for details on a specific option */
+#ifdef NU_WITH_EVERYTHING
+# define NU_WITH_UTF8
+# define NU_WITH_CESU8
+# define NU_WITH_UTF16
+# define NU_WITH_UTF16HE
+# define NU_WITH_UTF32
+# define NU_WITH_UTF32HE
+# define NU_WITH_STRINGS
+# define NU_WITH_EXTRA
+# define NU_WITH_REVERSE_READ
+# define NU_WITH_VALIDATION
+# define NU_WITH_COLLATION
+# define NU_WITH_CASEMAP
+# define NU_WITH_UNACCENT
+#endif /* NU_WITH_EVERYTHING */
+
+/* Enable UTF-8 decoding and encoding */
+#ifdef NU_WITH_UTF8
+# define NU_WITH_UTF8_READER /* UTF-8 decoding functions */
+# define NU_WITH_UTF8_WRITER /* UTF-8 encoding functions */
+#endif /* NU_WITH_UTF8 */
+
+/* Enable CESU-8 decoding and encoding */
+#ifdef NU_WITH_CESU8
+# define NU_WITH_CESU8_READER
+# define NU_WITH_CESU8_WRITER
+#endif /* NU_WITH_CESU8 */
+
+/* Enable UTF-16LE decoding and encoding */
+#ifdef NU_WITH_UTF16LE
+# define NU_WITH_UTF16LE_READER
+# define NU_WITH_UTF16LE_WRITER
+#endif /* NU_WITH_UTF16LE */
+
+/* Enable UTF-16BE decoding and encoding */
+#ifdef NU_WITH_UTF16BE
+# define NU_WITH_UTF16BE_READER
+# define NU_WITH_UTF16BE_WRITER
+#endif /* NU_WITH_UTF16BE */
+
+/* Enable UTF-16HE decoding and encoding */
+#ifdef NU_WITH_UTF16HE
+# define NU_WITH_UTF16HE_READER
+# define NU_WITH_UTF16HE_WRITER
+#endif /* NU_WITH_UTF16HE */
+
+/* Enable all UTF-16 options */
+#ifdef NU_WITH_UTF16
+# define NU_WITH_UTF16_READER
+# define NU_WITH_UTF16_WRITER
+#endif /* NU_WITH_UTF16 */
+
+/* Enable UTF-16LE and BE decoders of UTF-16 decoder is requested */
+#ifdef NU_WITH_UTF16_READER
+# define NU_WITH_UTF16LE_READER
+# define NU_WITH_UTF16BE_READER
+#endif /* NU_WITH_UTF16_READER */
+
+/* Enable UTF-16LE and BE encoders of UTF-16 encoder is requested */
+#ifdef NU_WITH_UTF16_WRITER
+# define NU_WITH_UTF16LE_WRITER
+# define NU_WITH_UTF16BE_WRITER
+#endif /* NU_WITH_UTF16_WRITER */
+
+/* Enable UTF-32LE decoding and encoding */
+#ifdef NU_WITH_UTF32LE
+# define NU_WITH_UTF32LE_READER
+# define NU_WITH_UTF32LE_WRITER
+#endif /* NU_WITH_UTF32LE */
+
+/* Enable UTF-32BE decoding and encoding */
+#ifdef NU_WITH_UTF32BE
+# define NU_WITH_UTF32BE_READER
+# define NU_WITH_UTF32BE_WRITER
+#endif /* NU_WITH_UTF32BE */
+
+/* Enable UTF-32HE decoding and encoding */
+#ifdef NU_WITH_UTF32HE
+# define NU_WITH_UTF32HE_READER
+# define NU_WITH_UTF32HE_WRITER
+#endif /* NU_WITH_UTF32HE */
+
+/* Enable all UTF-32 options */
+#ifdef NU_WITH_UTF32
+# define NU_WITH_UTF32_READER
+# define NU_WITH_UTF32_WRITER
+#endif /* NU_WITH_UTF32 */
+
+/* Enable UTF-32LE and BE decoders of UTF-32 decoder is requested */
+#ifdef NU_WITH_UTF32_READER
+# define NU_WITH_UTF32LE_READER
+# define NU_WITH_UTF32BE_READER
+#endif /* NU_WITH_UTF32_READER */
+
+/* Enable UTF-32LE and BE encoders of UTF-32 encoder is requested */
+#ifdef NU_WITH_UTF32_WRITER
+# define NU_WITH_UTF32LE_WRITER
+# define NU_WITH_UTF32BE_WRITER
+#endif /* NU_WITH_UTF32_WRITER */
+
+/* Shortcut for all string functions */
+#ifdef NU_WITH_STRINGS
+# define NU_WITH_Z_STRINGS /* 0-terminated string functions */
+# define NU_WITH_N_STRINGS /* unterminated string functions */
+#endif /* NU_WITH_STRINGS */
+
+/* Shortcut for extra string functions */
+#ifdef NU_WITH_EXTRA
+# define NU_WITH_Z_EXTRA /* extra functions for 0-terminated strings */
+# define NU_WITH_N_EXTRA /* extra functions for unterminated strings */
+#endif /* NU_WITH_STRINGS */
+
+/* Enable collation functions */
+#ifdef NU_WITH_COLLATION
+# define NU_WITH_Z_COLLATION /* collation functions for 0-terminated strings */
+# define NU_WITH_N_COLLATION /* collation functions for unterminated strings */
+#endif /* NU_WITH_COLLATION */
+
+/* Requirements for collation functions on 0-terminated strings */
+#ifdef NU_WITH_Z_COLLATION
+# define NU_WITH_Z_STRINGS
+# define NU_WITH_TOUPPER /* nu_toupper() */
+#endif
+
+/* Requirements for collation functions
+ * on unterminated strings */
+#ifdef NU_WITH_N_COLLATION
+# define NU_WITH_N_STRINGS
+# define NU_WITH_TOUPPER
+#endif
+
+/* Requirements for casemap functions */
+#ifdef NU_WITH_CASEMAP
+# define NU_WITH_TOLOWER /* nu_tolower() */
+# define NU_WITH_TOUPPER
+# define NU_WITH_TOFOLD
+#endif /* NU_WITH_CASEMAP */
+
+/* More requirements for collation functions all collation functions depends
+ * on NU_WITH_DUCET */
+#if (defined NU_WITH_Z_COLLATION) || (defined NU_WITH_N_COLLATION)
+# ifndef NU_WITH_DUCET
+# define NU_WITH_DUCET
+# endif
+#endif
+
+/* All collation and casemapping functions depends on NU_WITH_UDB */
+#if (defined NU_WITH_Z_COLLATION) || (defined NU_WITH_N_COLLATION) \
+|| (defined NU_WITH_TOLOWER) || (defined NU_WITH_TOUPPER) || (defined NU_WITH_TOFOLD) \
+|| (defined NU_WITH_UNACCENT)
+# ifndef NU_WITH_UDB
+# define NU_WITH_UDB /* nu_udb_* functions, pretty much internal stuff */
+# endif /* NU_WITH_UDB */
+#endif
+
+/* DUCET implementation depends on NU_WITH_UDB */
+#ifdef NU_WITH_DUCET
+# define NU_WITH_UDB
+#endif /* NU_WITH_DUCET */
+
+/* NU_WITH_UDB depends on NU_WITH_UTF8_READER because internal encoding
+ * of UDB is UTF-8 */
+#ifdef NU_WITH_UDB
+# define NU_WITH_UTF8_READER
+#endif /* NU_WITH_UDB */
+
+#endif /* NU_BUILD_CONFIG_H */
diff --git a/vendor/nunicode/include/libnu/defines.h b/vendor/nunicode/include/libnu/defines.h
new file mode 100644
index 0000000000..2678013f94
--- /dev/null
+++ b/vendor/nunicode/include/libnu/defines.h
@@ -0,0 +1,43 @@
+#ifndef NU_DEFINES_H
+#define NU_DEFINES_H
+
+/** @file
+ */
+
+/** @defgroup defines Defines
+ */
+
+#ifndef NU_EXPORT
+
+# ifdef _WIN32
+# define NU_EXPORT __declspec(dllexport)
+
+# elif __GNUC__ >= 4
+# ifdef NU_BUILD_STATIC
+# define NU_EXPORT __attribute__ ((visibility ("hidden")))
+# else
+# define NU_EXPORT __attribute__ ((visibility ("default")))
+# endif
+
+# else
+# define NU_EXPORT
+# endif
+
+#endif /* NU_EXPORT */
+
+/** Integer version of Unicode specification implemented. 900 == 9.0.0
+ *
+ * @ingroup defines
+ */
+#define NU_UNICODE_VERSION 1000
+/** Special limit value to unset limit on string. Used internally by nunicode.
+ *
+ * @ingroup defines
+ */
+#define NU_UNLIMITED ((const void *)(-1))
+
+#ifdef _MSC_VER
+#define ssize_t ptrdiff_t
+#endif
+
+#endif /* NU_DEFINES_H */
diff --git a/vendor/nunicode/include/libnu/ducet.h b/vendor/nunicode/include/libnu/ducet.h
new file mode 100644
index 0000000000..ecc65e84d8
--- /dev/null
+++ b/vendor/nunicode/include/libnu/ducet.h
@@ -0,0 +1,37 @@
+#ifndef NU_DUCET_H
+#define NU_DUCET_H
+
+#include <stdint.h>
+
+#include <libnu/config.h>
+#include <libnu/defines.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+#ifdef NU_WITH_DUCET
+
+/** Get DUCET value of codepoint
+ *
+ * Normally, for unlisted codepoints, this function will return number greater
+ * than max weight of listed codepoints, hence putting all unlisted codepoints
+ * (not letters and not numbers) to the end of the sorted list (in codepoint
+ * order).
+ *
+ * @ingroup udb
+ * @param codepoint codepoint
+ * @param weight previous weight for compound weight (not used here)
+ * @param context pointer passed to nu_strcoll()
+ * @return comparable weight of the codepoint
+ */
+NU_EXPORT
+int32_t nu_ducet_weight(uint32_t codepoint, int32_t *weight, void *context);
+
+#endif /* NU_WITH_DUCET */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_DUCET_H */
diff --git a/vendor/nunicode/include/libnu/mph.h b/vendor/nunicode/include/libnu/mph.h
new file mode 100644
index 0000000000..53f2043ad1
--- /dev/null
+++ b/vendor/nunicode/include/libnu/mph.h
@@ -0,0 +1,71 @@
+#ifndef NU_MPH_H
+#define NU_MPH_H
+
+/* Intentionally undocumented
+ *
+ * http://iswsa.acm.org/mphf/index.html
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <libnu/config.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+#ifdef NU_WITH_UDB
+
+/* those need to be the same values as used in MPH generation */
+#define PRIME 0x01000193
+
+/** Calculate G offset from codepoint
+ */
+static inline
+uint32_t _nu_hash(uint32_t hash, uint32_t codepoint) {
+ if (hash == 0) {
+ hash = PRIME;
+ }
+
+ return hash ^ codepoint;
+}
+
+/** Get hash value of Unicode codepoint
+ */
+static inline
+uint32_t nu_mph_hash(const int16_t *G, size_t G_SIZE,
+ uint32_t codepoint) {
+
+ uint32_t h = _nu_hash(0, codepoint);
+ int16_t offset = G[h % G_SIZE];
+ if (offset < 0) {
+ return (uint32_t)(-offset - 1);
+ }
+ return (_nu_hash(offset, codepoint) % G_SIZE);
+}
+
+/** Lookup value in MPH
+ */
+static inline
+uint32_t nu_mph_lookup(const uint32_t *V_C, const uint16_t *V_I,
+ uint32_t codepoint, uint32_t hash) {
+
+ const uint32_t *c = (V_C + hash);
+ const uint16_t *i = (V_I + hash);
+
+ /* due to nature of minimal perfect hash, it will always
+ * produce collision for codepoints outside of MPH original set.
+ * thus VALUES_C contain original codepoint to check if
+ * collision occurred */
+
+ return (*c != codepoint ? 0 : *i);
+}
+
+#endif /* NU_WITH_UDB */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_MPH_H */
diff --git a/vendor/nunicode/include/libnu/strcoll.h b/vendor/nunicode/include/libnu/strcoll.h
new file mode 100644
index 0000000000..3300e0a013
--- /dev/null
+++ b/vendor/nunicode/include/libnu/strcoll.h
@@ -0,0 +1,199 @@
+#ifndef NU_STRCOLL_H
+#define NU_STRCOLL_H
+
+/** @defgroup collation Collation functions
+ *
+ * All functions in this group are following full Unicode collation rules,
+ * i.e. nu_strstr(haystack, "Æ") will find "AE" in haystack and
+ * nu_strstr(haystack, "ß") will find "ss".
+ *
+ * Same applies for *every* function, nu_strchr(str, 0x00DF), as you would
+ * guess, will also find "ss" in str.
+ *
+ * Please expect this.
+ *
+ * Note on "n" functions variant: please see comment on this topic
+ * in strings.h
+ */
+
+#include <sys/types.h>
+
+#include <libnu/config.h>
+#include <libnu/casemap.h>
+#include <libnu/defines.h>
+#include <libnu/strings.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+#ifdef NU_WITH_TOFOLD
+# define NU_FOLDING_FUNCTION nu_tofold
+#else
+# define NU_FOLDING_FUNCTION nu_toupper
+#endif /* NU_WITH_TOFOLD */
+
+#ifdef NU_WITH_Z_COLLATION
+
+/** Locate codepoint in string
+ *
+ * @ingroup collation
+ * @param encoded encoded string
+ * @param c charater to locate
+ * @param read read (decode) function for encoded string
+ * @return pointer to codepoint in string or 0
+ */
+NU_EXPORT
+const char* nu_strchr(const char *encoded, uint32_t c, nu_read_iterator_t read);
+
+/** Locate codepoint in string ignoring case
+ *
+ * @ingroup collation
+ * @see nu_strchr
+ */
+NU_EXPORT
+const char* nu_strcasechr(const char *encoded, uint32_t c, nu_read_iterator_t read);
+
+/** Locate codepoint in string in reverse direction
+ *
+ * @ingroup collation
+ * @param encoded encoded string
+ * @param c charater to locate
+ * @param read read (decode) function for encoded string
+ * @return pointer to codepoint in string or 0
+ */
+NU_EXPORT
+const char* nu_strrchr(const char *encoded, uint32_t c, nu_read_iterator_t read);
+
+/** Locate codepoint in string in reverse direction, case-insensitive
+ *
+ * @ingroup collation
+ * @see nu_strrchr
+ */
+NU_EXPORT
+const char* nu_strrcasechr(const char *encoded, uint32_t c, nu_read_iterator_t read);
+
+/** Compare strings in case-sensitive manner.
+ *
+ * @ingroup collation
+ * @param s1 first encoded strings
+ * @param s2 second encoded strings
+ * @param s1_read read (decode) function for first string
+ * @param s2_read read (decode) function for second string
+ * @return -1, 0, 1
+ */
+NU_EXPORT
+int nu_strcoll(const char *s1, const char *s2,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read);
+
+/** Compare strings in case-insensitive manner.
+ *
+ * @ingroup collation
+ * @see nu_strcoll
+ */
+NU_EXPORT
+int nu_strcasecoll(const char *s1, const char *s2,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read);
+
+/** Find needle in haystack
+ *
+ * @ingroup collation
+ * @param haystack encoded haystack
+ * @param needle encoded needle
+ * @param haystack_read haystack read (decode) function
+ * @param needle_read needle read (decode) function
+ * @return pointer to found string or 0, will return
+ * haystack if needle is empty string
+ */
+NU_EXPORT
+const char* nu_strstr(const char *haystack, const char *needle,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read);
+
+/** Find needle in haystack (case-insensitive)
+ *
+ * @ingroup collation
+ * @see nu_strstr
+ */
+NU_EXPORT
+const char* nu_strcasestr(const char *haystack, const char *needle,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read);
+
+#endif /* NU_WITH_Z_COLLATION */
+
+#ifdef NU_WITH_N_COLLATION
+
+/**
+ * @ingroup collation
+ * @see nu_strchr
+ */
+NU_EXPORT
+const char* nu_strnchr(const char *encoded, size_t max_len, uint32_t c,
+ nu_read_iterator_t read);
+
+/**
+ * @ingroup collation
+ * @see nu_strcasechr
+ */
+NU_EXPORT
+const char* nu_strcasenchr(const char *encoded, size_t max_len, uint32_t c,
+ nu_read_iterator_t read);
+
+/**
+ * @ingroup collation
+ * @see nu_strrchr
+ */
+NU_EXPORT
+const char* nu_strrnchr(const char *encoded, size_t max_len, uint32_t c,
+ nu_read_iterator_t read);
+
+/**
+ * @ingroup collation
+ * @see nu_strrcasechr
+ */
+NU_EXPORT
+const char* nu_strrcasenchr(const char *encoded, size_t max_len, uint32_t c,
+ nu_read_iterator_t read);
+
+/**
+ * @ingroup collation
+ * @see nu_strcoll
+ */
+NU_EXPORT
+int nu_strncoll(const char *s1, size_t s1_max_len,
+ const char *s2, size_t s2_max_len,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read);
+
+/**
+ * @ingroup collation
+ * @see nu_strncoll
+ */
+NU_EXPORT
+int nu_strcasencoll(const char *s1, size_t s1_max_len,
+ const char *s2, size_t s2_max_len,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read);
+
+/**
+ * @ingroup collation
+ * @see nu_strstr
+ */
+NU_EXPORT
+const char* nu_strnstr(const char *haystack, size_t haystack_max_len,
+ const char *needle, size_t needle_max_len,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read);
+
+/**
+ * @ingroup collation
+ * @see nu_strcasestr
+ */
+NU_EXPORT
+const char* nu_strcasenstr(const char *haystack, size_t haystack_max_len,
+ const char *needle, size_t needle_max_len,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read);
+
+#endif /* NU_WITH_N_COLLATION */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_STRCOLL_H */
diff --git a/vendor/nunicode/include/libnu/strcoll_internal.h b/vendor/nunicode/include/libnu/strcoll_internal.h
new file mode 100644
index 0000000000..570cb14f87
--- /dev/null
+++ b/vendor/nunicode/include/libnu/strcoll_internal.h
@@ -0,0 +1,232 @@
+#ifndef NU_STRCOLL_INTERNAL_H
+#define NU_STRCOLL_INTERNAL_H
+
+/** @defgroup collation_internal Internal collation functions
+ *
+ * Functions in this group are mostly for the internal use. PLease use them
+ * with care.
+ */
+
+#include <libnu/config.h>
+#include <libnu/casemap.h>
+#include <libnu/defines.h>
+#include <libnu/strings.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+/** Read (decode) iterator with transformation applied inside of it
+ *
+ * @ingroup collation_internal
+ * @see nu_default_compound_read
+ * @see nu_nocase_compound_read
+ */
+typedef const char* (*nu_compound_read_t)(
+ const char *encoded, const char *encoded_limit, nu_read_iterator_t encoded_read,
+ uint32_t *unicode, const char **tail);
+
+/** Weight unicode codepoint (or several codepoints)
+ *
+ * 0 should always be weighted to 0. If your weight function need more
+ * than one codepoint - return negative value, which will be passed back to
+ * this function along with next codepoint.
+ *
+ * When function decided on weight and returned positive result, it has to
+ * fill weight with how many (Unicode) codepoints nunicode should rollback.
+ * E.g. function consumed "ZZS" and decided weight (in Hungarian collation),
+ * it fills 0 to \*weight because no rollback is needed. Then function
+ * consumed "ZZZ" and no weight available for such contraction - it
+ * returns weight for "Z" and fills \*weight with 2, to rollback
+ * redundant "ZZ".
+ *
+ * If string suddenly ends before weight function can decide (string limit
+ * reached), 0 will be passed additionally to the previous string to signal
+ * end of the string.
+ *
+ * @ingroup collation_internal
+ * @param u unicode codepoint to weight
+ * @param weight 0 at first call or (on sequential calls) pointer to negative
+ * weight previously returned by this function
+ * @param context pointer passed to _nu_strcoll() or _nu_strstr()
+ * @return positive codepoint weight or negative value if function need more
+ * codepoints
+ */
+typedef int32_t (*nu_codepoint_weight_t)(uint32_t u, int32_t *weight, void *context);
+
+#if (defined NU_WITH_Z_COLLATION) || (defined NU_WITH_N_COLLATION)
+
+/** Default compound read, equal to simply calling encoded_read(encoded, &unicode)
+ *
+ * @ingroup collation_internal
+ * @param encoded encoded string
+ * @param encoded_limit upper limit for encoded. NU_UNLIMITED for 0-terminated
+ * strings
+ * @param encoded_read read (decode) function
+ * @param unicode output unicode codepoint
+ * @param tail output pointer to compound tail, should never be 0
+ * @return pointer to next encoded codepoint
+ */
+static inline
+const char* nu_default_compound_read(const char *encoded, const char *encoded_limit,
+ nu_read_iterator_t encoded_read, uint32_t *unicode,
+ const char **tail) {
+ (void)(encoded_limit);
+ (void)(tail);
+
+ return encoded_read(encoded, unicode);
+}
+
+/** Case-ignoring compound read, equal to calling
+ * encoded_read(encoded, &unicode) with nu_toupper() applied internally
+ *
+ * @ingroup collation_internal
+ * @param encoded encoded string
+ * @param encoded_limit upper limit for encoded. NU_UNLIMITED for 0-terminated
+ * strings
+ * @param encoded_read read (decode) function
+ * @param unicode output unicode codepoint
+ * @param tail output pointer to compound tail, should never be 0
+ * @return pointer to next encoded codepoint
+ */
+static inline
+const char* nu_nocase_compound_read(const char *encoded, const char *encoded_limit,
+ nu_read_iterator_t encoded_read, uint32_t *unicode,
+ const char **tail) {
+
+ /* re-entry with tail != 0 */
+ if (*tail != 0) {
+ *tail = nu_casemap_read(*tail, unicode);
+
+ if (*unicode != 0) {
+ return encoded;
+ }
+
+ *tail = 0; // fall thru
+ }
+
+ if (encoded >= encoded_limit) {
+ *unicode = 0;
+ return encoded;
+ }
+
+ const char *p = encoded_read(encoded, unicode);
+
+ if (*unicode == 0) {
+ return p;
+ }
+
+ const char *map = NU_FOLDING_FUNCTION(*unicode);
+ if (map != 0) {
+ *tail = nu_casemap_read(map, unicode);
+ }
+
+ return p;
+}
+
+/** Internal interface for nu_strcoll
+ *
+ * @ingroup collation_internal
+ * @param lhs left-hand side encoded string
+ * @param lhs_limit upper limit for lhs, use NU_UNLIMITED for 0-terminated
+ * strings
+ * @param rhs right-hand side encoded string
+ * @param rhs_limit upper limit for rhs, use NU_UNLIMITED for 0-terminated
+ * strings
+ * @param it1 lhs read (decoding) function
+ * @param it2 rhs read (decoding) function
+ * @param com1 lhs compound read function
+ * @param com2 rhs compound read function
+ * @param weight codepoint weighting function
+ * @param context pointer which will be passed to weight
+ * @param collated_left (optional) number of codepoints collated in lhs
+ * @param collated_right (optional) number of codepoints collated in rhs
+ *
+ * @see nu_strcoll
+ * @see nu_default_compound_read
+ * @see nu_nocase_compound_read
+ * @see nu_ducet_weight
+ */
+NU_EXPORT
+int _nu_strcoll(const char *lhs, const char *lhs_limit,
+ const char *rhs, const char *rhs_limit,
+ nu_read_iterator_t it1, nu_read_iterator_t it2,
+ nu_compound_read_t com1, nu_compound_read_t com2,
+ nu_codepoint_weight_t weight, void *context,
+ ssize_t *collated_left, ssize_t *collated_right);
+
+/** Internal interface for nu_strchr
+ *
+ * @ingroup collation_internal
+ * @param lhs left-hand side encoded string
+ * @param lhs_limit upper limit for lhs, use NU_UNLIMITED for 0-terminated
+ * strings
+ * @param c unicode codepoint to look for
+ * @param read lhs read (decoding) function
+ * @param com lhs compound read function
+ * @param casemap casemapping function
+ * @param casemap_read casemapping result decoding function
+ *
+ * @see nu_strchr
+ * @see nu_default_compound_read
+ * @see nu_nocase_compound_read
+ * @see nu_toupper
+ * @see nu_tolower
+ */
+NU_EXPORT
+const char* _nu_strchr(const char *lhs, const char *lhs_limit,
+ uint32_t c, nu_read_iterator_t read,
+ nu_compound_read_t com,
+ nu_casemapping_t casemap, nu_read_iterator_t casemap_read);
+
+/** Internal interface for nu_strchr
+ *
+ * @ingroup collation_internal
+ * @see _nu_strchr
+ */
+NU_EXPORT
+const char* _nu_strrchr(const char *encoded, const char *limit,
+ uint32_t c, nu_read_iterator_t read,
+ nu_compound_read_t com,
+ nu_casemapping_t casemap, nu_read_iterator_t casemap_read);
+
+/** Internal interface for nu_strcoll
+ *
+ * @ingroup collation_internal
+ * @param haystack encoded haystack
+ * @param haystack_limit upper limit for haystack, use NU_UNLIMITED for
+ * 0-terminated strings
+ * @param needle encoded needle string
+ * @param needle_limit upper limit for needle, use NU_UNLIMITED for
+ * 0-terminated strings
+ * @param it1 haystack read (decoding) function
+ * @param it2 needle read (decoding) function
+ * @param com1 haystack compound read function
+ * @param com2 needle compound read function
+ * @param casemap casemapping function
+ * @param casemap_read casemapping result decoding function
+ * @param weight codepoint weighting function
+ * @param context pointer which will be passed to weight
+ *
+ * @see nu_strstr
+ * @see nu_default_compound_read
+ * @see nu_nocase_compound_read
+ * @see nu_toupper
+ * @see nu_tolower
+ * @see nu_ducet_weight
+ */
+NU_EXPORT
+const char* _nu_strstr(const char *haystack, const char *haystack_limit,
+ const char *needle, const char *needle_limit,
+ nu_read_iterator_t it1, nu_read_iterator_t it2,
+ nu_compound_read_t com1, nu_compound_read_t com2,
+ nu_casemapping_t casemap, nu_read_iterator_t casemap_read,
+ nu_codepoint_weight_t weight, void *context);
+
+#endif /* (defined NU_WITH_Z_COLLATION) || (defined NU_WITH_N_COLLATION) */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_STRCOLL_INTERNAL_H */
diff --git a/vendor/nunicode/include/libnu/strings.h b/vendor/nunicode/include/libnu/strings.h
new file mode 100644
index 0000000000..989ef5ba3f
--- /dev/null
+++ b/vendor/nunicode/include/libnu/strings.h
@@ -0,0 +1,142 @@
+#ifndef NU_STRINGS_H
+#define NU_STRINGS_H
+
+/** @defgroup strings String functions
+ *
+ * Note on "n" functions variant: "n" is in bytes in all functions,
+ * note though that those are not for memory overrun control.
+ * They are just for strings not having terminating 0 byte and those
+ * functions won't go further than m-th *codepoint* in string, but might go
+ * further than n-th byte in case of multibyte sequence.
+ *
+ * E.g.: ``nu_strnlen("абв", 3, nu_utf8_read);``.
+ * Since codepoints are 2-byte sequences, nu_strnlen() won't go further than 2nd
+ * codepoint, but will go further than 3rd byte while reading "б".
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <libnu/config.h>
+#include <libnu/defines.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+/**
+ * @defgroup iterators Iterators
+ * @defgroup transformations Codepoint transformations
+ * @defgroup transformations_internal Codepoint transformations (internal)
+ */
+
+/** Read (decode) iterator
+ *
+ * @ingroup iterators
+ * @see nu_utf8_read
+ */
+typedef const char* (*nu_read_iterator_t)(const char *encoded, uint32_t *unicode);
+
+/** Read (decode) backwards iterator
+ *
+ * Arguments intentionally reversed to not mix this with nu_read_iterator_t.
+ * Reverse read is not compatible with any of string functions.
+ *
+ * @ingroup iterators
+ * @see nu_utf8_revread
+ */
+typedef const char* (*nu_revread_iterator_t)(uint32_t *unicode, const char *encoded);
+
+/** Write (encode) iterator
+ *
+ * @ingroup iterators
+ * @see nu_utf8_write
+ */
+typedef char* (*nu_write_iterator_t)(uint32_t unicode, char *encoded);
+
+/** Transform codepoint
+ *
+ * @ingroup transformations
+ * @see nu_toupper
+ * @see nu_tolower
+ */
+typedef const char* (*nu_transformation_t)(uint32_t codepoint);
+
+/** Transform codepoint (used internally). This kind of transformation
+ * delegates iteration on string to transformation implementation.
+ *
+ * @ingroup transformations_internal
+ * @see _nu_toupper
+ * @see _nu_tolower
+ */
+typedef const char* (*nu_transform_read_t)(
+ const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transformed,
+ void *context);
+
+#if (defined NU_WITH_Z_STRINGS) || (defined NU_WITH_N_STRINGS)
+
+#endif /* NU_WITH_Z_STRINGS NU_WITH_N_STRINGS */
+
+#ifdef NU_WITH_Z_STRINGS
+
+/** Get decoded string codepoints length
+ *
+ * @ingroup strings
+ * @param encoded encoded string
+ * @param it decoding function
+ * @return string length or negative error
+ *
+ * @see nu_strnlen
+ */
+NU_EXPORT
+ssize_t nu_strlen(const char *encoded, nu_read_iterator_t it);
+
+/** Get encoded string bytes length (encoding variant)
+ *
+ * @ingroup strings
+ * @param unicode unicode codepoints
+ * @param it encoding function
+ * @return byte length or negative error
+ *
+ * @see nu_bytenlen
+ */
+NU_EXPORT
+ssize_t nu_bytelen(const uint32_t *unicode, nu_write_iterator_t it);
+
+/** Get encoded string bytes length
+ *
+ * @ingroup strings
+ * @param encoded encoded string
+ * @param it decoding function
+ * @return string length or negative error
+ */
+NU_EXPORT
+ssize_t nu_strbytelen(const char *encoded, nu_read_iterator_t it);
+
+#endif /* NU_WITH_Z_STRINGS */
+
+#ifdef NU_WITH_N_STRINGS
+
+/**
+ * @ingroup strings
+ * @see nu_strlen
+ */
+NU_EXPORT
+ssize_t nu_strnlen(const char *encoded, size_t max_len, nu_read_iterator_t it);
+
+/**
+ * @ingroup strings
+ * @see nu_bytelen
+ */
+NU_EXPORT
+ssize_t nu_bytenlen(const uint32_t *unicode, size_t max_len,
+ nu_write_iterator_t it);
+
+#endif /* NU_WITH_N_STRINGS */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_STRINGS_H */
diff --git a/vendor/nunicode/include/libnu/udb.h b/vendor/nunicode/include/libnu/udb.h
new file mode 100644
index 0000000000..39a785bc69
--- /dev/null
+++ b/vendor/nunicode/include/libnu/udb.h
@@ -0,0 +1,81 @@
+#ifndef NU_UDB_H
+#define NU_UDB_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <libnu/config.h>
+#include <libnu/defines.h>
+#include <libnu/mph.h>
+#include <libnu/strings.h>
+#include <libnu/utf8.h>
+
+/** @defgroup udb Unicode database
+ *
+ * Note: never use it directly, it is subject to change in next releases
+ */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+#ifdef NU_WITH_UDB
+
+#define NU_UDB_DECODING_FUNCTION (nu_utf8_read)
+#define nu_udb_read (nu_utf8_read)
+
+/** Lookup value in UDB
+ *
+ * Similar to nu_udb_lookup(), but doesn't look into COMBINED
+ *
+ * @ingroup udb
+ * @see nu_udb_lookup
+ * @return raw value from VALUES_I or 0 if value wasn't found
+ */
+static inline
+uint32_t nu_udb_lookup_value(uint32_t codepoint,
+ const int16_t *G, size_t G_SIZE,
+ const uint32_t *VALUES_C, const uint16_t *VALUES_I) {
+
+ uint32_t hash = nu_mph_hash(G, G_SIZE, codepoint);
+ uint32_t value = nu_mph_lookup(VALUES_C, VALUES_I, codepoint, hash);
+
+ return value;
+}
+
+/** Lookup data in UDB
+ *
+ * Returned data is encoded, therefore you need to use p = it(p, &u) to
+ * fetch it. Returned string might contain more than 1 codepoint.
+ *
+ * @ingroup udb
+ * @param codepoint unicode codepoint
+ * @param G first MPH table
+ * @param G_SIZE first table number of elements (original MPH set size)
+ * @param VALUES_C codepoints array
+ * @param VALUES_I offsets array
+ * @param COMBINED joined values addressed by index stored in VALUES
+ * @return looked up data or 0
+ */
+static inline
+const char* nu_udb_lookup(uint32_t codepoint,
+ const int16_t *G, size_t G_SIZE,
+ const uint32_t *VALUES_C, const uint16_t *VALUES_I, const uint8_t *COMBINED) {
+
+ uint32_t combined_offset = nu_udb_lookup_value(codepoint,
+ G, G_SIZE, VALUES_C, VALUES_I);
+
+ if (combined_offset == 0) {
+ return 0;
+ }
+
+ return (const char *)(COMBINED + combined_offset);
+}
+
+#endif /* NU_WITH_UDB */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_UDB_H */
diff --git a/vendor/nunicode/include/libnu/unaccent.h b/vendor/nunicode/include/libnu/unaccent.h
new file mode 100644
index 0000000000..1486a43f34
--- /dev/null
+++ b/vendor/nunicode/include/libnu/unaccent.h
@@ -0,0 +1,57 @@
+#ifndef NU_UNACCENT_H
+#define NU_UNACCENT_H
+
+#include <libnu/casemap.h>
+#include <libnu/strings.h>
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+/**
+ * @example unaccent.c
+ */
+
+#ifdef NU_WITH_UNACCENT
+
+/** Return unaccented value of codepoint. If codepoint is
+ * accent (disacritic) itself, returns empty string.
+ *
+ * @note This is nunicode extenstion.
+ *
+ * @ingroup transformations
+ * @param codepoint unicode codepoint
+ * @return unaccented codepoint, 0 if mapping doesn't exist
+ * and empty string if codepoint is accent
+ */
+NU_EXPORT
+const char* nu_tounaccent(uint32_t codepoint);
+
+/** Return unaccented value of codepoint. If codepoint is
+ * accent (disacritic) itself, returns empty string.
+ *
+ * @note This is nunicode extenstion.
+ *
+ * @ingroup transformations_internal
+ * @param encoded pointer to encoded string
+ * @param limit memory limit of encoded string or NU_UNLIMITED
+ * @param read read (decoding) function
+ * @param u (optional) codepoint which was (or wasn't) transformed
+ * @param transform output value of codepoint unaccented or 0 if
+ * mapping doesn't exist, or empty string if codepoint is accent.
+ * Can't be NULL, supposed to be decoded with nu_casemap_read
+ * @param context not used
+ * @return pointer to the next codepoint in string
+ */
+NU_EXPORT
+const char* _nu_tounaccent(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context);
+
+#endif /* NU_WITH_UNACCENT */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_UNACCENT_H */
diff --git a/vendor/nunicode/include/libnu/utf8.h b/vendor/nunicode/include/libnu/utf8.h
new file mode 100644
index 0000000000..6f654e24c4
--- /dev/null
+++ b/vendor/nunicode/include/libnu/utf8.h
@@ -0,0 +1,130 @@
+#ifndef NU_UTF8_H
+#define NU_UTF8_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <libnu/config.h>
+#include <libnu/defines.h>
+#include <libnu/utf8_internal.h>
+
+/** @defgroup utf8 UTF-8 support
+ *
+ * Note: There is no utf8_string[i] equivalent - it will be slow,
+ * use nu_utf8_read() and nu_utf8_revread() instead
+ *
+ * @example utf8.c
+ * @example revread.c
+ */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+extern "C" {
+#endif
+
+#ifdef NU_WITH_UTF8_READER
+
+/** Read codepoint from UTF-8 string
+ *
+ * @ingroup utf8
+ * @param utf8 pointer to UTF-8 encoded string
+ * @param unicode output unicode codepoint or 0
+ * @return pointer to next codepoint in UTF-8 string
+ */
+static inline
+const char* nu_utf8_read(const char *utf8, uint32_t *unicode) {
+ uint32_t c = *(unsigned char *)(utf8);
+
+ if (c >= 0x80) {
+ if (c < 0xE0) {
+ if (unicode != 0) {
+ utf8_2b(utf8, unicode);
+ }
+ return utf8 + 2;
+ }
+ else if (c < 0xF0) {
+ if (unicode != 0) {
+ utf8_3b(utf8, unicode);
+ }
+ return utf8 + 3;
+ }
+ else {
+ if (unicode != 0) {
+ utf8_4b(utf8, unicode);
+ }
+ return utf8 + 4;
+ }
+ }
+ else if (unicode != 0) {
+ *unicode = c;
+ }
+
+ return utf8 + 1;
+}
+
+#ifdef NU_WITH_REVERSE_READ
+
+/** Read codepoint from UTF-8 string in backward direction
+ *
+ * Note that it is your responsibility to check that this call
+ * is not going under beginning of encoded string. Normally you
+ * shouldn't call it like this: nu_utf8_revread(&u, "hello"); which
+ * will result in undefined behavior
+ *
+ * @ingroup utf8
+ * @param unicode output unicode codepoint or 0
+ * @param utf8 pointer to UTF-8 encoded string
+ * @return pointer to previous codepoint in UTF-8 string
+ */
+static inline
+const char* nu_utf8_revread(uint32_t *unicode, const char *utf8) {
+ /* valid UTF-8 has either 10xxxxxx (continuation byte)
+ * or beginning of byte sequence */
+ const char *p = utf8 - 1;
+ while (((unsigned char)(*p) & 0xC0) == 0x80) { /* skip every 0b10000000 */
+ --p;
+ }
+
+ if (unicode != 0) {
+ nu_utf8_read(p, unicode);
+ }
+
+ return p;
+}
+
+#endif /* NU_WITH_REVERSE_READ */
+
+#ifdef NU_WITH_VALIDATION
+
+/** Validate codepoint in string
+ *
+ * @ingroup utf8
+ * @param encoded buffer with encoded string
+ * @param max_len buffer length
+ * @return codepoint length or 0 on error
+ */
+NU_EXPORT
+int nu_utf8_validread(const char *encoded, size_t max_len);
+
+#endif /* NU_WITH_VALIDATION */
+#endif /* NU_WITH_UTF8_READER */
+
+#ifdef NU_WITH_UTF8_WRITER
+
+/** Write unicode codepoints into UTF-8 encoded string
+ *
+ * @ingroup utf8
+ * @param unicode unicode codepoint
+ * @param utf8 pointer to buffer to write UTF-8 encoded text to,
+ * should be large enough to hold encoded value
+ * @return pointer to byte after last written
+ */
+NU_EXPORT
+char* nu_utf8_write(uint32_t unicode, char *utf8);
+
+#endif /* NU_WITH_UTF8_WRITER */
+
+#if defined (__cplusplus) || defined (c_plusplus)
+}
+#endif
+
+#endif /* NU_UTF8_H */
diff --git a/vendor/nunicode/include/libnu/utf8_internal.h b/vendor/nunicode/include/libnu/utf8_internal.h
new file mode 100644
index 0000000000..77b7eb5ced
--- /dev/null
+++ b/vendor/nunicode/include/libnu/utf8_internal.h
@@ -0,0 +1,168 @@
+#ifndef NU_UTF8_INTERNAL_H
+#define NU_UTF8_INTERNAL_H
+
+#include <sys/types.h>
+
+static inline
+unsigned utf8_char_length(const char c) {
+ const unsigned char uc = c;
+
+ if ((uc & 0x80) == 0) return 1;
+ if ((uc & 0xE0) == 0xC0) return 2;
+ if ((uc & 0xF0) == 0xE0) return 3;
+ if ((uc & 0xF8) == 0xF0) return 4;
+
+ return 0; /* undefined */
+}
+
+static inline
+void utf8_2b(const char *p, uint32_t *codepoint) {
+ const unsigned char *up = (const unsigned char *)(p);
+
+ /* UTF-8: 110xxxxx 10xxxxxx
+ * |__ 1st unicode octet
+ * 110xxx00 << 6 -> 00000xxx 00000000 |
+ * --------
+ * 110000xx << 6 -> 00000xxx xx000000 |__ 2nd unicode octet
+ * 10xxxxxx -> 00000xxx xxxxxxxx |
+ * -------- */
+ *codepoint = (*(up) & 0x1C) << 6
+ | ((*(up) & 0x03) << 6 | (*(up + 1) & 0x3F));
+}
+
+static inline
+void utf8_3b(const char *p, uint32_t *codepoint) {
+ const unsigned char *up = (const unsigned char *)(p);
+
+ /* UTF-8: 1110xxxx 10xxxxxx 10xxxxxx
+ *
+ * 1110xxxx << 12 -> xxxx0000 0000000 |__ 1st unicode octet
+ * 10xxxx00 << 6 -> xxxxxxxx 0000000 |
+ * --------
+ * 100000xx << 6 -> xxxxxxxx xx00000 |__ 2nd unicode octet
+ * 10xxxxxx -> xxxxxxxx xxxxxxx |
+ * ------- */
+ *codepoint =
+ ((*(up) & 0x0F) << 12 | (*(up + 1) & 0x3C) << 6)
+ | ((*(up + 1) & 0x03) << 6 | (*(up + 2) & 0x3F));
+}
+
+static inline
+void utf8_4b(const char *p, uint32_t *codepoint) {
+ const unsigned char *up = (const unsigned char *)(p);
+
+ /* UTF-8: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ *
+ * 11110xxx << 18 -> 00xxx00 00000000 00000000 |__ 1st unicode octet
+ * 10xx0000 << 12 -> 00xxxxx 00000000 00000000 |
+ * -------
+ * 1000xxxx << 12 -> 00xxxxx xxxx0000 00000000 |__ 2nd unicode octet
+ * 10xxxx00 << 6 -> 00xxxxx xxxxxxxx 00000000 |
+ * --------
+ * 100000xx << 6 -> 00xxxxx xxxxxxxx xx000000 |__ 3rd unicode octet
+ * 10xxxxxx -> 00xxxxx xxxxxxxx xxxxxxxx |
+ * --------- */
+ *codepoint =
+ ((*(up) & 0x07) << 18 | (*(up + 1) & 0x30) << 12)
+ | ((*(up + 1) & 0x0F) << 12 | (*(up + 2) & 0x3C) << 6)
+ | ((*(up + 2) & 0x03) << 6 | (*(up + 3) & 0x3F));
+}
+
+static inline
+unsigned utf8_codepoint_length(uint32_t codepoint) {
+ if (codepoint < 128) return 1;
+ if (codepoint < 0x0800) return 2;
+ if (codepoint < 0x10000) return 3;
+
+ return 4; /* de facto max length in UTF-8 */
+}
+
+static inline
+void b2_utf8(uint32_t codepoint, char *p) {
+ unsigned char *up = (unsigned char *)(p);
+
+ /* UNICODE: 00000xxx xxxxxxxx
+ *
+ * 00000xxx >> 6 -> 110xxx00 10000000 |__ 1st UTF-8 octet
+ * xxxxxxxx >> 6 -> 110xxxxx 10000000 |
+ * --------
+ * |__ 2nd UTF-8 octet
+ * xxxxxxxx -> 110xxxxx 10xxxxxx |
+ * -------- */
+ *(up) = (0xC0 | (codepoint & 0xFF00) >> 6 | (codepoint & 0xFF) >> 6);
+ *(up + 1) = (0x80 | (codepoint & 0x3F));
+}
+
+static inline
+void b3_utf8(uint32_t codepoint, char *p) {
+ unsigned char *up = (unsigned char *)(p);
+
+ /* UNICODE: xxxxxxxx xxxxxxxx
+ * |__ 1st UTF-8 octet
+ * xxxxxxxx >> 12 -> 1110xxxx 10000000 10000000 |
+ * --------
+ * xxxxxxxx >> 6 -> 1110xxxx 10xxxx00 10000000 |__ 2nd UTF-8 octet
+ * xxxxxxxx >> 6 -> 1110xxxx 10xxxxxx 10000000 |
+ * --------
+ * |__ 3rd UTF-8 octet
+ * xxxxxxxx -> 1110xxxx 10xxxxxx 10xxxxxx |
+ * -------- */
+ *(up) = (0xE0 | (codepoint & 0xF000) >> 12);
+ *(up + 1) = (0x80 | (codepoint & 0x0F00) >> 6 | (codepoint & 0xC0) >> 6);
+ *(up + 2) = (0x80 | (codepoint & 0x3F));
+}
+
+static inline
+void b4_utf8(uint32_t codepoint, char *p) {
+ unsigned char *up = (unsigned char *)(p);
+
+ /* UNICODE: 000xxxxx xxxxxxxx xxxxxxxx
+ * |__ 1st UTF-8 octet
+ * 000xxxxx >> 18 -> 11110xxx 1000000 10000000 10000000 |
+ * --------
+ * 000xxxxx >> 12 -> 11110xxx 10xx000 10000000 10000000 |__ 2nd UTF-8 octet
+ * xxxxxxxx >> 12 -> 11110xxx 10xxxxx 10000000 10000000 |
+ * -------
+ * xxxxxxxx >> 6 -> 11110xxx 10xxxxx 10xxxxx0 10000000 |__ 3rd UTF-8 octet
+ * xxxxxxxx >> 6 -> 11110xxx 10xxxxx 10xxxxxx 10000000 |
+ * --------
+ * |__ 4th UTF-8 octet
+ * xxxxxxxx -> 11110xxx 10xxxxx 10xxxxxx 10000000 | */
+ *(up) = (0xF0 | ((codepoint & 0x1C0000) >> 18));
+ *(up + 1) = (0x80 | (codepoint & 0x030000) >> 12 | (codepoint & 0x00E000) >> 12);
+ *(up + 2) = (0x80 | (codepoint & 0x001F00) >> 6 | (codepoint & 0x0000E0) >> 6);
+ *(up + 3) = (0x80 | (codepoint & 0x3F));
+}
+
+static inline
+int utf8_validread_basic(const char *p, size_t max_len) {
+ const unsigned char *up = (const unsigned char *)(p);
+
+ /* it should be 0xxxxxxx or 110xxxxx or 1110xxxx or 11110xxx
+ * latter should be followed by number of 10xxxxxx */
+
+ unsigned len = utf8_char_length(*p);
+
+ /* codepoints longer than 6 bytes does not currently exist
+ * and not currently supported
+ * TODO: longer UTF-8 sequences support
+ */
+ if (max_len < len) {
+ return 0;
+ }
+
+ switch (len) {
+ case 1: return 1; /* one byte codepoint */
+ case 2: return ((*(up + 1) & 0xC0) == 0x80 ? 2 : 0);
+ case 3: return ((*(up + 1) & 0xC0) == 0x80
+ && (*(up + 2) & 0xC0) == 0x80 ? 3 : 0);
+
+ case 4: return ((*(up + 1) & 0xC0) == 0x80
+ && (*(up + 2) & 0xC0) == 0x80
+ && (*(up + 3) & 0xC0) == 0x80 ? 4 : 0);
+ }
+
+ return 0;
+}
+
+#endif /* NU_UTF8_INTERNAL_H */
diff --git a/vendor/nunicode/src/libnu/ducet.c b/vendor/nunicode/src/libnu/ducet.c
new file mode 100644
index 0000000000..b634538481
--- /dev/null
+++ b/vendor/nunicode/src/libnu/ducet.c
@@ -0,0 +1,65 @@
+#include <assert.h>
+
+#include <libnu/ducet.h>
+#include <libnu/udb.h>
+
+#ifdef NU_WITH_DUCET
+
+#include "gen/_ducet.c"
+
+#ifndef NU_DISABLE_CONTRACTIONS
+# include "gen/_ducet_switch.c"
+#else
+ const size_t _NU_DUCET_CONTRACTIONS = 0;
+#endif
+
+static size_t _nu_ducet_weights_count() {
+ return NU_DUCET_G_SIZE + _NU_DUCET_CONTRACTIONS;
+}
+
+int32_t nu_ducet_weight(uint32_t codepoint, int32_t *weight, void *context) {
+ (void)(weight);
+ (void)(context);
+
+ assert(_nu_ducet_weights_count() < 0x7FFFFFFF - 0x10FFFF);
+
+#ifndef NU_DISABLE_CONTRACTIONS
+ int32_t switch_value = _nu_ducet_weight_switch(codepoint, weight, context);
+ /* weight switch should return weight (if any) and fill value of *weight
+ * with fallback (if needed). returned value of 0 is impossible result - this
+ * special case is already handled above, this return value indicates that switch
+ * couldn't find weight for a codepoint */
+ if (switch_value != 0) {
+ return switch_value;
+ }
+#endif
+
+ /* special case switch after contractions switch
+ * to let state-machine figure out its state on abort */
+ if (codepoint == 0) {
+ return 0;
+ }
+
+ uint32_t mph_value = nu_udb_lookup_value(codepoint, NU_DUCET_G, NU_DUCET_G_SIZE,
+ NU_DUCET_VALUES_C, NU_DUCET_VALUES_I);
+
+ return (mph_value != 0
+ ? (int32_t)(mph_value)
+ : (int32_t)(codepoint + _nu_ducet_weights_count()));
+
+ /* ISO/IEC 14651 requests that codepoints with undefined weight should be
+ * sorted before max weight in collation table. This way all codepoints
+ * defined in ducet would have weight under a value of _nu_ducet_weights_count(),
+ * all undefined codepoints would have weight under
+ * 0x10FFFF + _nu_ducet_weights_count() - 1, max weight will be
+ * 0x10FFFF + _nu_ducet_weights_count() */
+
+ /* Regarding integer overflow:
+ *
+ * int32_t can hold 0xFFFFFFFF / 2 = 0x7FFFFFFF positive numbers, this
+ * function can safely offset codepoint value up to +2146369536 without
+ * risk of overflow. Thus max collation table size supported is
+ * 2146369536 (0x7FFFFFFF - 0x10FFFF) */
+}
+
+#endif /* NU_WITH_DUCET */
diff --git a/vendor/nunicode/src/libnu/gen/_ducet.c b/vendor/nunicode/src/libnu/gen/_ducet.c
new file mode 100644
index 0000000000..715bc913e8
--- /dev/null
+++ b/vendor/nunicode/src/libnu/gen/_ducet.c
@@ -0,0 +1,6197 @@
+/* Automatically generated file (mph.py), 1490539895
+ *
+ * Tag : NU_DUCET
+ * Prime : 01000193,
+ * G size : 20027,
+ * Combined length : 0,
+ * Encoding : UTF-8
+ */
+
+#include <stdint.h>
+
+const int16_t NU_DUCET_G[] = {
+ -20026, -20025, -20024, -20023, -20022, -20021, -20020, -20019, -20018, -20017, -20016, -20015,
+ -20013, 6, 49, 26, 52, 49, 56, -20011, 57, 50, 48, 83,
+ 68, 133, 139, 141, 144, -20010, -20005, -19999, -19998, -19997, -19996, -19994,
+ -19993, -19991, -19990, -19989, -19988, -19987, -19986, -19985, -19984, -19983, -19981, -19980,
+ -19979, -19978, -19971, -19969, -19967, -19961, -19957, -19956, -19951, -19950, -19948, -19947,
+ -19946, -19943, -19942, -19941, -19939, -19938, -19937, -19934, -19933, 3, 1, -19932,
+ -19931, -19930, -19917, -19916, -19897, -19896, -19895, -19894, -19893, -19892, -19891, -19890,
+ -19889, -19888, -19887, -19886, -19885, -19884, -19883, -19882, -19881, -19880, -19879, -19878,
+ -19877, -19876, -19874, -19873, -19872, -19871, -19870, -19869, -19868, -19867, -19866, -19865,
+ -19864, -19863, -19862, -19861, -19860, 0, -19859, -19858, -19857, -19856, -19855, -19854,
+ -19853, -19852, -19851, -19850, -19849, -19848, -19847, -19846, -19845, -19844, -19843, -19842,
+ -19841, -19840, -19839, -19838, -19837, -19836, -19835, -19834, -19833, -19832, -19831, -19830,
+ -19829, -19828, -19827, -19826, -19825, -19824, -19823, -19822, -19821, -19820, -19819, -19818,
+ -19817, -19816, -19815, -19814, -19813, -19812, -19811, -19810, -19809, -19808, -19807, -19806,
+ -19805, -19804, -19803, -19802, -19672, 1, 1, 1, 4, 1, 1, 8,
+ 8, 3, 4, 6, 17, 20, 17, 24, 24, -19671, -19670, -19669,
+ -19668, 32, -19666, -19665, -19664, 10, 16, 16, 40, 42, 40, 22,
+ 46, 64, 10, 54, 80, -19663, -19662, -19661, -19660, -19659, -19658, -19657,
+ -19656, -19655, -19654, -19653, -19652, 82, 1, 5, 1, 8, 8, 8,
+ 8, 1, 1, 1, 17, 17, 17, 17, 17, 5, 1, 1,
+ 1, 5, 1, 1, 1, 5, 1, 1, 4, 20, 25, 29,
+ 25, 32, 1, 3, 1, 3, -19651, -19650, -19649, -19648, -19647, -19646,
+ -19645, -19644, -19643, -19642, -19641, -19640, 2, 4, 2, 8, 2, 2,
+ 2, -19639, -19638, -19637, 2, -19636, -19635, -19634, -19633, 1, -19632, -19631,
+ -19630, -19629, -19628, -19627, -19626, -19625, -19624, -19623, -19622, -19621, -19620, -19619,
+ -19618, 1, -19617, -19616, -19615, -19614, -19613, -19612, -19611, -19610, -19609, -19608,
+ -19607, -19606, -19605, -19604, -19603, -19602, 5, 3, 4, 2, 9, 9,
+ 9, 3, -19601, -19600, 1, 5, -19599, -19598, -19597, -19596, 1, 3,
+ 1, 3, 1, 3, 1, 3, -19595, -19594, 1, 1, -19593, -19592,
+ -19591, -19590, -19589, -19588, 3, 1, -19587, -19586, -19585, -19584, -19583, -19582,
+ -19581, -19580, -19579, -19578, -19577, -19576, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -19575, 1, -19574, -19573,
+ 1, 1, -19572, -19571, -19570, -19569, -19568, -19567, -19566, -19565, -19564, -19563,
+ -19562, -19561, 1, 1, 1, 1, 1, 1, 1, -19560, 1, 1,
+ 1, -19559, -19558, -19557, -19556, 1, -19555, -19554, 1, 1, -19553, -19552,
+ -19551, -19550, -19549, -19548, -19547, -19546, -19545, -19544, -19543, -19542, 1, 1,
+ 1, 9, 2, 8, 1, 3, 1, 5, 16, 16, 16, 16,
+ 16, 1, -19541, -19540, -19539, 2, -19538, -19537, -19536, -19535, -19534, -19533,
+ -19532, -19531, -19530, -19529, 0, -19528, 15, 17, 22, 16, 24, 50,
+ 55, -19527, 48, 48, 64, 52, -19526, 64, -19525, 64, 64, 70,
+ 64, -19524, 66, 72, 74, 66, -19523, 65, 82, 64, -19522, -19521,
+ -19520, -19519, 1, 1, 5, -19518, 14, 3, 50, 2, 48, 11,
+ 51, -19517, -19516, 128, 144, 25, 29, 1, 49, 130, 129, 129,
+ 137, 62, 128, 128, 128, -19515, -19514, 134, 131, -19513, -19512, -19511,
+ -19510, -19509, -19508, -19507, -19506, -19505, -19504, -19503, -19502, -19501, -19500, -19499,
+ -19498, -19497, -19496, -19495, -19494, -19493, -19492, -19491, -19490, -19489, -19488, -19487,
+ -19486, -19485, -19484, -19483, -19482, 1, 4, 10, 12, 10, 8, 10,
+ 21, 22, 18, 22, 33, -19481, -19480, 39, 40, 32, 1, 3,
+ 4, 9, 1, 9, 2, 19, -19479, -19478, -19477, 4, -19476, -19475,
+ -19474, -19473, 1, 1, 1, 1, 3, 18, 21, 23, -19472, 16,
+ 18, 16, 81, 16, -19471, -19470, 50, 64, 64, 2, 64, 75,
+ 64, 72, 64, 83, 64, 37, 81, 97, 92, 120, 8, 8,
+ -19469, -19468, -19467, 9, 9, -19466, -19465, -19464, -19463, -19462, -19461, -19460,
+ -19459, 144, 28, 6, 2, -19458, -19457, -19456, -19455, 128, 67, 90,
+ 128, 128, 130, 136, 129, -19454, -19453, -19452, -19451, -19450, -19449, -19448,
+ -19447, -19446, -19445, -19444, -19443, -19442, -19440, -19439, -19438, -19437, -19436, -19435,
+ -19434, -19433, -19432, -19431, -19430, -19429, -19428, -19427, -19426, -19425, -19424, -19423,
+ -19422, 16, 8, 13, 72, 216, 220, 11, 220, 218, 256, 183,
+ 257, 248, 265, 211, 280, 163, 149, 218, 154, 273, 222, 218,
+ 259, 154, 258, 273, 278, 282, 332, 352, 352, 278, 286, 280,
+ 324, 213, 328, 280, 337, 337, 337, 294, 336, 281, 336, -19421,
+ -19420, 336, 1, 1, 1, -19419, -19418, -19416, -19415, -19414, -19413, -19412,
+ -19411, 1, 1, 1, -19410, 1, 2, 4, 4, 9, 10, 2,
+ 2, 6, 1, 16, 1, 25, 4, 25, 22, 2, 1, 1,
+ 7, 5, 8, 53, 53, -19409, 52, 64, 64, -19407, -19406, -19405,
+ -19404, 5, 1, 9, 11, -19402, -19401, 64, 64, -19400, -19399, -19398,
+ -19397, -19396, 0, 0, 0, -19395, 69, 71, 69, 76, 79, 90,
+ 97, 100, -19394, 98, 98, 98, -19393, -19392, -19391, -19390, 2, 10,
+ 12, 9, 9, 16, 9, 16, -19389, -19388, 16, -19387, 0, 0,
+ -19386, -19385, -19384, -19383, -19382, -19381, -19380, -19379, -19378, -19377, -19376, -19375,
+ -19374, -19373, -19372, -19371, -19370, -19369, -19368, -19367, -19366, -19365, -19364, -19363,
+ -19362, -19361, -19360, -19359, -19358, -19357, -19356, -19355, -19354, -19353, 9, 13,
+ 41, 36, 43, 64, 46, 64, 64, 64, 64, 64, -19352, 64,
+ 64, -19351, -19350, -19349, 29, -19348, -19347, -19346, -19345, -19344, -19343, -19342,
+ -19341, -19340, -19339, -19338, -19337, 45, -19336, -19335, -19334, -19333, -19332, -19331,
+ -19330, -19329, -19328, -19327, -19326, -19325, -19324, -19323, -19322, -19321, -19320, -19319,
+ -19318, -19317, -19316, -19315, -19314, -19313, -19312, -19311, -19310, 0, 0, 0,
+ 0, -19309, 1, 1, -19308, 1, 2, 21, 5, 32, 20, 26,
+ 32, 32, 32, 36, 32, -19307, 0, 0, 0, 0, -19306, -19305,
+ 0, 0, -19304, -19303, -19302, -19301, -19300, -19299, -19298, -19297, -19296, -19295,
+ -19294, -19293, 0, 0, 0, -19292, 0, 0, 0, 0, 0, 0,
+ 0, 0, -19291, -19290, -19289, -19288, -19287, -19286, -19285, -19284, -19283, -19282,
+ -19281, -19280, 0, 0, -19279, -19278, -19275, -19274, -19273, -19272, -19271, -19270,
+ -19269, -19268, -19267, -19266, -19265, -19264, -19263, -19262, -19261, -19260, -19259, -19258,
+ -19253, -19246, -19213, 0, 0, -19193, -19192, -19191, -19190, -19189, -19188, -19187,
+ -19186, -19185, -19184, -19183, -19182, -19181, -19180, -19179, -19178, -19177, -19173, -19172,
+ -19171, -19169, -19168, -19167, -19166, -19165, -19164, -19163, -19162, -19161, -19160, -19159,
+ -19158, -19157, 0, -19156, 0, -19155, 0, 0, 0, 0, -19154, -19153,
+ -19152, -19151, -19150, -19149, -19148, -19147, -19146, -19145, -19144, -19143, -19142, -19141,
+ -19140, -19139, -19138, -19137, -19136, -19135, -19134, -19133, -19132, -19131, -19130, -19129,
+ -19128, -19127, -19126, -19125, -19124, -19123, -19122, -19121, -19120, -19119, 0, 0,
+ -19118, -19117, 0, 0, 0, 0, 0, 0, 0, 0, -19116, -19115,
+ -19114, -19113, -19112, -19111, -19110, -19109, -19108, -19107, -19106, -19105, -19104, -19103,
+ -19102, -19101, -19100, -19099, -19098, -19097, -19096, -19095, -19094, -19093, 0, 0,
+ -19092, -19091, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -19090, -19089, 19, 20,
+ 16, 19, 19, 28, 37, 67, 68, 70, -19088, -19087, -19086, -19085,
+ 31, 59, 64, 66, 64, 66, 64, 66, 64, -19084, 65, 66,
+ 88, 91, 65, 66, 97, 125, 81, 99, 103, 117, 124, 288,
+ 295, 315, 384, 388, -19083, -19082, -19081, -19080, 310, 1, 228, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 18, 42, 10, 33, 33, 37, 33, 45, 82, 88, -19079, -19078,
+ -19077, -19076, -19075, -19074, -19073, -19072, 74, 74, 76, 78, 97, 101,
+ 96, 96, 96, 96, 96, 96, 96, 111, 96, 155, 1, 4,
+ 4, 1, 8, 8, 8, -19071, -19070, -19069, -19068, -19067, -19066, -19065,
+ -19064, 6, 3, -19063, -19062, -19061, 32, 32, 32, 36, 32, 36,
+ 38, 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 85, -19060, -19059,
+ -19058, 83, -19057, 0, -19056, -19055, -19054, -19053, -19052, -19051, 274, 274,
+ 0, 259, 1, 1, 1, 257, 256, 256, 257, -19050, 262, -19049,
+ -19048, -19047, -19046, -19045, -19044, 1, 1, 1, 1, 9, 9, 1,
+ 1, 1, 1, 1, 1, 263, 265, 1, 1, 1, 264, -19043,
+ 260, -19042, -19041, 265, 261, -19040, 259, -19039, 288, -19038, 288, -19037,
+ -19036, 289, 1, 1, 1, 1, -19035, -19034, 1, 1, 278, -19033,
+ 288, 288, 288, -19032, -19031, 256, 1, 1, 1, 1, 1, 1,
+ 1, 256, 257, 6, 28, 265, -19030, 265, -19029, 1, 264, -19028,
+ 267, 0, -19027, 276, -19026, 258, 1, 1, 1, 1, 1, 1,
+ 1, 12, 2, 11, 13, 16, -19025, -19024, -19023, -19022, -19021, -19020,
+ -19019, -19018, -19017, -19016, -19015, -19014, 1, 1, 4, 1, 1, 8,
+ 1, 3, 4, 6, 2, -19013, -19012, -19011, -19010, 1, 2, 4,
+ 1, 8, 8, 2, 2, 1, -19009, -19008, 4, 2, -19007, -19006,
+ -19005, -19004, -19003, -19002, -19001, -19000, 65, 68, 65, -18999, 72, 71,
+ 119, 73, -18998, -18997, -18996, -18995, -18994, -18993, -18992, -18991, -18990, -18989,
+ -18988, -18987, -18986, -18985, -18984, -18983, -18982, -18981, -18980, -18979, -18978, -18977,
+ -18976, -18975, -18974, -18973, -18972, -18971, -18970, -18969, -18968, -18967, -18966, -18965,
+ -18964, -18963, 118, 120, 120, 69, 123, 204, 126, 116, -18962, -18961,
+ 192, 71, -18960, -18959, -18958, -18957, 160, 160, 209, 317, 219, 336,
+ 292, 160, -18956, -18955, 337, 339, -18954, -18953, -18952, -18951, -18950, -18949,
+ -18948, -18947, -18946, -18945, -18944, -18943, -18942, -18941, -18940, -18939, -18938, -18937,
+ 48, 8, 139, 141, 161, 161, 172, 204, 5, 272, 284, 286,
+ -18936, -18935, -18934, 324, -18933, -18932, -18931, -18930, -18929, -18928, -18927, -18926,
+ -18925, -18924, -18923, -18922, -18921, -18920, -18919, -18918, -18917, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -18916, -18915,
+ -18914, -18913, 0, -18912, -18911, -18910, 0, 0, 0, 0, 0, 0,
+ 0, 0, -18909, -18908, -18907, -18906, -18905, -18904, -18903, -18902, -18901, -18900,
+ -18899, -18898, -18897, -18896, -18895, -18894, -18893, -18892, -18891, -18890, -18889, -18888,
+ -18887, -18886, -18885, -18884, -18883, -18882, -18881, -18880, -18879, -18878, -18877, -18876,
+ -18875, -18874, -18873, -18872, -18871, -18870, -18869, -18868, -18867, -18866, -18865, -18864,
+ -18863, -18862, -18861, -18860, -18859, -18858, 0, 0, 0, -18857, 0, 0,
+ 0, 0, 0, 0, 0, -18856, 12, 16, 16, 19, 17, 19,
+ 27, 38, 49, 38, 48, 54, 48, 144, 151, 144, -18855, -18854,
+ -18853, -18852, -18851, -18850, -18849, -18848, -18847, -18846, -18845, -18844, -18843, -18842,
+ -18841, -18840, -18839, -18838, -18837, 0, -18836, -18835, -18834, 0, 0, 0,
+ 0, 0, 0, 0, 0, -18833, 1, 1, 1, 1, 1, 1,
+ 1, 1, -18832, 4, 4, 17, -18831, -18830, -18829, -18828, 1, 1,
+ 1, -18827, -18826, 1, 1, -18825, -18824, -18823, -18822, -18821, -18820, -18819,
+ -18818, 1, -18817, -18816, -18815, -18814, -18813, -18812, -18811, -18810, -18809, -18808,
+ -18807, -18806, -18805, -18804, -18803, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -18802, -18801, -18800,
+ -18799, -18798, -18797, -18796, -18795, 0, 0, 0, 0, 0, 0, 0,
+ 0, -18794, -18793, -18792, -18791, -18790, -18789, -18788, -18787, -18786, -18785, -18784,
+ -18783, -18782, -18781, -18780, -18779, -18778, -18777, -18776, -18775, -18774, -18773, -18772,
+ -18771, -18770, -18769, -18768, -18767, -18766, -18765, -18764, -18763, -18762, -18761, -18760,
+ -18759, -18758, -18757, -18756, -18755, -18754, -18753, -18752, -18751, -18750, -18749, -18748,
+ -18747, -18746, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1,
+ 1, 1, 2, 2, 16, 3, 1, 3, 1, 3, 1, 3,
+ 1, 3, 1, 3, 5, 31, 1, 32, 2, 4, -18745, -18744,
+ -18743, -18742, -18741, -18740, -18739, -18738, -18737, -18736, -18735, -18734, -18733, -18732,
+ -18731, -18730, 1, 1, 1, 5, 1, 1, 8, 5, 1, 3,
+ 1, 16, -18729, -18728, -18727, -18726, -18725, -18724, -18723, -18722, -18721, -18720,
+ -18719, -18718, -18717, -18716, -18715, -18714, -18713, -18712, -18711, -18710, -18709, -18708,
+ -18707, -18706, -18705, -18704, -18703, -18702, -18701, -18700, -18699, -18698, -18697, -18696,
+ -18695, -18694, 1, 1, 4, 8, 10, 8, 14, 16, 16, 16,
+ 16, -18693, 16, 16, 16, 3, -18692, -18691, -18690, -18689, -18688, -18687,
+ -18686, -18685, 3, -18684, -18683, -18682, 8, 2, 8, 10, -18681, -18680,
+ -18679, -18678, -18677, -18676, -18675, -18674, -18673, -18672, -18671, -18670, -18669, -18668,
+ -18667, -18666, 8, 10, 14, 18, 18, 21, 21, 18, -18665, -18664,
+ -18663, 18, -18662, -18661, -18660, -18659, -18658, -18657, -18656, -18655, -18654, -18653,
+ -18652, -18651, -18650, -18649, -18648, -18647, -18646, -18645, -18644, -18643, -18642, -18641,
+ -18640, -18639, -18638, -18637, -18636, -18635, -18634, -18633, -18632, -18631, -18630, -18629,
+ -18628, -18627, -18626, -18625, -18624, -18623, -18622, -18621, -18620, -18619, -18618, -18617,
+ -18616, -18615, -18614, -18613, -18612, -18611, -18610, -18609, -18608, -18607, -18606, -18605,
+ -18604, -18603, -18602, -18601, -18600, -18599, -18598, -18597, -18596, -18595, -18594, -18593,
+ 1, 1, -18592, 1, 1, -18591, -18590, -18589, -18588, -18587, -18586, -18585,
+ -18584, -18583, -18582, -18581, -18580, -18579, -18578, -18577, -18576, 0, -18575, -18574,
+ -18573, -18572, 1, 1, -18571, 1, 1, 1, 1, 1, 2, 2,
+ 8, 3, 1, 3, 1, 17, 1, 16, 1, 7, 1, -18570,
+ -18569, 1, 1, 5, 1, 1, 1, 6, 1, 39, 2, 50,
+ 13, 11, -18568, -18567, -18566, -18565, -18564, -18563, -18562, -18561, -18560, -18559,
+ -18558, -18557, -18556, -18555, -18554, -18553, 16, 16, 16, 16, -18552, -18551,
+ -18550, -18549, -18548, -18547, -18546, -18545, -18544, -18543, -18542, -18541, 1, 5,
+ 5, 1, 8, 12, 8, 26, 2, 2, 2, 38, 3, 33,
+ 44, 48, 32, 32, 32, 32, 32, 40, 32, 32, -18540, -18539,
+ 32, -18538, -18537, -18536, -18535, -18534, 24, 24, 68, 24, 64, 64,
+ 72, 64, -18533, -18532, -18531, -18530, -18529, -18528, -18527, -18526, 88, 88,
+ 88, 88, 128, 128, 128, -18525, -18524, 128, 128, -18523, -18522, -18521,
+ -18520, 141, 2, 4, 1, 3, 8, 2, 2, 1, 1, 1,
+ 1, 16, 1, 17, 1, -18519, -18518, -18517, -18516, -18515, -18514, -18513,
+ -18512, -18511, -18510, -18509, -18508, -18507, -18506, -18505, -18504, -18503, -18502, -18501,
+ -18500, -18499, -18498, -18497, 0, -18496, -18495, -18494, -18493, -18492, 0, -18491,
+ 0, -18490, -18489, -18488, -18487, -18486, -18485, -18484, -18483, -18482, -18481, -18480,
+ -18479, -18478, -18477, -18476, -18475, -18474, -18473, -18472, -18471, -18470, -18469, -18468,
+ 0, 0, -18467, -18466, -18465, -18464, 0, 0, 0, -18463, 1, 1,
+ -18462, -18461, 1, 1, -18460, 1, 1, 1, 1, -18459, -18457, -18451,
+ -18449, 1, 1, 1, -18448, -18447, 1, 1, -18444, 1, 1, 1,
+ 1, 1, -18443, -18442, -18441, -18440, -18439, -18438, -18437, -18436, -18435, -18434,
+ -18433, -18432, -18431, -18430, -18429, -18428, 0, 0, 0, -18427, -18426, -18425,
+ -18424, 1, 0, 0, -18423, 1, 1, 4, 4, 1, -18422, -18421,
+ 9, -18420, -18419, -18418, -18417, -18416, -18415, -18414, -18413, -18412, -18411, -18410,
+ -18409, -18408, -18407, -18406, -18405, -18404, -18403, -18402, -18401, -18400, -18399, -18398,
+ -18397, -18396, -18395, -18394, -18393, -18392, -18391, -18390, -18389, -18388, 2, 5,
+ 12, -18387, -18386, 10, 26, 34, -18385, -18384, -18383, 33, 37, 44,
+ 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, -18382,
+ 1, -18381, 1, -18380, 1, -18379, 1, 1, 4, 6, -18378, -18377,
+ 24, 9, 16, 32, 16, 32, -18376, -18375, 18, 2, 1, 1,
+ 4, -18374, -18373, 2, 2, 2, 1, -18372, 5, 50, -18371, -18370,
+ 3, 1, 4, 6, 12, 12, -18369, 23, 21, -18368, -18367, -18366,
+ 16, 116, -18365, -18364, 22, 14, 5, 10, 34, 2, 35, 64,
+ 66, 69, 64, 64, 64, 64, 66, 64, 79, 1, 1, 6,
+ 8, -18363, -18362, 9, 13, 27, 23, 7, 32, 22, 32, 23,
+ 32, 28, 14, 16, 16, 19, 16, 16, 25, 16, 16, 43,
+ 130, 47, 136, 143, 148, 3, 3, 7, 9, -18361, 9, 20,
+ 15, 31, 17, 129, -18360, 24, 131, 136, 142, 16, 16, 20,
+ 20, 16, 27, 31, 154, 145, 170, 144, 186, 152, 184, 165,
+ 185, -18359, -18358, 3, 3, -18357, -18356, -18355, -18354, -18353, -18352, -18351,
+ -18350, -18349, -18348, -18347, -18346, 1, 7, 13, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 18, 16, 33, -18345, -18341, -18340,
+ -18339, -18338, -18337, -18336, -18335, -18334, -18333, -18332, -18331, -18330, -18329, -18328,
+ -18327, -18326, -18325, -18324, -18323, -18322, -18321, -18320, -18319, 2, 1, 1,
+ -18318, 5, 11, 2, 13, -18317, -18316, -18315, -18314, -18313, -18312, -18311,
+ -18310, -18309, -18308, -18307, -18306, -18305, -18304, -18303, -18302, -18301, -18300, -18299,
+ -18298, -18297, -18296, -18295, -18294, -18293, -18292, -18291, -18290, -18289, -18288, -18287,
+ -18286, -18285, -18284, -18283, -18282, -18281, -18280, -18279, -18278, -18277, -18276, -18275,
+ -18274, -18273, -18272, -18271, -18270, -18269, -18268, -18267, -18266, -18265, -18264, -18263,
+ -18262, -18261, -18260, -18259, -18258, -18257, -18256, -18255, -18254, 1, 1, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 30, 32, 18, 16, 20, 16, 26, 16, 30, 86, 17, 38,
+ 87, 96, 108, 108, 112, 112, 96, 96, 96, -18253, -18252, 96,
+ 96, -18251, -18250, -18249, -18248, -18247, -18246, -18245, -18244, 98, -18243, -18242,
+ -18241, -18240, -18239, -18238, -18237, -18236, -18235, -18234, -18233, -18232, -18231, -18230,
+ -18229, -18228, 1, 6, 6, -18227, -18226, 9, 12, 1, -18225, -18224,
+ 1, 4, -18223, -18222, -18221, -18220, -18219, -18218, -18217, -18216, -18215, -18214,
+ -18213, -18212, -18211, -18210, -18209, -18208, -18207, -18206, -18205, 0, -18204, -18203,
+ -18202, 0, 0, 0, 0, -18201, -18200, -18199, -18198, -18197, -18196, -18195,
+ -18194, -18193, -18192, -18191, -18190, -18189, -18188, -18187, -18186, -18185, -18184, -18183,
+ -18182, -18181, -18180, -18179, -18178, -18177, -18176, -18175, -18174, -18173, -18172, -18171,
+ -18170, -18169, -18168, -18167, -18166, -18165, -18164, -18163, -18162, -18161, -18160, -18159,
+ -18158, -18157, -18156, -18155, -18154, -18153, -18152, -18151, -18150, -18149, -18148, -18147,
+ -18146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -18145, -18144, -18143, -18142, 0, 0,
+ -18141, 0, -18140, -18139, -18138, 0, 0, 0, -18137, 1, -18136, 1,
+ -18135, -18134, 1, -18133, -18132, -18131, 1, 1, -18130, -18129, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -18128, -18127,
+ -18126, 1, 1, 1, 1, -18125, 0, 0, 0, 0, 0, -18124,
+ 0, -18123, -18122, -18121, 0, -18120, -18119, 0, -18118, 1, 1, 1,
+ 1, -18117, -18116, -18115, 1, 1, -18114, -18113, -18112, 1, 1, 1,
+ 1, 1, -18111, -18110, -18109, -18108, 1, 1, -18107, -18106, -18105, -18104,
+ -18103, 3, -18102, 2, -18101, 0, -18100, -18099, 17, -18098, -18097, -18096,
+ -18095, -18094, -18093, -18092, -18091, -18090, -18089, -18088, -18087, 1, 1, 1,
+ 4, -18086, -18085, -18084, -18083, -18082, -18081, -18080, -18079, -18078, -18077, -18076,
+ -18075, 3, -18074, -18073, -18072, -18071, -18070, -18069, -18068, -18067, -18066, -18065,
+ -18064, -18063, -18062, -18061, -18060, 0, -18059, -18058, -18057, -18056, -18055, -18054,
+ -18053, -18052, 0, 0, -18051, -18050, 0, 0, 0, -18049, -18048, -18047,
+ -18046, -18045, -18044, -18043, -18042, 0, 0, 0, 0, 0, 0, 0,
+ 0, -18041, -18040, -18039, -18038, -18037, -18036, -18035, -18034, -18033, -18032, -18031,
+ -18030, 0, -18029, -18028, -18027, -18026, -18025, -18024, -18023, -18022, -18021, -18020,
+ -18019, -18018, -18017, -18016, -18015, -18014, -18013, -18012, -18011, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -18010, -18009, -18008, -18007, -18006, 0, 0, -18005, -18004, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -18003, -18002, -18001, -18000, -17999, -17998, -17997, -17996, -17995, -17994, -17993,
+ -17992, -17991, -17990, -17989, -17988, -17987, -17986, -17985, -17984, -17983, -17982, -17981,
+ -17980, -17979, -17978, -17977, -17976, -17975, -17974, -17973, -17972, 0, -17971, -17970,
+ -17969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -17968, -17967, -17966, -17965, -17964, -17963, -17962, -17961, -17960, -17959, -17958,
+ -17957, -17956, -17955, -17954, -17953, -17952, -17951, -17950, -17949, -17948, -17947, -17946,
+ -17945, -17944, -17943, -17942, -17941, -17940, -17939, -17938, -17937, -17936, -17935, -17934,
+ -17933, -17932, -17931, -17930, -17929, -17928, -17927, -17926, -17925, -17924, -17923, -17922,
+ -17921, 0, -17920, -17919, -17918, 0, 0, 0, 0, -17917, -17916, 0,
+ 0, -17915, -17914, -17913, -17912, -17911, -17910, -17909, -17908, -17907, -17906, -17905,
+ -17904, -17903, -17902, -17901, -17900, -17899, -17898, -17897, -17896, -17895, -17894, -17893,
+ -17892, -17891, -17890, -17889, -17888, -17887, -17886, -17885, -17884, -17883, -17882, -17881,
+ -17880, -17879, -17878, -17877, -17876, -17875, -17874, -17873, -17872, -17871, -17870, -17869,
+ -17868, -17867, -17866, -17865, -17864, -17863, -17862, -17861, -17860, -17859, -17858, -17857,
+ -17856, -17855, -17854, -17853, -17852, -17851, -17850, -17849, -17848, -17847, -17846, -17845,
+ -17844, -17843, -17842, -17841, -17840, -17839, -17838, -17837, -17836, -17835, -17834, -17833,
+ -17832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17831, -17830, -17829, -17828, -17827, -17826, -17825,
+ -17824, 0, 0, 0, -17823, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -17822, -17821, -17820, -17819, -17818, -17817,
+ -17816, -17815, -17814, -17813, -17812, -17811, 0, 0, 0, 0, -17810, -17809,
+ -17808, -17807, -17806, -17805, -17804, -17803, -17802, -17801, -17800, -17799, -17798, -17797,
+ -17796, -17795, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17794, -17793, -17792, -17791, -17790, -17789, -17788,
+ -17787, -17786, -17785, -17784, -17783, 0, -17782, -17781, -17780, -17779, -17778, -17777,
+ -17776, -17775, -17774, -17773, -17772, -17771, -17770, -17769, -17768, -17767, -17766, -17765,
+ -17764, -17763, -17762, -17761, -17760, -17759, -17758, -17757, -17756, -17755, -17754, -17753,
+ -17749, -17748, -17747, -17746, -17745, -17744, -17743, -17742, -17741, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, -17740, -17739, -17738,
+ -17737, 0, 0, 0, 0, 0, -17736, -17735, 0, 0, -17734, -17733,
+ -17732, 1, -17730, -17729, -17728, -17727, -17726, -17724, -17723, -17722, -17721, -17720,
+ -17719, -17718, -17716, -17714, -17713, -17712, -17708, -17706, -17703, -17702, -17700, -17699,
+ -17698, 0, -17697, -17696, -17692, 0, 0, 0, -17691, -17690, -17686, -17682,
+ 0, 0, 0, 0, -17681, 0, 0, 0, 0, 0, 0, 0,
+ 0, -17680, -17677, -17676, -17675, 0, 0, 0, -17674, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17673, -17672, -17671, 0, -17670, -17669, -17668,
+ -17667, -17666, -17665, -17664, -17663, -17662, -17661, -17660, -17659, -17658, -17657, -17656,
+ -17655, -17654, -17653, -17652, -17651, -17650, -17649, -17648, -17647, -17646, -17645, -17644,
+ -17643, -17642, -17641, -17640, -17639, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, -17638, -17637, -17636, -17635, 1, 1, -17634,
+ -17633, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, -17632, -17631, -17630, -17629, 0, 0, 0, 0, 0, 0, 0,
+ 0, -17628, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, -17627, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17626, -17625,
+ -17624, 0, -17623, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -17622, -17621, -17620, -17619, -17618, -17617, -17616, -17615, -17614, -17613, -17612,
+ -17611, -17610, -17609, -17608, -17607, -17606, -17605, -17604, -17603, -17602, -17601, -17600,
+ -17599, -17598, -17597, -17596, -17595, -17594, -17593, -17592, -17591, -17590, 0, 0,
+ 0, -17589, -17588, -17587, -17586, -17585, -17584, -17583, -17582, -17581, -17580, -17579,
+ -17578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17577, -17576, -17575, -17574, -17573, -17572, -17571,
+ -17570, -17569, -17568, -17567, -17566, -17565, -17564, -17563, -17562, -17561, -17560, -17559,
+ -17558, -17557, -17556, -17555, -17554, -17553, -17552, -17551, -17550, -17549, -17548, -17547,
+ -17546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17545, -17544, -17543, -17542, -17541, -17540, -17539,
+ -17538, 0, 0, -17537, -17536, 0, 0, 0, 0, -17535, -17534, -17533,
+ -17532, -17531, -17530, -17529, -17528, 0, 0, 0, -17527, 0, 0, 0,
+ 0, -17526, -17525, -17524, -17523, -17522, -17521, -17520, -17519, -17518, -17517, -17516,
+ -17515, -17514, -17513, -17512, -17511, -17510, 0, 0, 0, -17509, 1, 1,
+ -17508, -17507, 1, 1, 1, 1, 1, 1, 1, 1, -17506, -17505,
+ -17504, -17503, -17502, -17501, -17500, 0, 0, 0, 0, 0, 0, 0,
+ 0, -17499, -17498, -17497, -17496, -17495, -17494, -17493, -17492, -17491, -17490, -17489,
+ -17488, -17487, -17486, -17485, -17484, -17483, -17482, 0, 0, -17481, -17480, -17479,
+ -17478, -17477, -17476, -17475, -17474, -17473, -17472, -17471, -17470, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17469, -17468, -17467, -17466, -17465, -17464, -17463,
+ -17462, -17461, -17460, -17459, -17458, -17457, -17456, -17455, -17454, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17453, 0, 0, -17452, -17451, -17450, -17449,
+ -17448, -17447, -17446, -17445, -17444, -17443, -17442, -17441, -17440, 0, 0, 0,
+ 0, -17439, -17438, -17437, 0, -17436, -17435, -17434, -17433, -17432, 0, 0,
+ -17431, -17430, -17429, 0, -17428, -17427, -17426, -17425, 0, 0, 0, -17424,
+ -17423, 0, 0, -17422, 0, -17421, -17420, -17419, -17418, -17417, -17416, -17415,
+ -17414, -17413, -17412, 0, -17411, -17410, -17409, -17408, -17407, 0, 0, 0,
+ -17406, 0, 0, 0, 0, 0, 0, 0, 0, -17405, -17404, -17403,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17402,
+ -17401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -17400, -17399, -17398, -17397, -17396, -17395, -17394, -17393, -17392, -17391, -17390,
+ -17389, -17388, 0, -17387, -17386, -17385, -17384, -17383, -17382, 0, -17381, -17380,
+ -17379, -17378, -17377, 0, -17376, -17375, 0, -17374, -17373, -17372, -17371, -17370,
+ -17369, -17368, -17367, -17366, -17365, -17364, -17363, -17362, -17361, -17360, -17359, -17358,
+ -17357, -17356, -17355, -17354, -17353, -17352, -17351, -17350, -17349, 0, 0, 0,
+ -17348, 0, 0, 0, 0, -17347, -17346, -17345, -17344, -17343, -17342, -17341,
+ -17340, -17339, -17338, -17337, -17336, 0, -17335, -17334, -17333, -17332, -17331, -17330,
+ -17329, -17328, -17327, -17326, -17325, -17324, -17323, -17322, -17321, -17320, -17319, -17318,
+ -17317, -17316, -17315, -17314, -17313, -17312, -17311, -17310, -17309, 0, 0, -17308,
+ -17307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -17306, 0, -17305,
+ -17304, -17303, -17302, -17301, -17300, -17299, -17298, -17297, -17296, -17295, -17294, -17293,
+ -17292, -17291, -17258, -17257, -17256, -17255, -17254, -17253, -17252, -17251, -17249, -17248,
+ -17247, -17246, -17234, -17230, -17229, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -17223, -17204, -17202,
+ -17201, -17200, -17199, -17198, -17196, -17195, -17189, -17188, -17187, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17186, -17185, -17182, -17180, -17166, -17162, -17160,
+ -17159, -17158, -17157, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, -17156, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, -17155, -17154, -17153, -17151, -17150, -17149, -17148, -17147, -17146, -17145, 0,
+ 0, 0, 0, 0, 0, -17144, -17143, -17142, -17141, -17140, -17139, -17138,
+ -17137, -17136, -17135, -17134, -17133, 0, -17132, -17131, -17130, 0, 0, 0,
+ 0, 0, 0, 0, 0, -17129, -17128, -17127, -17126, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17125,
+ -17124, -17123, -17122, -17121, -17120, -17119, -17118, -17117, -17116, -17115, -17114, -17113,
+ -17112, -17111, -17110, -17109, -17108, -17107, -17106, -17105, -17104, -17103, -17102, -17101,
+ -17100, -17099, -17098, -17097, -17096, -17095, -17094, -17093, -17092, -17091, -17090, -17089,
+ -17088, -17087, -17086, -17085, -17084, -17083, -17082, -17081, -17080, -17079, -17078, -17077,
+ -17076, -17075, -17074, -17073, -17072, -17071, -17070, -17069, -17068, -17067, -17066, -17065,
+ -17064, -17063, -17062, -17061, -17060, -17059, -17058, -17057, -17056, -17054, -17053, -17052,
+ -17051, -17049, -17048, -17047, -17046, -17045, -17044, -17043, -17042, -17041, -17040, -17038,
+ -17037, -17036, -17035, -17034, -17033, -17032, -17031, -17030, -17029, -17028, -17027, -17025,
+ -17024, -17023, -17022, -17021, -17020, -17019, -17018, -17016, -17015, -17014, -17013, -17012,
+ -17011, -17010, -17009, -17008, -17007, -17006, -17004, -17002, -17000, 1, 1, 4,
+ 4, 1, 1, 12, 12, 20, 20, 16, 16, 24, 24, 24,
+ 24, 2, 2, 41, 42, 40, 43, 41, 42, 32, 48, 52,
+ 55, 56, 56, 56, 56, -16998, -16997, -16996, -16995, -16994, -16991, -16990,
+ -16985, -16984, -16983, -16981, -16980, -16979, -16977, -16973, -16970, 16, 16, 16,
+ 16, 25, 26, 28, 31, 19, 64, 64, 64, 64, 64, 64,
+ 64, 2, 2, 2, 2, 18, 18, 2, 1, -16969, -16967, 1,
+ 1, -16966, -16965, -16964, -16963, -16962, -16961, -16960, -16959, 1, -16958, 2,
+ 4, -16957, -16956, -16955, -16953, -16946, -16942, -16941, -16940, -16939, -16938, -16937,
+ -16936, -16935, -16934, -16933, -16932, -16931, -16930, -16929, -16928, -16927, -16926, -16925,
+ -16924, -16923, -16922, -16921, -16920, -16919, -16918, -16917, -16916, -16915, -16914, -16913,
+ -16912, -16911, -16910, -16909, -16908, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, -16907, -16906, -16905, -16904, -16903, -16902, -16901, -16900, -16899,
+ -16898, -16897, -16896, -16895, -16894, -16893, -16892, -16891, -16890, -16889, -16888, -16887,
+ -16886, -16885, -16884, -16883, -16882, 0, 0, 0, -16881, 0, 0, 0,
+ 0, 0, 0, 0, 0, -16880, -16879, -16878, -16877, -16876, -16875, -16874,
+ -16873, -16872, -16871, -16870, -16869, -16868, -16867, -16866, -16865, -16864, -16863, -16862,
+ -16861, -16860, -16859, -16858, -16857, 0, 0, -16856, -16855, 0, 0, 0,
+ 0, 0, 0, 0, 0, -16854, 0, 0, 0, 0, -16853, -16852,
+ -16851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -16850, -16849, -16848,
+ -16847, -16846, -16845, -16844, -16843, 0, 0, -16842, -16841, 0, 0, 0,
+ 0, -16839, -16838, -16837, -16836, -16835, -16833, -16830, -16829, -16828, -16826, -16825,
+ -16824, -16823, -16822, -16821, -16820, -16819, -16818, -16817, -16816, -16815, -16814, -16813,
+ -16812, -16811, -16810, -16809, -16806, 0, 0, 0, 0, 0, -16805, -16803,
+ -16799, -16782, 0, -16781, -16780, -16778, 0, 0, 0, 0, 0, 0,
+ 0, 0, -16776, -16775, -16773, -16772, -16769, -16768, -16767, -16766, -16764, -16763,
+ -16762, -16761, -16760, -16759, -16758, -16757, -16756, -16755, -16754, -16752, 0, -16751,
+ -16750, -16749, -16748, -16747, -16746, -16745, 0, -16744, -16743, -16742, -16740, -16739,
+ -16738, -16737, 0, -16736, -16735, -16734, -16733, -16732, -16731, -16730, 0, -16729,
+ -16728, -16727, -16726, -16725, -16724, -16723, 0, -16722, -16721, -16720, -16719, -16718,
+ -16717, -16716, 0, -16715, -16714, 1, 1, 1, 1, 1, -16713, 1,
+ 1, 1, 1, 1, 1, 1, -16712, 1, 1, 1, -16711, -16710,
+ -16709, -16708, -16707, -16706, -16705, -16704, -16703, -16702, -16701, -16700, -16699, -16698,
+ -16697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -16696, 1, 1, 1, 1, 1, 1,
+ 1, -16695, 1, 1, 1, -16694, -16693, -16692, -16691, -16690, -16689, -16688,
+ -16687, -16686, -16685, -16684, -16683, -16682, -16681, -16680, -16679, -16678, -16677, -16676,
+ -16675, 1, 1, 1, 1, 1, 1, 1, 1, -16674, -16673, 1,
+ 1, -16672, -16671, -16670, -16669, -16668, -16667, -16666, -16665, -16664, -16663, 0,
+ -16662, -16661, 0, 0, 0, 0, 0, 0, -16660, 0, -16659, -16658,
+ -16657, -16656, -16655, -16654, -16653, -16652, -16651, -16634, -16631, -16606, -16602, -16601,
+ -16598, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, -16597, -16596, -16595, -16594, -16593, -16592,
+ -16591, -16590, -16589, -16588, -16587, -16586, -16585, -16584, -16583, 0, -16582, -16581,
+ -16580, -16579, -16578, -16577, -16576, -16575, 0, 0, 0, 0, 0, 0,
+ 0, -16574, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, -16573, -16572, 1, 1, -16571, -16570, -16569, -16568, -16567, -16566, -16565,
+ -16564, -16563, -16562, -16561, 1, -16560, -16559, -16558, -16557, -16556, -16555, -16554,
+ -16553, -16552, -16551, -16550, -16549, -16548, -16547, -16546, -16545, -16544, -16543, -16542,
+ -16541, -16540, -16539, -16538, -16537, -16536, -16535, -16534, -16533, -16532, -16531, -16530,
+ -16529, -16528, -16527, -16526, -16525, -16524, -16523, -16522, -16521, -16520, -16519, -16518,
+ -16517, -16516, -16515, -16514, -16513, -16512, -16511, -16510, -16509, -16508, -16507, -16506,
+ -16497, -16496, -16495, -16494, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -16493, 0, -16492, -16491, -16490, -16489, 0, 0,
+ 0, -16486, -16483, 0, 0, 0, 0, -16482, -16481, -16480, -16479, -16477,
+ -16476, -16475, -16471, -16470, -16469, -16468, -16466, -16465, -16464, -16463, -16462, -16461,
+ -16460, -16459, -16442, -16437, -16435, -16417, -16408, -16394, -16393, -16392, -16391, -16390,
+ -16389, -16388, -16387, -16386, -16385, -16384, -16383, -16382, -16381, -16380, -16379, -16378,
+ -16377, -16376, -16375, -16374, -16373, -16372, -16371, -16370, -16369, -16367, -16366, -16365,
+ -16364, -16363, -16362, -16361, -16360, -16359, -16358, -16357, -16356, -16355, 0, -16354,
+ -16353, -16352, -16351, -16350, -16349, -16348, -16347, -16346, -16345, -16344, -16343, -16342,
+ -16339, -16334, 0, -16330, -16329, -16328, -16327, -16326, -16325, -16324, -16323, -16322,
+ -16321, -16320, -16319, -16318, -16317, -16316, -16315, -16314, -16313, -16312, -16311, -16310,
+ -16309, -16308, -16307, -16306, -16305, -16304, -16303, -16302, -16301, -16300, -16299, -16298,
+ 0, 0, -16297, -16296, -16295, -16294, -16293, -16292, -16291, -16290, -16289, -16288,
+ -16287, -16286, -16285, -16284, -16283, -16282, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -16281, -16280, -16279,
+ -16278, -16277, -16276, -16275, -16274, -16273, -16272, -16271, -16270, -16269, -16268, -16267,
+ -16266, -16265, -16264, -16263, -16262, -16261, -16260, -16259, -16258, -16257, -16256, -16255,
+ -16254, -16253, -16252, -16251, -16250, -16249, -16248, -16247, -16246, -16245, -16244, -16243,
+ -16242, -16241, -16240, -16239, -16238, -16237, -16236, -16235, -16234, -16233, -16232, -16231,
+ -16230, -16229, -16228, -16227, -16226, -16225, -16224, -16223, -16222, -16221, -16220, -16219,
+ -16218, 0, -16217, -16216, -16215, 0, 0, 0, 0, 0, 0, 0,
+ 0, -16214, 0, 0, 0, -16213, -16212, -16211, -16210, -16209, -16208, -16207,
+ -16206, -16205, -16204, -16203, -16190, -16185, -16182, -16181, -16179, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -16178, -16177, -16176, -16175, -16173, -16172,
+ -16171, -16170, -16169, -16168, -16167, -16166, -16165, -16164, -16163, -16162, -16161, -16160,
+ -16159, -16157, -16155, -16140, -16138, -16135, -16134, -16133, -16131, -16127, -16124, -16122,
+ -16121, -16120, -16119, -16118, -16117, -16116, -16115, -16114, -16113, -16112, -16111, -16110,
+ -16109, -16108, -16107, -16106, -16105, -16104, -16103, -16102, -16101, -16100, -16099, -16098,
+ -16097, -16095, -16094, -16093, -16092, -16091, -16090, -16089, -16088, -16087, -16086, -16084,
+ -16083, -16082, -16081, -16080, -16079, -16078, -16077, -16076, -16075, -16059, -16053, -16049,
+ -16048, -16047, -16045, -16044, -16043, -16042, -16038, -16037, -16036, -16035, -16031, -16030,
+ -16028, -16025, -16024, -16023, -16020, -16019, -16018, -16017, -16014, -16010, -16009, -16008,
+ -16007, -16006, -16005, -16004, -16003, -16002, -16001, -16000, -15999, -15998, -15997, -15996,
+ -15995, -15994, -15993, -15992, -15991, -15990, -15989, -15988, -15987, -15986, -15985, -15984,
+ -15983, -15982, -15981, -15980, -15979, -15978, -15977, -15976, -15975, -15974, -15973, -15972,
+ -15971, -15970, -15969, -15968, -15967, -15966, -15965, -15964, -15963, -15962, -15961, -15960,
+ -15959, -15958, -15957, -15956, -15955, -15954, -15953, -15952, -15951, -15950, -15949, -15948,
+ -15947, -15946, -15945, -15944, -15943, -15942, -15941, -15940, -15939, -15938, -15937, -15936,
+ -15935, -15934, -15933, -15932, -15931, -15930, -15929, -15928, -15926, -15925, -15924, -15923,
+ -15922, -15921, -15920, -15919, -15918, -15917, -15916, -15915, -15914, -15913, -15912, -15911,
+ -15910, -15909, -15908, -15907, -15906, -15905, -15904, -15903, -15902, -15901, -15900, -15899,
+ -15897, -15896, -15895, -15894, -15893, -15892, -15891, -15890, -15889, -15888, -15887, -15886,
+ -15885, -15884, -15883, -15882, -15880, -15879, -15878, -15877, -15876, -15874, -15873, -15872,
+ -15871, -15870, 2, 1, -15869, -15868, -15867, -15866, 1, 1, -15865, -15864,
+ -15863, -15862, -15861, -15860, -15859, -15858, 1, 2, 4, 1, 1, 2,
+ 6, 8, 1, 3, 4, 15, -15857, 5, 3, 4, 1, 3,
+ 4, 16, 1, 1, 5, 7, -15856, 3, 3, 12, -15855, -15854,
+ -15853, -15852, 1, 1, 4, 1, 1, 1, 1, 8, 1, 1,
+ 1, 1, 1, 3, 16, 16, -15851, -15849, -15847, -15843, -15842, -15841,
+ -15840, -15839, -15838, -15835, -15834, -15833, -15832, -15831, -15830, -15829, -15828, -15827,
+ -15826, -15825, -15824, -15823, -15822, -15821, -15820, -15819, -15818, -15817, -15816, -15815,
+ -15814, 1, 1, 1, 1, 1, 8, 8, 3, 12, 1, 1,
+ 5, 1, 16, 16, 17, 24, -15813, -15812, -15811, -15810, -15809, -15808,
+ -15807, -15806, -15805, -15804, -15803, -15798, -15797, -15796, -15794, -15793, 6, 6,
+ 8, 8, 4, 4, 4, 4, 4, 4, 5, 41, 4, 4,
+ 24, 1, 2, 2, 6, 6, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 94, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 79, 1, 75, 1, 81, -15792, 89,
+ 147, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1,
+ 13, 14, 5, 32, 2, 33, 40, 32, 46, 137, 21, 29,
+ 5, 60, 7, 119, 146, 1, 144, 144, 144, 2, 2, 56,
+ 84, 154, 16, 116, 118, 130, 132, 147, 181, 191, 9, 158,
+ 209, 211, 240, 240, 256, 4, 4, 17, 69, 22, 261, 83,
+ 8, 6, 149, 257, 272, 148, 92, 272, 268, -15791, 57, 207,
+ 9, 211, -15790, -15789, -15788, -15787, -15786, -15785, -15784, 52, 52, 58,
+ 52, -15782, -15781, -15780, -15779, -15778, 1, 1, 4, 1, 3, 10,
+ 16, 16, 12, 1, 15, 2, 1, 1, 4, 177, 206, 265,
+ 282, 299, 304, 304, 308, 304, 307, 312, 314, 316, 258, 272,
+ 274, 272, 275, 280, 282, 274, 272, 274, 272, 303, 306, 274,
+ 317, -15776, -15775, -15774, -15773, -15772, -15771, -15770, -15769, -15768, -15767, -15766,
+ -15765, -15764, -15763, -15762, -15761, -15760, -15759, -15758, -15757, -15756, -15755, -15754,
+ -15753, -15752, 0, -15751, -15750, -15749, -15748, 0, 0, 0, -15747, -15746,
+ -15745, -15744, -15743, -15742, -15741, -15740, -15739, -15738, -15737, -15736, -15735, -15734,
+ -15733, -15732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 96,
+ -15731, -15730, -15729, -15728, -15727, -15726, -15725, -15724, -15723, -15722, -15721, -15720,
+ -15719, -15718, -15717, -15716, -15715, -15714, -15713, 73, 82, 97, -15712, -15711,
+ -15710, 67, 113, 114, 112, -15709, -15708, -15707, -15706, -15705, 0, 0,
+ -15704, -15703, 0, 0, 0, 0, -15701, -15700, -15699, -15698, 1, 1,
+ 9, 34, 35, 38, 49, 50, 49, 57, 56, 1, 4, 8,
+ 8, 22, 8, 8, 14, 16, 16, 20, 22, 4, 23, 44,
+ 24, 32, 2, 2, 15, 128, 128, 128, 128, 128, -15697, 128,
+ 128, 128, 128, 128, 128, -15696, -15694, -15693, 2, -15691, 3, 6,
+ 4, 128, 128, 128, 128, 128, -15690, -15689, -15688, 128, 4, 4,
+ 11, -15687, 8, -15686, 16, 2, 20, 1, 65, 67, 65, 2,
+ 68, 6, 110, 128, 128, 128, -15685, -15684, -15683, 0, 0, -15682,
+ -15681, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15680, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15678, -15674,
+ -15673, -15672, -15671, -15670, -15669, -15668, -15667, -15666, -15665, 9, 11, 47,
+ 16, 48, -15664, -15663, -15662, -15661, -15660, -15659, -15658, -15657, -15656, -15655,
+ -15654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15653, -15652,
+ -15651, -15650, -15649, -15648, -15647, -15646, -15645, -15644, -15643, -15642, 0, 0,
+ -15641, -15640, -15639, -15638, -15637, -15636, -15635, -15634, -15633, -15632, -15631, -15630,
+ -15629, -15628, -15627, -15622, -15618, -15616, -15614, -15613, -15612, -15610, -15609, -15597,
+ -15596, -15595, -15594, -15593, -15592, -15591, -15590, -15589, -15588, -15587, -15586, -15585,
+ -15584, -15583, -15582, -15581, -15580, -15579, 0, 0, 0, -15574, 0, 0,
+ 0, 0, -15573, -15572, -15570, -15569, -15568, -15567, -15566, -15565, -15564, -15563,
+ -15562, 48, 53, 151, 60, 146, 164, 56, 167, 13, 7, 148,
+ 96, 100, 160, 153, 164, 221, -15561, 325, 325, 241, 188, 184,
+ 189, 190, 338, -15560, 341, 322, 341, 358, 347, -15558, -15557, -15556,
+ -15555, -15548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -15547, -15546, -15543, -15542, -15541, 322, 322, 334, 334, 336, 336,
+ 336, -15540, -15538, -15537, 336, 135, 67, 79, 96, 126, 152, 152,
+ 156, 166, -15536, -15535, 186, 168, -15533, -15532, -15531, 0, -15530, -15529,
+ 3, 0, -15528, -15527, -15526, -15525, -15524, -15523, -15522, -15521, -15520, -15519,
+ -15518, 248, -15517, 0, 0, -15516, -15515, -15514, -15513, -15512, -15511, -15510,
+ -15509, -15508, -15507, -15506, -15505, -15504, -15503, -15502, -15501, -15500, -15499, -15494,
+ -15493, -15492, -15490, -15486, -15482, 0, 0, 0, -15476, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15474, -15472,
+ -15469, -15467, -15466, -15464, -15463, -15434, 0, 0, -15433, -15432, 0, 0,
+ 0, 0, -15430, -15429, -15427, 0, -15426, -15425, -15422, -15421, -15420, -15419,
+ -15416, -15414, -15401, -15399, -15397, -15390, 0, 0, 0, 0, 0, 0,
+ 0, 0, -15386, -15385, -15384, -15383, -15382, -15381, -15380, -15379, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -15378, -15377, -15376, -15375, -15374, -15373, -15372,
+ -15371, -15241, -15240, -15239, -15238, -15198, -15197, -15196, -15195, -15188, -15187, -15185,
+ -15178, -15177, -15176, -15175, -15174, -15173, -15172, -15171, -15170, -15169, -15168, -15167,
+ -15166, -15165, -15164, -15163, -15162, -15161, -15160, -15159, -15158, -15157, -15156, -15155,
+ -15154, -15153, -15152, -15151, -15150, -15149, -15148, -15147, -15146, -15145, -15144, -15143,
+ -15142, -15141, -15140, -15139, -15138, -15137, -15136, -15135, -15134, -15133, -15132, -15131,
+ -15130, -15129, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, -15128, -15127, -15126, 2, -15125, 1,
+ 2, 2, 1, 1, 2, 8, 10, -15124, -15123, 2, 2, 8,
+ 31, 2, -15122, 5, 29, 1, 32, 32, 32, 1, 1, -15121,
+ -15120, -15119, 1, -15118, -15117, -15116, -15115, -15114, -15113, -15112, -15111, -15110,
+ -15109, -15108, -15107, -15106, -15105, -15104, -15103, -15102, -15101, -15100, -15099, -15098,
+ -15097, -15096, -15095, -15094, -15093, -15092, -15091, -15090, -15089, -15088, -15087, -15086,
+ -15085, -15084, -15083, -15082, -15080, -15079, -15078, -15077, -15076, -15075, -15074, -15073,
+ -15072, -15071, -15070, -15069, -15068, -15067, -15066, -15065, -15064, -15063, -15062, -15061,
+ -15060, -15059, -15058, -15057, -15056, -15054, -15053, -15052, -15051, -15050, -15049, -15048,
+ -15047, -15046, -15045, -15044, -15043, -15042, -15041, -15040, -15039, -15038, -15037, -15036,
+ -15035, -15034, -15033, -15032, -15031, -15030, -15029, -15028, -15027, -15026, -15025, -15024,
+ -15023, -15022, -15021, -15020, -15018, -15016, -15015, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 24,
+ 24, 28, 28, 25, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 150, 160, 160, 160, 128, 128, 133,
+ 134, 128, 131, 136, 136, 128, 132, 192, 192, 144, 192, 219,
+ 221, 192, 208, 202, 226, 208, 237, -15013, -15011, -15010, 222, 224,
+ 224, 233, 234, 232, 235, 2, 4, -15009, 8, 56, 59, -15008,
+ -15007, -15006, -15005, -15004, -15003, -15002, -15001, -15000, -14999, -14998, -14997, -14995,
+ -14994, -14993, -14992, -14987, -14986, -14975, -14973, -14972, -14970, -14967, -14925, -14924,
+ -14923, -14922, -14921, -14920, -14919, -14918, -14917, -14916, -14915, -14914, -14913, -14912,
+ -14911, -14910, -14909, -14908, -14907, -14906, -14905, -14904, -14903, -14902, -14900, -14899,
+ -14898, -14897, -14896, -14895, -14894, -14893, -14892, -14891, -14890, -14889, -14888, -14887,
+ -14886, -14885, -14884, -14883, -14882, -14881, -14880, -14879, -14878, -14877, -14875, -14874,
+ -14873, -14872, -14871, -14870, -14869, -14868, -14867, -14866, -14865, -14864, -14863, -14862,
+ -14861, -14860, -14859, -14858, -14857, -14856, -14855, -14854, -14853, -14852, -14851, -14850,
+ -14849, -14848, -14847, -14846, -14845, -14844, -14843, -14842, -14841, -14840, -14839, -14838,
+ -14837, -14836, -14835, -14834, -14833, -14832, -14831, -14830, -13567, -13566, -13529, -13528,
+ -13527, -13526, -13525, -13524, -13523, -13522, -13521, -13520, -13519, 0, 0, -13518,
+ -13517, 0, 0, 0, 0, -13516, -13515, -13514, -13513, -13512, -13511, -13510,
+ -13509, -13508, -13507, -13506, -13505, -13504, -13503, -13502, -13501, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -13500, -13499, -13498,
+ -13497, -13496, -13495, -13494, -13493, -13492, -13491, -13490, -13489, -13488, -13487, -13486,
+ -13485, -13484, -13483, -13482, -13481, -13480, -13479, -13478, -13477, -13476, -13475, -13474,
+ -13473, -13469, -13468, 5, 13, 1, 1, 4, 1, 1, 1, 1,
+ 4, 1, 1, 4, 16, 1, 1, 1, 4, 1, 1, 4,
+ 1, 1, 1, 1, 38, 1, 1, 4, 1, 1, 1, 1,
+ 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 60, 76, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 42, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1,
+ 1, 8, 8, 1, 1, 1, 1, 1, 1, 55, 95, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1,
+ 8, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1,
+ 48, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 16, 1, 3, 16, 30, 1, 1, 2, 6,
+ 1, 1, 2, 14, 1, 1, 2, 6, 46, 3, 438, 658,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 4, 4, 1, 1, 8, 8, 1,
+ 1, 1, 1, 1, 1, 32, 48, 96, 96, 10, 16, 22,
+ 96, 96, 96, 96, 101, 96, 96, 97, 112, 96, 96, 96,
+ 96, 100, 100, 96, 96, 104, 104, 96, 96, 96, 96, 96,
+ 552, 124, 124, 68, 557, 519, 520, 522, 525, 557, 558, 556,
+ 577, 600, 768, 768, 768, 768, 768, 768, 768, 769, 772, 768,
+ 768, 768, 776, 768, 768, 768, 768, 768, 768, 768, 789, 768,
+ 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768,
+ 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768,
+ 768, 768, 768, 768, 768, 768, 768, 768, 768, -13467, -13464, -13463,
+ -13462, -13461, -13460, -13459, -13458, -13457, -13456, -13455, -13454, -13453, -13450, -13448,
+ -13447, -13446, -13444, -13443, -13442, -13441, -13440, -13439, -13438, -13437, -13436, -13435,
+ -13434, -13433, -13430, -13429, -13428, -13427, -13422, -13420, -13419, -13418, -13416, -13415,
+ -13413, -13412, -13411, -13409, -13407, -13402, -13400, -13396, -13394, -13392, -13391, -13390,
+ -13389, -13388, -13387, -13386, -13385, -13384, -13383, -13382, -13381, -13380, -13379, -13378,
+ -13377, -13367, -13364, -13363, -13361, -13356, -13355, -13354, -13352, -13349, -13347, -13344,
+ -13343, -13342, -13341, -13340, -13339, -13338, -13337, -13336, -13335, -13334, -13333, -13332,
+ -13331, -13330, -13329, -13328, 92, 94, 283, 289, 933, 935, 939, 941,
+ 947, 952, 952, 952, 952, 1051, 1017, 952, -13327, -13326, -13325, -13324,
+ -13323, -13322, -13321, -13320, -13319, -13318, -13317, -13316, -13315, -13314, -13313, -12052,
+ 1012, 1016, 1015, 915, 918, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 514, 1, 1, 1,
+ 1, 515, 517, 514, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 1, 16, -12051, -12050, -12049, -12048,
+ 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 15, 35,
+ 57, 3, 4, 2, -12047, -12046, -12045, -12044, -12043, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -12042, -12041, -12040, -12039, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -12038, -12037, -12036, -12035, -12034, -12033, -12032, -12031, -12030, -12029, -12028,
+ -12027, -12026, -12025, -12024, -12023, -12022, -12021, -12020, -12019, -12018, -12017, -12016,
+ -12015, -12014, -12013, -12012, -12011, -12010, -12009, -12008, -12007, -12006, -12005, -12004,
+ -12003, -12002, -12001, -12000, -11999, -11998, -11997, -11996, -11995, -11994, -11993, -11992,
+ -11991, -11990, -11989, -11988, -11987, -11986, -11985, -11984, -11983, -11982, -11981, -11980,
+ -11979, -11978, -11977, -11976, -11975, -11974, -11973, -11972, -11971, -11970, -11969, -11968,
+ -11967, -11966, -11965, -11964, -11963, -11962, -11961, -11960, -11959, -11958, -11957, -11956,
+ -11955, -11954, -11953, -11952, -11951, -11950, -11949, -11948, -11947, -11946, -11945, -11944,
+ -11943, -11942, -11941, -11940, -11939, -11938, -11937, -11936, -11935, -11934, -11933, -11932,
+ -11931, -11930, -11929, -11928, -11927, -11926, -11925, -11924, -11923, -11922, -11921, -11920,
+ -11919, -11918, -11917, -11916, -11915, -11914, -11913, -11912, -11911, -11910, -11909, -11908,
+ -11907, -11906, -11905, -11904, -11903, -11902, -11901, -11900, -11899, -11898, -11897, -11896,
+ -11895, -11894, -11893, -11892, -11891, -11890, -11889, -11888, -11887, -11886, -11885, -11884,
+ -11883, -11882, -11881, -11880, -11879, -11878, -11877, -11876, -11875, -11874, -11873, -11872,
+ -11871, -11870, -11869, -11868, -11867, -11866, -11865, -11864, -11863, -11862, -11861, -11860,
+ -11859, -11858, -11857, -11856, -11855, -11854, -11853, -11852, -11851, -11850, -11849, -11848,
+ -11847, -11846, -11845, -11844, -11843, -11842, -11841, -11840, -11839, -11838, -11837, -11836,
+ -11835, -11834, -11833, -11832, -11831, -11830, -11829, -11828, -11827, -11826, -11825, -11824,
+ -11823, -11822, -11821, -11820, -11819, -11818, -11817, -11816, -11815, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -11814, -11813, -11812, -11811, -11810, -11809, -11808, -11807, -11806, -11805, -11804,
+ -11803, 0, -11802, -11801, -11800, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11799,
+ -11798, -11797, -11796, -11795, -11794, -11793, -11792, -11791, -11790, -11789, -11788, 0,
+ 0, -11787, -11786, -11785, -11784, -11783, -11782, -11781, -11780, -11779, -11778, -11777,
+ -11776, -11775, -11774, -11773, -11772, -11771, -11770, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -11769, -11768, -11767,
+ -11766, -11765, -11764, -11763, -11762, -11761, -11760, -11759, -11758, -11757, -11756, -11755,
+ -11754, -11753, -11752, -11751, -11750, -11749, -11748, -11747, -11746, -11745, -11744, -11743,
+ -11741, -11740, -11739, -11738, -11737, -11736, -11735, -11734, -11733, -11732, -11731, -11730,
+ -11729, -11727, -11719, -11712, -11711, -11710, -11709, -11708, -11707, -11706, -11705, -11704,
+ -11703, -11702, -11701, -11700, -11699, -11698, -11697, -11696, -11695, -11694, -11693, -11692,
+ -11691, -11690, -11689, -11688, -11687, -11686, -11685, -11684, -11683, -11682, -11681, -11680,
+ -11679, -11678, -11677, -11676, -11675, -11674, -11673, -11672, -11671, -11670, -11669, -11668,
+ -11667, -11666, -11665, -11664, -11663, -11662, -11661, -11660, -11659, -11658, -11657, -11656,
+ -11655, -11654, -11653, -11652, -11651, -11650, -11649, -11648, -11647, -11646, -11645, -11644,
+ -11643, -11642, -11641, -11640, -11639, -11638, -11637, -11636, -11635, -11634, -11633, -11632,
+ -11631, -11630, -11629, -11628, -11627, -11626, -11625, -11624, -11623, -11622, -11621, -11620,
+ -11619, -11618, -11617, -11616, -11615, -11613, -11612, -11611, -11610, -11609, -11608, -11607,
+ -11606, -11605, -11604, -11603, -11602, -11601, -11584, -11583, -11582, -11581, -11579, -11578,
+ -11574, -11568, -11567, -11566, -11565, -11564, -11563, -11562, -11561, -11560, -11559, -11558,
+ -11557, -11556, -11555, -11554, -11553, -11552, -11551, -11550, -11549, -11546, -11542, -11536,
+ -11535, -11533, -11532, -11531, -11530, -11529, -11528, -11527, -11526, -11525, -11524, -11523,
+ -11522, -11521, -11520, -11519, -11518, -11517, -11516, -11515, -11514, -11513, -11512, -11511,
+ -11510, -11509, -11508, -11507, -11506, -11505, -11504, -11503, -11502, -11501, -11500, -11499,
+ -11498, -11497, -11496, -11495, -11494, -11493, -11492, -11491, -11490, -11489, -11488, -11487,
+ -11486, -11485, -11484, -11483, -11482, -11481, -11480, -11479, -11478, -11477, -11476, -11475,
+ -11474, -11473, -11472, -11471, -11470, -11469, -11468, -11467, -11466, -11465, -11464, -11463,
+ -11462, -11461, -11460, -11459, -11458, -11457, -11456, -11455, -11454, -11453, -11452, -11451,
+ -11450, -11449, -11448, -11447, -11446, -11444, -11443, -11442, -11441, -11440, -11439, -11438,
+ -11437, -11436, -11435, -11434, -11433, -11432, -11431, -11430, -11429, -11428, -11427, -11426,
+ -11425, -11408, -11407, -11406, -11405, -11403, -11402, -11398, -11392, -11391, -11390, -11389,
+ -11388, -11387, -11386, -11385, -11384, -11383, -11382, -11381, -11380, -11379, -11378, -11377,
+ -11376, -11375, -11374, -11373, -11372, -11371, -11370, -11369, -11368, -11367, -11366, -11365,
+ -11364, -11363, -11362, -11361, -11360, -11359, -11358, -11357, -11356, -11355, -11354, -11353,
+ -11352, -11351, -11350, -11349, -11348, -11347, -11346, -11345, -11344, -11343, -11342, -11341,
+ -11340, -11339, -11338, -11337, -11336, -11335, -11334, -11333, -11332, -11331, -11330, -11329,
+ -11328, -11327, -11326, -11325, -11324, -11323, -11322, -11321, -11320, -11319, -11318, -11317,
+ -11316, -11315, -11314, -11313, -11312, -11311, -11310, -11309, -11308, -11307, -11306, -11305,
+ -11304, -11303, -11302, -11301, -11300, -11299, -11298, -11297, -11296, -11295, -11294, -11293,
+ -11292, -11291, -11290, -11279, -11278, -11277, -11276, -11275, -11274, -11273, -11272, -11271,
+ -11270, -11269, -11268, -11267, -11266, -11265, -11264, -11263, -11262, -11261, -11260, -11258,
+ -11250, -11247, -11239, -11231, -11230, -11229, -11228, -11227, -11226, -11225, -11224, -11223,
+ -11222, -11221, -11220, -11219, -11217, -11216, -11215, -11214, -11213, -11212, -11211, -11210,
+ -11209, -11208, -11207, -11206, -11205, -11204, -11203, -11202, -11201, -11200, -11199, -11198,
+ -11197, -11196, -11195, -11194, -11193, -11192, -11191, -11190, -11189, -11188, -11187, -11186,
+ -11185, -11184, -11183, -11182, -11181, -11180, -11179, -11178, -11167, -11166, -11165, -11164,
+ -11163, -11162, -11161, -11160, -11159, -11158, -11156, -11155, -11154, -11153, -11152, -11151,
+ -11150, -11149, -11148, -11147, -11146, -11145, -11144, -11143, -11142, -11141, -11140, -11139,
+ -11138, -11137, -11136, -11122, -11103, -11102, -11101, -11100, -11099, -11098, -11097, -11096,
+ -11095, -11094, -11093, -11092, -11091, -11089, -11088, -11087, -11086, -11085, -11084, -11083,
+ -11082, -11081, -11080, -11079, -11078, -11077, -11076, -11075, -11074, -11073, -11072, -11071,
+ -11070, -11069, -11068, -11067, -11066, -11065, -11064, -11063, -11062, -11061, -11060, -11059,
+ -11058, -11057, -11056, -11055, -11054, -11053, -11052, -11051, -11050, -11049, -11048, -11047,
+ -11046, -11045, -11044, -11043, -11042, -11041, -11040, -11039, -11038, -11037, -11036, -11035,
+ -11034, -11033, -11032, -11031, -11030, -11029, -11028, -11027, -11026, -11025, -11024, -11023,
+ -11022, -11021, -11020, -11019, -11018, -11017, -11016, -11015, -11014, -11013, -11012, -11011,
+ -11010, -11009, -11008, -11007, -11006, -11005, -11004, -11003, -11002, -11001, -11000, -10999,
+ -10998, -10997, -10996, -10995, -10994, -10993, -10992, -10987, -10986, -10983, -10982, -10981,
+ -10980, -10979, -10978, -10977, -10976, -10964, -10959, -10958, -10957, -10956, -10955, -10954,
+ -10953, -10952, -10951, -10950, -10949, -10948, -10947, -10946, -10945, -10944, -10943, -10942,
+ -10941, -10940, -10939, -10938, -10937, -10936, -10935, -10934, -10933, -10932, -10931, -10930,
+ -10929, -10928, -10927, -10926, -10925, -10924, -10923, -10922, -10921, -10920, -10919, -10918,
+ -10917, -10916, -10915, -10914, -10913, -10912, -10911, -10910, -10909, -10908, -10907, -10906,
+ -10905, -10904, -10903, -10902, -10901, -10900, -10899, -10898, -10897, -10896, -10895, -10894,
+ -10893, -10892, -10891, -10890, -10889, -10888, -10887, -10886, -10885, -10884, -10883, -10882,
+ -10881, -10880, -10879, -10878, -10877, -10876, -10875, -10874, -10873, -10872, -10871, -10870,
+ -10869, -10868, -10867, -10866, -10865, -10864, -10863, -10862, -10861, -10860, -10859, -10858,
+ -10857, -10856, -10855, -10854, -10853, -10852, -10851, -10850, -10849, -10848, -10847, -10846,
+ -10845, -10844, -10843, -10842, -10841, -10840, -10839, -10838, -10837, -10836, -10835, -10834,
+ -10833, -10832, -10831, -10830, -10829, -10828, -10827, -10826, -10825, -10824, -10823, -10822,
+ -10821, -10820, -10819, -10818, -10817, -10816, -10811, -10807, -10806, -10805, -10804, -10803,
+ -10802, -10801, -10800, -10799, -10798, -10797, -10796, -10795, -10794, -10790, -10788, -10783,
+ -10782, -10781, -10780, -10779, -10778, -10777, -10776, -10771, -10770, -10769, -10703, -10702,
+ -10701, -10700, -10699, -10698, -10695, -10694, -10693, -10692, -10689, -10688, -10683, -10682,
+ -10681, -10680, -10679, -10678, -10677, -10676, -10675, -10674, -10673, -10672, -10671, -10670,
+ -10669, -10668, -10667, -10666, -10665, -10664, -10663, -10662, -10661, -10660, -10659, -10658,
+ -10657, -10656, -10655, -10654, -10653, -10652, -10651, -10650, -10649, -10648, -10647, -10646,
+ -10645, -10644, -10643, -10642, -10641, -10640, -10639, -10638, -10637, -10636, -10635, -10634,
+ -10633, -10632, -10631, -10630, -10629, -10628, -10627, -10626, -10625, -10624, -10623, -10622,
+ -10621, -10620, -10619, -10618, -10617, -10616, -10615, -10614, -10613, -10612, -10611, -10610,
+ -10609, -10608, -10607, -10606, -10605, -10604, -10601, -10600, -10591, -10590, -10589, -10588,
+ -10587, -10586, -10585, -10584, -10583, -10581, -10580, -10579, -10578, -10577, -10576, -10575,
+ -10574, -10573, -10572, -10571, -10570, -10553, -10552, -10550, -10549, -10547, -10545, -10544,
+ -10543, -10542, -10539, -10538, -10537, -10536, -10535, -10534, -10533, -10532, -10531, -10530,
+ -10529, -10528, -10527, -10526, -10525, -10524, -10523, -10522, -10518, -10489, -10488, -10487,
+ -10486, -10485, -10484, -10483, -10482, -10479, -10478, -10477, -10476, -10475, -10474, -10471,
+ -10470, -10469, -10468, -10465, -10464, -10463, -10462, -10459, -10458, -10457, -10456, -10455,
+ -10454, -10453, -10452, -10451, -10450, -10449, -10448, -10447, -10446, -10445, -10444, -10443,
+ -10442, -10441, -10440, -10439, -10438, -10437, -10436, -10435, -10434, -10433, -10432, -10431,
+ -10430, -10429, -10428, -10427, -10426, -10425, -10424, -10423, -10422, -10421, -10420, -10419,
+ -10418, -10417, -10416, -10415, -10414, -10413, -10412, -10411, -10410, -10409, -10408, -10407,
+ -10406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -10405, -10404, -10403, -10402, -10401, -10400, -10399, -10398, -10397, -10396, -10395,
+ -10394, -10393, -10392, -10391, -10390, -10389, -10388, -10387, -10386, -10385, -10384, -10383,
+ -10382, -10381, -10380, -10379, -10378, -10377, -10376, -10375, -10374, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -10373, -10372, -10371, -10370, -10369, -10368, -10367, -10366, -10365, -10364, -10363,
+ -10362, 0, -10361, -10360, -10359, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -10358, -10357, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10356,
+ -10355, -10354, -10353, -10352, -10351, -10350, -10349, -10348, -10347, -10346, -10345, -10344,
+ -10343, -10342, -10341, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, -10340, -10339, -10338, -10337, -10336,
+ -10335, -10334, -10333, -10332, -10331, -10330, -10329, -10328, -10327, -10326, -10325, -10324,
+ -10323, -10322, -10321, -10320, -10319, -10317, -10316, -10315, -10314, -10313, -10312, -10311,
+ -10310, -10309, -10308, -10307, -10306, -10305, -10304, -10303, -10302, -10301, -10300, -10299,
+ -10298, -10297, -10296, -10295, -10294, -10293, -10292, -10291, -10290, -10289, -10288, -10287,
+ -10286, -10285, -10284, -10283, -10282, -10281, -10280, -10279, -10278, -10277, -10276, -10275,
+ -10274, -10273, -10272, -10271, -10270, -10269, -10268, -10267, -10266, -10265, -10264, -10263,
+ -10262, -10261, -10260, -10259, -10258, -10257, -10256, -10255, -10254, -10253, -10252, -10251,
+ -10250, -10249, -10248, -10247, -10246, -10245, -10244, -10243, -10242, -10241, -10240, -10239,
+ -10238, -10237, -10236, -10235, -10234, -10233, -10232, -10231, -10230, -10229, -10228, -10227,
+ -10226, -10225, -10224, -10223, -10222, -10221, -10220, -10219, -10218, -10217, -10216, -10215,
+ -10214, -10213, -10212, -10211, -10210, -10209, -10208, -10207, -10206, 0, -10205, -10204,
+ -10203, -10202, -10201, -10200, -10199, 0, -10198, -10197, -10195, -10194, -10193, -10192,
+ 0, -10191, -10190, 0, -10189, -10188, -10187, -10186, -10185, -10184, 0, -10183,
+ -10182, -10181, -10180, -10179, -10178, -10177, -10176, -10175, 0, -10174, -10173, 0,
+ -10171, -10170, -10169, -10168, -10167, -10165, -10164, -10162, -10161, -10160, -10159, -10158,
+ -10157, -10156, -10155, -10154, -10153, -10152, -10151, -10150, -10149, 0, -10148, -10147,
+ -10146, -10145, -10144, -10143, -10142, -10141, -10140, -10139, -10138, -10137, -10136, -10135,
+ -10134, -10133, -10130, 0, -10126, 0, -10102, -10101, -10100, 0, 0, -10099,
+ -10098, -10097, -10096, -10095, -10094, -10093, -10092, -10091, -10090, -10089, -10088, -10087,
+ -10086, -10085, -10084, -10083, -10082, -10081, -10080, -10079, -10078, -10077, -10076, -10075,
+ -10074, -10073, -10072, -10071, -10070, -10069, -10068, -10067, -10066, -10065, -10064, -10063,
+ -10062, -10061, -10060, -10059, -10058, -10057, -10056, -10055, -10054, -10053, -10052, -10051,
+ -10050, 0, -10049, -10048, -10047, -10046, -10045, -10044, -10043, -10042, -10041, -10040,
+ -10039, -10038, -10037, -10036, -10035, -10034, -10033, -10032, -10031, -10030, -10029, -10028,
+ -10027, -10026, -10025, -10024, 0, -10023, -10022, -10021, -10020, -10019, 0, 0,
+ -10018, 0, 0, 0, -10017, -10016, 0, -10015, -10014, -10013, 0, -10012,
+ -10011, 0, -10010, -10009, -10008, -10007, -10006, -10005, -10004, -10003, -10002, -10001,
+ -10000, -9999, -9998, -9997, -9996, -9995, -9994, -9993, -9992, -9991, -9990, -9989,
+ -9988, -9987, 0, -9986, -9985, -9984, -9983, -9982, -9981, -9980, -9979, -9978,
+ -9977, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, -9976, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, -9975, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, -9974, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -9973,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, -9972, -9971, 1, 1, -9969, -9968, -9967, -9966, -9965, -9964, -9963,
+ -9962, -9961, -9960, -9959, -9958, -9957, -9956, -9955, -9954, -9953, -9952, -9939,
+ -9938, -9937, -9936, -9935, -9934, -9933, -9932, -9931, -9930, -9929, -9928, -9927,
+ -9925, 73, 96, -9922, -9921, 0, -9920, 96, -9919, -9918, 96, 96,
+ -9917, -9916, 96, 96, 96, -9915, -9914, -9913, -9912, -9911, -9910, -9909,
+ -9908, -9907, 96, -9906, -9905, -9904, -9890, -9887, -9886, 64, 66, 64,
+ 66, 0, 65, 65, 73, 64, 69, 65, 80, 80, 80, 68,
+ 70, 68, 70, 72, 76, 76, 140, 64, 162, 192, 192, 192,
+ 192, 192, 192, 37, 144, 156, 156, 160, 160, -9885, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 178, 160, 160, 160,
+ 160, 160, 160, 160, 160, 184, 189, -9884, 512, 512, 512, 145,
+ 512, -9883, -9882, -9881, -9880, -9879, -9878, -9877, -9876, -9875, -9874, -9873,
+ -9872, -9861, -9860, -9859, -9858, -9857, -9856, -9855, -9854, -9853, -9852, -9851,
+ -9850, -9849, -9848, 0, -9847, -9846, -9845, -9844, -9839, 29, 64, 70,
+ 72, 128, 128, 55, 128, -9838, -9837, 128, 137, -9836, -9835, -9834,
+ -9833, -9832, -9831, -9830, -9829, -9828, -9827, -9826, -9825, -9824, -9811, -9810,
+ -9809, -9808, -9807, -9806, -9805, 128, 137, 129, 134, 144, 144, 144,
+ 144, -9804, 164, 161, 163, -9803, -9802, -9801, -9800, 161, 162, -9799,
+ 0, 160, 160, 132, 132, 160, 160, 160, 164, 160, 160, 134,
+ 148, 133, 145, 128, 128, 244, 244, -9798, 149, -9797, 652, 128,
+ 135, -9796, -9795, -9794, -9793, -9792, 770, 192, -9791, 768, 768, 768,
+ 768, 768, 772, 252, 768, 768, 771, 784, 784, 175, 183, 229,
+ 230, 228, 250, -9790, 829, 785, 830, 896, 896, 896, 896, 906,
+ 906, -9789, -9788, -9787, -9786, -9785, 901, -9784, -9783, -9782, 928, 904,
+ 904, 930, 933, -9781, 769, 805, 814, 896, 896, 896, 896, 906,
+ 912, 901, 924, 896, 896, 920, 941, 936, 936, 942, -9780, 896,
+ 946, 939, 984, 901, 977, 980, 1024, 985, 1024, 1024, 1024, 998,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, -9779, 900, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1024, 1024, -9778, -9777, -9776, -9775, -9774, -9773, -9772,
+ -9771, -9770, -9769, -9768, -9767, -9766, -9765, -9764, -9763, -9762, -9761, -9760,
+ -9759, -9758, -9757, -9756, -9755, -9754, -9753, -9752, -9751, -9750, -9749, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -9748, -9747, -9746, -9745, -9744, -9743, 0,
+ 0, -9742, 0, 0, 0, -9741, 0, -9740, -9739, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -9738, -9737, -9736, -9735, -9734, -9733, -9732, -9731, -9730, -9729, -9728,
+ -9727, -9726, -9725, -9724, -9723, -9722, -9721, -9720, -9719, -9718, -9717, -9716,
+ -9715, -9714, -9713, -9712, -9711, -9710, -9709, -9708, -9707, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, -9706, -9705, -9704, -9703, -9702, -9701, -9700, -9699, -9698, -9697, -9696,
+ -9695, -9694, -9693, -9692, -9691, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -9690, -9689, -9688,
+ -9687, -9686, -9685, -9684, -9683, -9682, -9681, 134, 134, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192, 197, 224, 224, 212,
+ 212, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 256, 256, 128, 128, 128, 128, 128,
+ 128, 128, 257, 128, 128, 128, 128, 256, 256, 256, 256, 264,
+ 268, 256, 256, 256, 273, 270, 276, 286, 286, 257, 288, 288,
+ 288, 292, 296, 288, 288, -9680, -9679, -9678, -9677, -9676, -9675, -9674,
+ -9673, -9672, -9671, -9670, -9669, -9668, -9667, -9666, -9665, 2, 2, 2,
+ 2, 2, 2, 2, 2, -9664, -9663, -9662, -9661, -9660, -9659, -9658,
+ -9657, -9656, -9655, -9654, -9653, -9652, -9651, -9650, -9649, -9648, -9647, -9646,
+ -9645, -9644, -9643, -9642, -9641, -9640, -9639, -9638, -9637, -9636, -9635, -9634,
+ -9633, -9632, -9631, -9630, -9629, -9628, -9627, -9626, -9625, 34, 34, 40,
+ 40, 40, 40, 48, 48, 60, 60, 27, 48, 48, 48, 49,
+ 60, -9624, -9623, -9622, -9621, -9620, -9619, -9618, -9617, -9616, -9615, -9614,
+ -9613, -9612, -9611, -9610, -9609, -9608, 32, 32, 35, -9607, -9606, -9605,
+ -9604, -9603, -9601, -9600, -9599, -9598, -9597, -9596, -9595, 16, 24, 19,
+ 20, 106, 106, 16, 19, -9594, 130, 128, 132, -9593, -9592, -9591,
+ -9590, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 1,
+ 1, 1, 1, 1, 1, 8, 8, 14, 14, 16, 16, 16,
+ 16, 6, 6, 26, 26, 30, 30, 32, 32, 1, 1, 1,
+ -9589, 2, 8, 2, 2, 10, 14, 1, 1, 4, 1, 1,
+ 1, 1, 4, 1, 1, 4, 1, 1, 1, 1, 4, 1,
+ 1, 4, 1, 72, 72, 1, 4, 1, 1, -9588, 1, 1,
+ 1, -9587, -9586, -9585, -9584, -9583, -9582, -9581, -9580, 1, 1, 1,
+ 1, 1, 1, 1, 1, 16, 1, 7, 16, 16, 16, 16,
+ 16, 9, 14, 34, 1, 45, 47, 57, 130, 51, 53, 25,
+ 26, 20, 29, 128, 128, 89, 128, 6, -9579, 1, 27, 44,
+ 127, 128, 128, 128, 133, 140, 143, 150, 160, 131, 145, 148,
+ 148, 154, 161, 167, 204, 194, 234, 512, 512, 480, 516, 512,
+ 512, 0, -9578, 460, 512, -9577, -9576, -9575, -9574, 512, 512, -9573,
+ -9572, 512, 512, 520, 520, 512, 512, 528, 530, 457, 529, 528,
+ 528, 536, 545, 512, 512, 512, 512, 512, 512, 520, 520, 513,
+ 526, 528, 528, 522, 528, 514, 514, 516, 516, 538, 598, 523,
+ 593, 512, 512, 443, 512, 514, 519, 524, 524, 524, 524, 514,
+ 514, 514, 514, 514, 514, 552, 552, 533, 544, 544, 544, 544,
+ 544, 550, 640, 512, 514, 512, 517, 513, 514, 520, 520, 512,
+ 512, 624, 640, 512, 640, 640, 640, 640, 640, 648, 652, 648,
+ 656, 640, 640, 645, 653, 674, 677, 673, 680, 645, 665, 672,
+ 680, 646, 673, 684, 689, 127, 644, 723, 724, 648, 679, 722,
+ 722, 683, 729, 27, 896, 896, 896, 896, 896, 896, 896, 896,
+ 900, 896, 896, 896, 909, 896, 896, 897, 901, 896, 896, 909,
+ 929, 896, 896, 896, 900, 896, 896, 896, 909, 896, 896, 897,
+ 900, 896, 896, 896, 908, 896, 896, 896, 900, 896, 896, 896,
+ 909, 896, 988, 905, 1097, 1086, 1112, 1792, 1792, 960, 960, 960,
+ 960, 960, 960, 961, 975, 961, 1121, 1792, 1792, 1792, 1792, 1792,
+ 1792, 1792, 1792, 1792, 1792, 1792, 1808, 1792, 1792, 1808, 1808, 1819,
+ 1823, 1856, 1856, 1856, 1856, 902, 999, 1112, 1824, 1826, 1829, 1825,
+ 1856, 1834, 1856, 1856, 1856, 1856, 1856, 1856, 1865, 1856, 1856, 1856,
+ 1856, 1856, 1856, 1857, 1874, 1856, 1856, 1856, 1856, 1856, 1856, 1892,
+ 1892, 10, 129, 129, 133, 27, 128, 130, 138, 129, 133, 128,
+ 128, 139, 143, 148, 148, 130, 130, 130, 130, 130, 137, 129,
+ 130, 128, 160, 164, 164, 129, 161, 176, 176, -9571, -9570, 182,
+ -9569, -9568, -9562, -9558, -9557, -9555, -9554, -9553, -9552, -9551, -9550, -9549,
+ -9548, 141, 152, 148, 148, -9547, -9545, 202, 202, -9544, -9543, -9542,
+ -9541, -9540, -9539, -9538, -9537, 136, 140, 130, 148, 152, 156, 144,
+ 389, 152, 384, 128, 128, 136, 136, 136, 136, 136, 142, 140,
+ 170, 137, 171, 174, 176, 404, 448, 152, 164, 157, 449, 448,
+ 448, -9536, -9535, -9534, -9533, -9532, -9531, -9530, -9529, -9528, -9527, -9526,
+ -9525, -9524, -9523, -9522, -9521, 449, 453, 144, 430, 144, 144, 460,
+ 460, -9520, 472, 452, 452, -9519, -9518, -9517, -9516, 492, 492, -9515,
+ 497, 507, 510, 502, 509, 487, 504, 325, 404, 64, 1030, 400,
+ 1025, -9514, -9512, -9511, -9510, -9509, -9508, -9507, -9506, -9505, -9504, -9503,
+ -9502, -9501, -9500, -9499, -9498, -9497, -9496, -9495, -9494, -9493, -9492, -9491,
+ -9490, -9489, -9488, -9487, -9486, -9485, -9484, -9483, -9482, 445, 1045, 1040,
+ 1042, 432, 1046, 1046, 1056, 1056, 1056, 1042, 1064, 1064, 1080, 1084,
+ 1084, 414, 1095, 1, 1090, 407, 1089, 1089, 1096, 1088, 1088, 1098,
+ 1152, 1152, 1152, 1152, 1152, -9481, -9480, -9479, -9478, -9477, -9476, -9475,
+ -9474, -9473, -9470, -9460, -9459, 1152, 1152, 1153, -9457, 1136, 1136, 1136,
+ 1141, 1129, 1136, 1168, 1168, 1153, 1158, 1177, 1185, 1188, 1188, 1194,
+ 1197, 1152, 1152, 1144, 1151, 1152, 1152, 1156, 1160, 1154, 1154, 1222,
+ 1222, 1188, 1188, 1237, 1241, 1296, 1298, 1301, 1304, 1296, 1311, 1315,
+ 1316, 1309, 1311, 189, 1305, 128, 135, 1311, 1323, 153, 177, 171,
+ 1322, 1324, 1344, 1360, 1360, 188, 2051, 1338, 1338, 2071, 2096, 2105,
+ 2168, 2057, 2172, 164, 2176, 2176, 2176, 2189, 2190, 2176, 2198, 2180,
+ 2186, 2188, 2208, 2208, 2208, 2177, 2186, 2178, 2233, 2240, 2242, 2244,
+ 2248, 2254, 2260, 2240, 2248, 2224, 2246, 2261, 2282, 2287, 2295, 2306,
+ 2306, -9456, -9455, 2304, -9453, -9452, -9451, -9450, -9449, -9448, -9447, -9446,
+ -9445, 2192, 2197, 2187, 2190, 2187, 2217, 2192, 2229, 2321, 2325, 2304,
+ 2304, 2192, 2237, 2317, 2336, 2309, 2351, 2356, 2359, 2368, 2368, 2368,
+ 2372, 2368, 2368, 2368, 2368, 2368, -9444, -9443, 2368, -9442, -9441, -9440,
+ -9439, -9438, -9437, -9436, -9435, -9434, -9433, -9432, -9431, 2368, 2370, -9430,
+ -9429, -9428, -9427, -9426, -9425, -9424, -9423, -9422, -9421, -9420, -9419, -9418,
+ -9417, -9416, -9415, -9414, -9413, -9412, -9411, -9410, -9409, -9408, -9407, -9406,
+ -9405, -9404, -9403, -9402, -9401, -9400, -9399, -9398, -9397, 36, 42, 63,
+ 138, 140, 162, 160, 245, 2066, 2124, 2135, 2144, 2176, 2182, 2184,
+ 2186, 938, 2176, 2176, 2176, 2176, 2176, 2177, 2187, 2190, 2202, 2176,
+ 2178, 2188, 2209, 2179, 2203, -9396, -9395, -9394, -9393, -9392, -9391, -9390,
+ -9389, -9388, -9387, -9386, -9385, -9384, -9383, -9382, -9381, 2180, 2186, 2183,
+ -9380, 2246, 2252, 2254, 2257, -9379, 2179, 2259, 2260, -9378, -9377, -9376,
+ -9375, 2242, 2275, 2282, -9374, 2304, 2306, 2282, 2309, 2277, 2279, 2304,
+ 2304, 2304, 2308, 2317, 2319, 2304, 2306, 2304, 2309, 2313, 2333, 2312,
+ 2336, -9373, -9372, 2307, 2308, 2304, 2336, -9371, -9370, 4, -9369, -9368,
+ 4, 1, 8, 8, 8, 1, 1, 1, 1, 22, 1, 21,
+ 23, -9367, -9366, -9365, 1, 1, 1, 1, -9364, 8, 8, 9,
+ 13, 35, -9363, -9362, 40, -9361, 8, -9360, 2, 4, 1, -9359,
+ -9358, -9357, -9356, 1, 1, -9355, -9354, 2, -9353, 2, 2, 4,
+ 22, 25, 27, 30, 64, 68, 72, -9352, 28, 73, 77, 80,
+ 80, -9351, -9350, -9349, -9348, -9347, -9346, -9345, -9342, -9332, -9331, -9329,
+ -9320, 6, -9317, 5, 9, -9316, -9315, -9313, -9312, -9311, -9310, -9309,
+ -9308, -9307, -9306, -9305, -9304, -9303, 2, -9302, -9301, -9300, -9299, 10,
+ 10, 15, 33, 36, 49, -9298, -9297, 42, 42, -9296, -9295, -9294,
+ 49, -9293, -9292, 32, 32, 36, 36, -9291, -9290, 35, 44, 45,
+ 47, 136, 138, 132, 132, 1, 1, 1, 4, 6, 8, 3,
+ 8, 12, 15, -9289, -9288, -9287, -9286, -9285, -9284, 0, 0, 0,
+ 0, -9283, -9282, -9281, -9280, -9279, -9278, 6, 6, 8, 8, 16,
+ 19, 8, 11, 1, 1, 16, 16, -9277, -9276, 0, -9275, -9274,
+ -9273, 0, 0, -9272, 0, -9271, -9270, -9269, -9268, -9267, -9266, -9265,
+ -9264, -9263, -9262, -9261, -9260, -9259, -9258, -9257, -9256, 0, 0, 0,
+ -9255, 0, 0, 0, 0, -9254, -9253, 15, 16, 16, 16, 16,
+ 16, -9252, -9251, -9250, -9249, -9248, -9247, -9246, -9245, -9244, -9243, 0,
+ 0, 0, 0, 0, 0, -9242, -9241, 0, 0, -9240, -9239, -9238,
+ -9237, -9236, -9235, 2, 1, 1, 2, 2, 1, -9234, -9233, -9232,
+ -9231, -9230, -9229, 0, 0, -9228, -9227, 6, 6, 9, 12, 8,
+ 15, -9226, -9225, -9224, -9223, -9222, -9221, -9220, -9219, -9218, -9217, -9216,
+ -9215, -9214, -9213, -9212, -9211, -9210, -9209, -9208, -9207, -9206, -9205, -9204,
+ -9203, -9202, -9201, -9200, -9199, -9198, -9197, -9196, -9195, 124, 124, 116,
+ 116, 116, 116, -9194, 121, 156, 156, 69, 73, -9193, -9192, 152,
+ 152, 79, 130, 205, 244, 144, 204, 240, 385, 153, 193, 217,
+ 384, 385, 394, 388, 397, -9191, -9190, -9189, -9188, -9187, -9186, -9185,
+ -9184, -9183, -9182, -9181, -9180, -9179, -9178, -9177, -9176, -9175, -9174, -9173,
+ -9172, -9171, -9170, -9169, -9168, -9167, -9166, -9165, -9164, -9163, -9162, -9161,
+ -9160, -9159, -9158, -9157, -9156, -9155, -9154, -9153, -9152, -9151, -9150, -9149,
+ -9148, -9147, -9146, -9145, -9144, -9143, -9142, -9141, -9140, -9139, -9138, -9137,
+ -9136, -9135, -9134, -9133, -9132, -9131, -9130, -9129, -9128, 134, 156, 148,
+ 163, -9127, -9126, 171, 203, -9125, -9124, -9123, -9122, -9121, -9120, -9119,
+ -9118, 29, 30, 28, 79, 51, 75, 131, 135, 35, 130, 132,
+ 144, 149, 160, 157, 168, -9117, -9116, -9115, 0, 0, 0, -9114,
+ -9113, -9112, -9111, -9110, -9109, -9108, -9107, -9106, -9105, -9104, -9103, 0,
+ 0, 0, 0, 0, 0, 0, 0, -9102, -9101, -9100, -9099, -9098,
+ -9097, 102, 123, 132, 139, 131, 173, -9096, 146, -9095, -9094, 0,
+ -9093, 0, 0, 0, 0, -9092, -9091, -9090, -9089, -9088, -9086, -9085,
+ -9082, -9081, -9080, -9079, -9078, -9077, -9076, -9075, -9074, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9073,
+ 0, -9072, -9071, 129, 154, -9070, -9069, 152, 163, -9068, 149, -9067,
+ -9066, 0, 0, 0, 0, -9065, -9064, 0, -9063, 0, 0, -9062,
+ -9061, 0, -9060, -9059, 0, -9058, -9057, 0, -9056, -9055, 0, 0,
+ 0, -9054, -9053, -9052, 0, 0, -9051, -9050, -9049, -9048, -9047, 0,
+ 0, -9046, -9045, -9044, -9043, -9042, -9041, -9040, -9039, 0, 0, 4,
+ 1, -9038, -9037, -9036, -9035, 3, -9034, -9033, -9032, -9031, -9030, -9029,
+ 10, -9028, 2, 28, 36, -9027, -9026, -9025, -9024, -9023, -9022, -9021,
+ 16, -9020, -9019, -9018, -9017, -9016, -9015, -9014, -9013, -9012, -9011, -9010,
+ -9009, -9008, -9007, -9006, -9005, -9004, -9003, -9002, -9001, -9000, -8999, -8998,
+ -8997, -8996, -8995, -8994, -8993, -8992, 8, 10, 19, -8991, -8990, -8988,
+ -8987, -8986, -8985, -8984, -8983, -8982, 0, -8981, -8980, -8979, -8978, -8977,
+ -8976, 1, 3, -8975, -8974, 2, 8, 20, 33, 41, 45, 34,
+ 49, 3, -8973, -8972, 5, 1, 5, 14, 24, 1, 2, 17,
+ 18, 45, 46, 19, 66, -8971, -8970, -8969, -8968, 35, 37, -8967,
+ 0, -8966, -8965, 66, 66, 76, -8964, -8962, 67, 53, 61, -8961,
+ 61, 64, 64, 68, -8960, -8959, -8958, 64, 64, -8957, -8956, 70,
+ -8955, 3, 64, 9, 67, 66, 72, 72, 72, 121, 122, -8954,
+ 112, 75, 108, 124, 127, -8953, -8952, -8951, -8950, -8949, -8948, -8947,
+ -8945, -8944, -8943, -8942, -8941, 315, -8940, 385, 396, -8939, -8938, -8937,
+ -8936, -8935, -8934, -8933, -8932, -8931, -8930, -8929, -8928, -8927, -8926, -8925,
+ -8924, 391, 397, 1, -8923, 386, 396, 448, 452, -8922, -8921, 0,
+ 0, 0, 0, 0, 0, 0, 0, -8920, -8919, -8918, -8917, 0,
+ 0, -8916, -8915, 500, 511, 366, 432, 948, 971, 51, -8914, 51,
+ 108, 43, 401, 262, 267, 94, 305, 212, 249, 266, 289, 263,
+ 920, -8913, -8912, -8911, -8910, 1, 1, 1, 271, 1, 1, 1,
+ 1, 1, 268, 1, 1, 1, 1, 390, 1, 1, 1, 407,
+ -8909, -8908, -8907, 68, 4099, -8906, -8905, 4099, -8904, 300, 624, 4112,
+ 4119, 4128, 4128, 4128, 4132, 127, 278, 418, 1, 1, 1, 1,
+ 1, 357, 383, 2055, 1, 2056, 2056, -8903, -8902, -8901, -8900, 271,
+ 2049, 2051, 2053, 2048, 2056, 2051, 2057, 2048, 2068, 2049, 2056, 2062,
+ 2068, 2057, 2065, 2056, 2072, 417, 2054, 2080, 2080, 2074, 2084, 2066,
+ 2070, 2083, 2085, 2056, 2092, 2088, 2095, 4096, -8899, -8898, -8897, -8896,
+ -8895, -8894, -8893, 4098, 4104, 4113, 4115, -8892, -8891, 4113, 4114, 1,
+ 1, 1, 1, 1, 1, 1, 2053, 2063, 1, 1, 1, 4241,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 532, 1024, 529,
+ 532, 1, 1, 1, 409, 1157, 1, 4224, 4226, 4225, -8890, 1154,
+ 1156, 3, 4, 1152, 1, 1167, 1, 1, 1165, 1185, 1220, 4274,
+ 1, 1182, 1195, -8889, -8888, 4256, 4256, 4256, 4268, 4266, 4309, 4308,
+ 4312, 4372, 4375, 1162, 1, 1, 1, 1, 1, 1185, 1222, 1220,
+ 1226, 1236, 1256, 1701, 1707, 1, 1, 1, 1615, 1164, 1, 1612,
+ 1, 1792, 1792, -8887, -8886, 1808, 1810, -8885, -8884, -8883, -8882, -8881,
+ -8880, -8879, -8878, -8877, -8876, 4231, 4253, -8875, -8874, -8873, -8872, -8871,
+ 4234, -8870, -8869, 1793, 1794, 1792, 1798, 1792, 1794, 1800, 1803, 1792,
+ 1796, 1, 1, -8868, 1809, 1, 1, 1, 1, 1, 1, 1,
+ 4243, 1864, 1, 1, 1, 1797, 1, 1, 1, 1, 1, 1562,
+ 1879, 1, 1, 1, 1, 1881, 1884, 1874, 1888, 2, 10, 10,
+ 342, 5, 18, 8, 1, 11, 37, 20, 32, 17, 1688, 3,
+ 5, 16, 36, 53, 57, 48, 48, 2, 1, 1702, 1857, 1,
+ 1686, 5, 1, 15, 16, 2, 21, 1, 12, 4, 18, 8,
+ 64, 25, 64, 4178, 4208, 1687, 1688, -8866, -8865, -8864, -8863, -8862,
+ -8860, -8859, -8858, -8857, -8856, -8855, -8854, -8853, -8852, 4125, 4137, 4142,
+ 4224, -8851, 4114, 4112, 4224, -8850, -8849, 1928, 1978, 1758, 1853, -8848,
+ 1764, 1946, 3304, -8847, -8846, -8845, -8844, -8843, -8842, -8841, -8840, 1804,
+ 3253, 3257, 3269, 3268, 3283, 3288, 3293, 3248, 3298, 1, 1, -8838,
+ -8837, 1735, 1, 4, 1, 5, 1, 1, 14, 40, 40, 3293,
+ 16, 3, 1, 10, 32, 34, 36, 7, 1, 35, 38, 46,
+ 46, 1760, 3333, 4299, 4302, 1, 3, 14, 1569, 10, 38, 32,
+ 39, 4100, 4130, 3856, 41, 6, 13, 21, 38, 25, 68, 68,
+ 72, 3864, 65, 68, 80, 4166, 4166, 4098, -8836, 4104, 4112, 4113,
+ 4193, 4099, 4114, 4118, 4125, 4100, 4196, 64, 70, 9, 73, 72,
+ 72, 3889, 4184, 4179, 4181, 4176, 1, 4, 4, 13, 14, 3,
+ 5, 7, 1, 4, 15, 4142, 4482, -8835, -8834, 4132, 4228, -8833,
+ -8832, -8831, -8830, -8829, -8828, -8827, 4100, -8826, -8825, 4149, 4153, 4152,
+ 4156, 4149, 4167, 4171, 4227, 4161, 4251, 4241, 26, 4238, 4240, 27,
+ 34, 4486, 4550, 1, 4141, 4130, 4142, -8824, -8823, 32, 4137, 4142,
+ 4512, 4180, 4516, 4521, 4543, 4106, 4132, -8822, 4165, 4096, 4140, 4142,
+ 4164, 4111, 4155, 25, 70, 28, 39, 31, 65, 4536, 4687, 5081,
+ 84, 930, 938, 931, -8821, 931, 945, 944, -8820, 929, 961, -8819,
+ -8818, 901, 4107, -8817, 929, 1012, 1023, 4419, -8816, -8815, -8814, 1844,
+ 4101, -8813, -8812, -8811, 0, 4673, 4686, -8810, -8809, -8808, -8806, -8805,
+ -8804, -8803, -8802, 0, 4215, 4720, 4871, -8801, -8800, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, -8799, -8798, -8797, 4873, -8796,
+ 922, 940, 926, 1007, 930, 1096, 1019, 1131, 1016, 1121, 1156, 1158,
+ 1122, 1120, 1154, 1162, 1152, 1154, 17, 17, 1157, 1153, 1156, 1164,
+ 1152, 1176, 1182, 1184, 1190, 946, 1193, -8795, -8794, -8793, -8792, 768,
+ 768, 768, 768, -8791, -8790, 768, 768, 1, 1, 8, 8, 12,
+ 8, 2, 2, 1152, 15, 52, 54, 34, 42, 25, 30, 1,
+ 13, 9, 31, 1, 31, 1169, 1176, 1174, 930, 46, 64, 64,
+ 1280, 64, 64, 78, 64, 80, 82, 1174, 88, 66, 66, 88,
+ 90, 178, 82, 90, 101, 1280, 1280, 220, 83, 1282, 1291, 230,
+ 1288, 70, 64, 114, 72, 244, 246, 239, 118, 201, 115, 1285,
+ 227, 332, 336, 338, 352, 1312, 1312, 1195, 1291, 1192, 1292, 1193,
+ 1316, 1328, 2, 24, 266, 1325, 1321, 1329, 1284, 1284, 1296, 1300,
+ 1300, 1306, 1314, 1322, 1332, 1334, 1332, 1316, 1360, 1344, 1369, 1371,
+ 1360, 1360, 1364, 1360, 1360, 1374, 1446, 1440, 1445, 307, 165, 31,
+ 392, 1364, 384, 392, 309, 1409, 1414, 898, 900, 386, 389, -8789,
+ -8788, 898, 898, 900, 392, 427, 429, 898, 898, -8787, -8786, -8785,
+ -8784, -8783, -8780, -8778, -8777, -8776, -8775, 1288, 1284, 1288, -8774, -8773,
+ 1298, 1370, 1378, -8772, -8771, -8770, -8769, -8768, -8767, 4114, 4119, 1,
+ 1, 1281, -8766, -8765, 2, 1394, 1384, 1394, 1393, 1399, -8764, -8763,
+ 1406, 1536, 1538, 1553, 1536, 1563, 1566, 1572, 1572, 1541, 1577, 1548,
+ 1571, 1580, 1584, 1576, 1568, 1575, 1667, 1313, 1667, 1569, 1672, -8762,
+ 1664, 1580, 1664, 1666, 1664, 1666, 1674, -8761, 1664, 1664, 1664, 1546,
+ 1553, 1559, 1563, 1576, -8760, -8759, -8758, 0, -8757, -8756, -8755, 0,
+ 0, 0, 0, -8754, -8753, -8752, -8751, -8750, -8749, -8748, -8747, -8746,
+ -8745, -8744, -8743, -8742, -8741, -8740, -8739, -8738, -8737, -8736, -8735, -8734,
+ -8733, -8732, -8731, -8730, -8729, -8728, -8727, -8726, -8725, -8724, -8723, -8722,
+ -8721, -8720, -8719, 0, 0, -8718, -8717, 0, 0, 0, 0, 0,
+ 0, 0, 0, -8716, -8715, -8714, -8712, -8711, -8710, -8708, -8707, -8706,
+ 4288, 4303, 4325, 4349, 5025, 4512, 4801, 4320, 4526, 4335, 5025, 4335,
+ 4998, 36, 36, 36, 45, 5024, 5052, 5294, 5296, 5301, 5303, -8705,
+ -8704, 4596, -8703, -8702, 4598, 57, 5092, 62, 62, 3, 4238, 5001,
+ 5012, 24, 24, 24, 129, 93, 128, 128, 139, 19, 144, 129,
+ 145, 192, 192, 153, 155, 145, 218, 4346, 5961, 5971, 5982, 6172,
+ 6204, 4103, 4997, 144, 5005, -8701, -8700, -8699, -8698, -8697, 5120, -8696,
+ -8695, -8694, 5120, -8693, -8692, 0, 0, 0, 0, -8691, -8690, -8689,
+ -8688, 0, -8687, -8686, 5514, 0, 0, 0, 0, -8685, -8684, -8683,
+ -8682, -8681, -8680, -8679, -8678, -8677, -8676, 5151, 5152, -8674, -8673, -8672,
+ 5157, -8671, -8670, 0, -8669, 4392, 4397, -8668, -8667, -8666, -8665, 4393,
+ -8664, 4410, 4582, 5199, 5228, -8663, 4555, 4544, -8662, 5377, -8661, -8660,
+ 5216, -8659, 5390, -8658, 5477, -8657, -8656, 5525, -8655, 5617, 5620, -8654,
+ 5627, -8653, -8652, -8651, -8650, -8648, -8647, 0, 0, 0, 0, -8645,
+ 0, -8644, -8642, -8641, 0, -8640, 0, -8639, 0, -8638, -8637, -8636,
+ -8635, 5666, 5668, 5670, -8634, 5713, 5714, -8633, -8632, -8631, 5712, -8630,
+ -8629, 0, 0, 5834, 5834, 5834, 5834, 5843, 24, 1, 3, 280,
+ 280, 1837, 1920, -8628, 294, -8627, -8626, -8625, 1921, 1923, 1921, 1928,
+ 1253, 1920, 1928, 1935, 1941, 1943, 1941, -8624, -8623, -8622, -8621, 1933,
+ 1921, 1928, -8619, -8618, -8617, -8616, 1938, -8615, -8614, 0, 0, -8613,
+ -8612, 0, 0, -8611, -8610, -8609, -8608, -8607, 1926, 2, 10, 4,
+ 27, 40, 59, 32, 93, 60, 60, 461, 402, 466, 480, 485,
+ 385, -8606, -8605, -8604, -8603, 402, 404, 416, 395, 440, 4480, 4417,
+ 4481, 4483, 4488, 4488, -8602, -8601, -8600, 0, -8599, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -8598, 4481, 4483, 4481,
+ 4487, 4481, 4488, 4481, 432, 4480, 4480, 4484, 4484, 4480, 4496, 4496,
+ 434, 424, 4418, 436, 4422, 4481, 4483, 4481, 4484, -8597, -8596, 4480,
+ 4484, -8595, -8594, -8593, -8591, -8590, -8588, -8587, 433, -8583, -8580, 444,
+ -8578, 0, 0, 0, -8577, 0, -8576, 0, -8575, -8573, -8572, -8571,
+ 0, -8570, -8569, -8568, 0, 0, 0, 0, 0, 0, 0, 0,
+ -8567, -8566, -8565, -8564, 0, -8563, -8562, -8561, -8559, -8558, -8557, -8556,
+ 0, -8555, 0, -8554, -8553, 26, 128, 130, 128, 128, 128, 136,
+ 133, 130, -8552, 129, 130, 144, 144, 152, 128, 130, 128, 133,
+ 128, 141, 161, 141, 169, 170, 180, 178, 167, 207, 212, 261,
+ 151, -8551, 180, 192, 129, 193, -8549, 198, 142, 194, 284, 384,
+ 384, 384, 384, 384, 254, 289, 384, 295, 232, 384, 384, 384,
+ 388, 384, 384, 384, 396, 386, 399, 408, 384, 393, 393, 416,
+ 237, 416, 416, 422, 416, 419, 419, 427, 438, 442, 434, 444,
+ 492, 389, 468, 1027, 267, 1352, 1035, 1520, 1074, 1529, 1062, 7698,
+ 472, 7699, 1387, 7707, 1046, 410, 508, 1048, 258, 1064, 1097, 1368,
+ 7680, 7686, 7680, 7690, 1083, 7693, 7682, 8224, 1111, 8253, 8359, 8364,
+ 1495, 8392, 8397, 8421, 8422, 8424, 8452, 8452, 8455, 8456, 8456, 8456,
+ 8460, 1076, 101, 1083, 1032, 1315, 298, 8579, 315, 8577, 8586, 8594,
+ 8594, 8602, 8602, 8624, 1080, 1080, 1078, 8608, 1775, 8608, 8608, 8617,
+ -8546, -8540, 8608, 8646, -8539, -8537, -8536, -8535, 1066, 8599, 8640, 8640,
+ 118, 8644, 8650, 8654, 8662, 8664, 8672, 8664, 8672, 8672, 8672, 8672,
+ -8530, -8528, -8527, -8526, -8523, -8522, -8521, -8518, -8517, -8516, -8515, -8514,
+ -8513, -8510, -8508, -8507, -8505, -8496, -8495, -8493, -8492, -8491, -8490, -8489,
+ -8488, -8487, -8486, -8485, -8484, -8483, -8482, -8481, 8576, 8592, 8576, 8592,
+ 8592, 8592, 8592, 8592, 8598, 8592, 8704, 8592, 8709, 8712, 8712, 8712,
+ 8706, 8704, 8722, 8704, 8777, 8721, 8776, 8776, 8768, 8771, 8785, 8787,
+ 8784, 8786, 8793, 8798, 8768, 8770, 8768, 8772, 8777, 8771, 8776, 8784,
+ 8786, 8784, 8773, 8787, 8772, 8784, 8796, 8794, 8796, 1428, 1432, 1488,
+ 1488, 8769, 8774, 8772, 8774, -8480, -8479, 8768, 8790, -8477, -8476, -8475,
+ -8474, -8473, -8472, 1418, 8737, -8471, -8470, -8469, -8468, -8467, -8466, -8465,
+ -8458, -8457, 184, -8456, -8454, 1424, 1424, 1446, 8832, 8854, 8861, 8878,
+ 8730, 8947, 8957, 8960, 8960, 8960, 8960, 8960, 8705, 8712, 8723, 8960,
+ 8719, 8960, 8729, 8960, 8724, 8960, 8960, 8960, 8960, 8960, 8960, 8960,
+ 8960, 8725, 8754, 8759, 8960, 8960, 8960, 8960, 8960, 8960, 8960, 8960,
+ -8453, -8451, 8960, 8960, 8707, 8704, -8450, -8449, 1909, 8706, -8448, 8705,
+ 8709, -8446, -8444, -8439, -8438, -8436, -8435, 8705, -8434, 1846, 8705, 8708,
+ 8705, 8705, 8713, 8705, 8707, -8432, 8704, 8706, 8704, 8707, 8707, 8720,
+ -8430, 8704, 1885, 8707, 8711, 8706, 8706, 8713, 8714, 8704, 8704, 8704,
+ 8704, 8704, 8727, 8743, 8769, 8870, 8878, 8884, 8914, 8920, 8960, 8960,
+ 8960, 8960, 8960, 8960, 8960, 8962, 8960, 8970, -8417, -8415, -8414, -8413,
+ -8411, -8410, -8409, -8408, -8407, -8406, -8404, -8403, -8401, -8400, -8399, -8398,
+ 8960, -8397, -8395, -8394, -8393, -8392, -8391, -8390, 0, 0, 0, 0,
+ 0, -8389, 0, 0, -8388, 8976, 8993, 8976, 8997, 8992, 8992, 9000,
+ 9002, -8387, 9014, 8998, -8386, 0, 0, 0, 0, -8385, -8384, -8382,
+ -8381, 0, 0, -8380, -8379, -8378, -8377, 0, 0, 0, 0, -8376,
+ 8960, 8960, 8960, 8960, 8960, 8963, 8969, 8969, 8973, -8375, -8374, 8961,
+ 8976, -8373, -8372, -8371, -8368, -8366, -8351, -8350, 8960, 8960, 8960, 8960,
+ -8349, 8960, 8960, 8960, 8964, 8960, 8960, 8960, 8964, -8348, -8347, 8960,
+ -8346, -8345, 8961, 8961, -8344, -8343, -8342, -8341, 0, -8340, 8960, -8338,
+ -8336, -8335, -8334, -8333, -8332, -8331, -8330, -8329, -8328, -8327, -8326, -8325,
+ -8324, -8323, -8322, -8321, -8320, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+ 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, -8318, -8317, -8316, -8315,
+ -8314, -8313, -8312, -8311, -8310, -8309, -8308, -8306, -8305, -8304, -8303, -8302,
+ 8192, 8192, 8192, 8197, 8192, 8208, 8208, 8208, 8194, 8208, 8208, 8216,
+ 8216, 8220, 8220, 8240, 8216, 8193, 8202, 8205, 8207, 8208, 8213, 8208,
+ 8197, 8208, 8212, 8208, 8208, 8208, 8224, 8208, 8207, 8193, 8195, 8193,
+ 8202, 8193, 8202, 8193, 8224, 8224, 8224, 8224, 8224, 8224, 8224, 8224,
+ 8224, 8192, 8192, 8192, 8192, -8301, -8297, 8192, 8192, 8192, 8192, 8192,
+ 8192, -8296, -8294, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+ 8210, 8212, 8221, 8293, 8304, 8304, 8304, 8308, 8304, 8192, 8192, -8284,
+ 8192, -8275, -8271, 8196, 8256, 8256, 8256, 8256, 8264, 8256, 8256, 8256,
+ 8265, 8273, 8265, 8278, 8306, 8336, 8272, 8336, 8277, 8336, 8336, 8344,
+ 8344, 8347, 8348, 8350, 8293, 8278, 8273, 8281, 8284, 8280, 8352, 9232,
+ 8295, 9241, 9243, 9241, 9255, 9265, 9267, 9265, 8286, 9252, 9252, 9257,
+ 9248, 9260, 9289, 9263, 8272, 9296, 9296, 9296, 9249, 9296, 9298, 9296,
+ 9256, 8248, 8248, 8252, 9217, 9227, 9220, 9248, 9231, -8270, 9256, 9258,
+ 9248, -8269, -8268, -8267, -8266, 9344, 9344, 9344, 9344, 9344, 9344, 9344,
+ 9344, 9346, 9344, 9349, 9344, 9456, 9441, 9456, 9413, 9409, 9409, 9456,
+ 9417, 9456, 9408, 9456, 9409, 9464, 9412, 9465, 9466, -8265, -8264, -8263,
+ 9419, -8262, -8261, -8260, -8259, -8258, -8257, -8256, -8251, 9425, 9477, 9482,
+ -8249, 9488, 9488, 9492, 9492, 9287, 9492, 9616, 9492, 9618, 9620, 9622,
+ 9696, 9707, 9709, 9728, 9728, 9728, 9728, 9728, 9446, 9456, 9458, 9456,
+ 9462, 9456, 9458, 9456, 9728, 9728, 9728, -8248, 9728, -8247, -8246, 1,
+ 1, 1, 1, 5120, 1, 748, 5120, 1, 1, 1, 1, 1,
+ 1, 5120, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5120, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 5376, 1, 5376, 5376, 1, 1, 1, 1, 1,
+ 1058, 1452, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9223,
+ 9216, 1, 1, 9217, 9217, 9217, 9217, 1, 1, 1, 1, 9216,
+ 9216, 9220, 9220, 9226, 9216, 9216, 9216, 9223, -8244, 9234, 9236, 9233,
+ 9216, 9360, 9362, 9365, 9359, 9360, 9370, 9368, 9370, 9361, 9361, 9361,
+ 9361, 9401, 9403, 9401, 9369, 9376, -8238, -8234, 9376, 9381, 9424, 9424,
+ 9381, 9425, -8233, -8225, -8219, -8217, -8216, 1, 1, 1, 9409, 1415,
+ 1, 1, 1, 1, 1, 1, 9409, 1481, 1, 1, 1, 1,
+ 1530, 9412, 9412, 9412, 9416, 9418, 9423, 1520, 9425, 9434, 9436, 9446,
+ 9456, 9432, 9456, 1410, 1428, 1432, 1436, 1423, 1432, -8206, 9345, 1414,
+ 9348, 9344, 9347, -8205, 9348, -8204, -8203, 1348, 1, 1, 1, 1,
+ 1, 1, 1, 1, 9365, 9364, 1, 5376, 9370, -8202, -8201, -8200,
+ -8199, -8198, -8197, -8196, -8194, -8192, -8190, -8189, -8181, -8178, -8177, -8176,
+ -8175, -8174, -8173, 9376, 1, 1, 1, 1, 9729, 9730, 1, 1,
+ 9399, 1, 1, 1, 9728, 9728, 9728, -8172, 9728, 8329, 8329, -8171,
+ 8329, 8329, 8329, 8329, 8329, 8348, 8338, 8349, 8356, 8364, 8364, 8371,
+ 8345, 8320, 8320, 8320, 8352, 8321, 8356, 8356, -8170, 8352, 8354, 8352,
+ -8169, -8168, -8167, 589, 10, 3, 9, 8320, 22, 20, 36, 35,
+ 49, 49, 49, 61, 68, 61, 71, 64, 68, 72, 71, 8332,
+ 72, 72, 72, 90, 90, 70, 94, 88, 96, 96, 96, 86,
+ 8323, 8344, 8344, 8344, 65, 67, 8344, 8344, 67, 65, 68, 65,
+ 67, 76, 78, 72, 64, 64, 74, 64, 64, 74, 91, 66,
+ 74, 82, 96, 100, 100, 111, 129, 39, 40, 50, 52, 128,
+ 128, 128, 60, 40, 128, 128, 128, 128, 138, 128, 128, 54,
+ 128, 49, 132, 128, 137, 137, 170, 128, 183, 152, 186, 188,
+ 144, 192, 198, 133, 208, 154, 194, 196, 224, 257, 229, 208,
+ 227, 261, 265, 257, 265, 276, 280, 231, 261, 224, 224, 181,
+ 224, 224, 289, 260, 260, 290, 290, 281, 294, 288, 290, 8242,
+ 8244, 8195, 8196, 8196, 8199, 8205, 8194, 8313, 8448, 8450, 8448, 8452,
+ 8448, 8448, 8448, 8456, 8448, 8448, 8452, 8452, 8449, 8456, 8456, 8456,
+ 8452, 8451, 8465, 8472, -8166, -8165, -8164, 8474, 8448, 8451, 8452, 8452,
+ 8456, 8456, 8450, 8456, 8454, 8448, 8448, 8488, 8452, 8488, 8488, 8493,
+ -8163, -8162, -8161, -8160, -8159, -8158, -8156, -8155, -8153, -8148, -8147, -8146,
+ -8144, -8143, -8141, -8138, -8133, -8130, -8125, -8123, -8122, -8121, -8120, -8119,
+ -8118, -8117, -8116, -8115, -8114, -8083, -8072, -8069, -7486, -7479, -7412, -7381,
+ -7378, -7375, -7326, -7321, -6282, -6280, -6176, -6138, -6132, -6098, -6097, -6090,
+ -6082, -6079, -6058, -6051, -6049, -5951, -5950, -5948, -5945, -5944, -5943, -5939,
+ -5917, -5916, -5915, -5913, -5912, -5911, -5910, -5909, -5908, -5905, -5901, -5870,
+ -5607, -5443, -5438, -5432, -5169, -5117, -5003, -4390, -4206, -4197, -4193, };
+
+const size_t NU_DUCET_G_SIZE = sizeof(NU_DUCET_G) / sizeof(*NU_DUCET_G);
+
+/* codepoints */
+const uint32_t NU_DUCET_VALUES_C[] = {
+ 0x000388, 0x000389, 0x000035, 0x000386, 0x01D6EE, 0x01D6EF, 0x01D6E2, 0x01D6E3,
+ 0x0000C8, 0x0000C9, 0x0000CA, 0x0000CB, 0x0003A7, 0x0003A3, 0x0000CE, 0x0000CF,
+ 0x01D772, 0x00042F, 0x0003A0, 0x0003BE, 0x0003BC, 0x0003BD, 0x00039C, 0x00039D,
+ 0x000398, 0x000399, 0x01D6FC, 0x01D6FD, 0x01D6FE, 0x01D6FF, 0x00039E, 0x00039F,
+ 0x0003A5, 0x0003A1, 0x01D618, 0x01D61D, 0x0003B4, 0x01D607, 0x0003BA, 0x0003BF,
+ 0x01D61A, 0x000471, 0x00038A, 0x00038E, 0x01D60B, 0x00038F, 0x000033, 0x01D61B,
+ 0x0003B0, 0x0003B1, 0x01D614, 0x01D615, 0x01D616, 0x01D617, 0x0003B6, 0x0003B7,
+ 0x0003B8, 0x0003B9, 0x01D619, 0x00045A, 0x01D61E, 0x01D61F, 0x0003BB, 0x0003B5,
+ 0x0000E0, 0x0000E1, 0x0000E2, 0x0000E3, 0x0000E4, 0x0000E5, 0x0000E6, 0x0000E7,
+ 0x01D602, 0x01D603, 0x0000C6, 0x0003AD, 0x01D605, 0x01D601, 0x0000FC, 0x01D61C,
+ 0x0000F0, 0x0000F1, 0x01D606, 0x0000EB, 0x0000F4, 0x0000F5, 0x0000F6, 0x0000EA,
+ 0x0000F8, 0x0000F9, 0x0000FA, 0x0000FB, 0x0000CC, 0x0000FD, 0x0000FE, 0x0000FF,
+ 0x01D6C0, 0x000428, 0x01D6C4, 0x01D6C5, 0x01D6F8, 0x01D6FA, 0x0000C4, 0x01D6C9,
+ 0x01D6CA, 0x01D6CB, 0x01D6C8, 0x01D6CD, 0x01D6CE, 0x01D6CC, 0x0000F2, 0x0000F3,
+ 0x0003A9, 0x0003F5, 0x000032, 0x01D633, 0x01D60F, 0x0003A4, 0x00042E, 0x000031,
+ 0x000030, 0x01D60A, 0x01D604, 0x01D609, 0x0000ED, 0x01D65B, 0x0003A6, 0x0003AB,
+ 0x01D6F2, 0x01D6F3, 0x000076, 0x000077, 0x0000C2, 0x0000C5, 0x01D6F9, 0x0000C3,
+ 0x0000D8, 0x0000C1, 0x00039B, 0x0000C7, 0x0000C0, 0x00038C, 0x0000DE, 0x0000DF,
+ 0x0000D2, 0x0000D1, 0x0000D0, 0x0000D3, 0x0000D5, 0x000069, 0x0003B3, 0x0000D6,
+ 0x0000D9, 0x0000DD, 0x0000DC, 0x0000DB, 0x0003B2, 0x0000D4, 0x01D6A1, 0x0000DA,
+ 0x01D6A0, 0x000061, 0x01D6A4, 0x01D6A5, 0x00039A, 0x01D6C7, 0x01D6A8, 0x01D6A9,
+ 0x01D6AE, 0x000394, 0x01D6AC, 0x01D6AD, 0x01D6F4, 0x01D6AF, 0x01D6F6, 0x01D6F5,
+ 0x01D6F7, 0x000038, 0x01D694, 0x01D695, 0x000034, 0x01D69E, 0x000036, 0x000037,
+ 0x01D69A, 0x000039, 0x01D6B8, 0x01D6BE, 0x01D6BF, 0x01D69F, 0x01D6D4, 0x01D6D5,
+ 0x000044, 0x000045, 0x01D6B4, 0x01D6B5, 0x000054, 0x000055, 0x000056, 0x000057,
+ 0x01D6BA, 0x01D6BB, 0x0000AA, 0x00004D, 0x01D6AA, 0x01D6AB, 0x01D6B6, 0x01D6B1,
+ 0x000051, 0x01D6CF, 0x0000B2, 0x000053, 0x01D6B7, 0x0000B5, 0x000050, 0x01D6B0,
+ 0x00004C, 0x0000B9, 0x0000BA, 0x000052, 0x0000BC, 0x0000BD, 0x0000BE, 0x01D6D0,
+ 0x000042, 0x000074, 0x000043, 0x000072, 0x01D6D2, 0x01D6F0, 0x000046, 0x000047,
+ 0x0000CD, 0x000049, 0x00004A, 0x00004B, 0x000048, 0x01D6DA, 0x00004E, 0x00004F,
+ 0x000070, 0x000071, 0x01D6D1, 0x01D6D3, 0x01D6D6, 0x01D6D7, 0x000073, 0x01D6DE,
+ 0x000059, 0x000079, 0x0000B3, 0x000058, 0x01D6F1, 0x01D6DF, 0x00005A, 0x000078,
+ 0x000101, 0x000100, 0x000103, 0x000102, 0x000105, 0x000104, 0x000107, 0x000106,
+ 0x000109, 0x000108, 0x00010B, 0x00010A, 0x00010D, 0x00010C, 0x00010F, 0x00010E,
+ 0x000111, 0x000110, 0x000113, 0x000112, 0x000115, 0x000114, 0x000117, 0x000116,
+ 0x000119, 0x000118, 0x00011B, 0x00011A, 0x00011D, 0x00011C, 0x00011F, 0x00011E,
+ 0x000121, 0x000120, 0x000123, 0x000122, 0x000125, 0x000124, 0x000127, 0x000126,
+ 0x000129, 0x000128, 0x01D691, 0x00012A, 0x00012D, 0x00012C, 0x00012F, 0x00012E,
+ 0x000131, 0x000130, 0x000133, 0x000132, 0x000135, 0x000134, 0x000137, 0x000136,
+ 0x000139, 0x000138, 0x00013B, 0x00013A, 0x00013D, 0x00013C, 0x00013F, 0x00013E,
+ 0x000141, 0x000140, 0x000143, 0x000142, 0x000145, 0x000144, 0x000147, 0x000146,
+ 0x000149, 0x000148, 0x01D69B, 0x00014A, 0x00014D, 0x00014C, 0x00014F, 0x00014E,
+ 0x000151, 0x000150, 0x000153, 0x000152, 0x000155, 0x000154, 0x000157, 0x000156,
+ 0x000159, 0x000158, 0x00015B, 0x00015A, 0x00015D, 0x00015C, 0x00015F, 0x00015E,
+ 0x000161, 0x000160, 0x000163, 0x000162, 0x000165, 0x000164, 0x000167, 0x000166,
+ 0x000169, 0x000168, 0x00016B, 0x00016A, 0x00016D, 0x00016C, 0x01D690, 0x01D697,
+ 0x000171, 0x000170, 0x000173, 0x000172, 0x000175, 0x000174, 0x000177, 0x000176,
+ 0x000179, 0x000178, 0x00017B, 0x00017A, 0x01D696, 0x00017C, 0x00017F, 0x00017E,
+ 0x000181, 0x000180, 0x000183, 0x000182, 0x000185, 0x000184, 0x000187, 0x000186,
+ 0x000189, 0x000188, 0x00018B, 0x00018A, 0x00018D, 0x00018C, 0x00018F, 0x00018E,
+ 0x000191, 0x000190, 0x000193, 0x000192, 0x000195, 0x000194, 0x000197, 0x000196,
+ 0x000199, 0x000198, 0x00019B, 0x00019A, 0x00019D, 0x00019C, 0x00019F, 0x00019E,
+ 0x0001A1, 0x0001A0, 0x0001A3, 0x0001A2, 0x0001A5, 0x0001A4, 0x0001A7, 0x0001A6,
+ 0x0001A9, 0x0001A8, 0x0001AB, 0x0001AA, 0x0001AD, 0x0001AC, 0x0001AF, 0x0001AE,
+ 0x0001B1, 0x0001B0, 0x0001B3, 0x0001B2, 0x0001B5, 0x0001B4, 0x0001B7, 0x0001B6,
+ 0x0001B9, 0x0001B8, 0x0001BB, 0x0001BA, 0x0001BD, 0x0001BC, 0x0001BF, 0x0001BE,
+ 0x0001C1, 0x0001C0, 0x0001C3, 0x0001C2, 0x0001C5, 0x0001C4, 0x0001C7, 0x0001C6,
+ 0x0001C9, 0x0001C8, 0x0001CB, 0x0001CA, 0x0001CD, 0x0001CC, 0x0001CF, 0x0001CE,
+ 0x0001D1, 0x0001D0, 0x0001D3, 0x0001D2, 0x0001D5, 0x0001D4, 0x0001D7, 0x0001D6,
+ 0x0001D9, 0x0001D8, 0x0001DB, 0x0001DA, 0x0001DD, 0x0001DC, 0x0001DF, 0x0001DE,
+ 0x0001E1, 0x0001E0, 0x0001E3, 0x0001E2, 0x0001E5, 0x0001E4, 0x0001E7, 0x0001E6,
+ 0x0001E9, 0x0001E8, 0x0001EB, 0x0001EA, 0x0001ED, 0x0001EC, 0x0001EF, 0x0001EE,
+ 0x0001F1, 0x0001F0, 0x0001F3, 0x0001F2, 0x0001F5, 0x0001F4, 0x01D711, 0x0001F6,
+ 0x0001F9, 0x0001F8, 0x0001FB, 0x0001FA, 0x0001FD, 0x0001FC, 0x0001FF, 0x0001FE,
+ 0x01D702, 0x01D703, 0x01D722, 0x01D721, 0x01D720, 0x01D723, 0x01D708, 0x01D725,
+ 0x01D726, 0x01D72B, 0x01D73C, 0x01D73D, 0x01D73E, 0x01D727, 0x01D710, 0x01D731,
+ 0x01D730, 0x01D73A, 0x01D736, 0x01D734, 0x01D753, 0x01D737, 0x01D718, 0x01D739,
+ 0x01D73B, 0x01D71B, 0x01D71C, 0x01D738, 0x01D73F, 0x01D71F, 0x01D781, 0x01D780,
+ 0x01D783, 0x01D782, 0x01D785, 0x01D784, 0x01D787, 0x01D786, 0x01D72A, 0x01D788,
+ 0x01D78B, 0x01D78A, 0x01D78D, 0x01D78C, 0x01D78F, 0x01D78E, 0x01D791, 0x01D790,
+ 0x01D793, 0x01D792, 0x01D795, 0x01D794, 0x01D797, 0x01D796, 0x01D799, 0x01D798,
+ 0x01D79B, 0x01D79A, 0x01D79D, 0x01D79C, 0x01D79F, 0x01D79E, 0x01D7A1, 0x01D7A0,
+ 0x01D7A3, 0x01D7A2, 0x01D7A5, 0x01D7A4, 0x01D7A7, 0x01D7A6, 0x01D724, 0x01D7A8,
+ 0x01D7AB, 0x01D7AA, 0x01D7AD, 0x01D7AC, 0x01D7AF, 0x01D7AE, 0x01D7B1, 0x01D7B0,
+ 0x01D7B3, 0x01D7B2, 0x01D7B5, 0x01D7B4, 0x01D7B7, 0x01D7B6, 0x01D7B9, 0x01D7B8,
+ 0x01D7BB, 0x01D7BA, 0x01D7BD, 0x01D7BC, 0x01D7BF, 0x01D7BE, 0x01D7C1, 0x01D7C0,
+ 0x01D752, 0x01D7C2, 0x01D7C5, 0x01D7C4, 0x01D7C7, 0x01D7C6, 0x01D7C9, 0x01D7C8,
+ 0x01D7CB, 0x01D7CA, 0x01D750, 0x01D751, 0x01D7CF, 0x01D7CE, 0x01D7D1, 0x01D7D0,
+ 0x01D7D3, 0x01D7D2, 0x01D7D5, 0x01D7D4, 0x01D7D7, 0x01D7D6, 0x01D7D9, 0x01D7D8,
+ 0x01D7DB, 0x01D7DA, 0x01D7DD, 0x01D7DC, 0x01D7DF, 0x01D7DE, 0x01D740, 0x01D741,
+ 0x01D773, 0x01D743, 0x01D744, 0x01D745, 0x01D746, 0x01D747, 0x01D728, 0x01D729,
+ 0x01D74A, 0x01D74B, 0x01D72C, 0x01D72D, 0x01D72E, 0x01D72F, 0x01D742, 0x01D749,
+ 0x01D7F3, 0x01D7F2, 0x01D754, 0x01D748, 0x01D756, 0x01D757, 0x01D758, 0x01D759,
+ 0x01D75A, 0x01D75B, 0x01D75C, 0x01D75D, 0x01D75E, 0x01D75F, 0x000218, 0x000219,
+ 0x000200, 0x000201, 0x000202, 0x000203, 0x000204, 0x000205, 0x000206, 0x000207,
+ 0x000208, 0x000209, 0x00020A, 0x00020B, 0x00020C, 0x00020D, 0x00020E, 0x00020F,
+ 0x000230, 0x000231, 0x000232, 0x000233, 0x000234, 0x000235, 0x000236, 0x000237,
+ 0x000238, 0x000239, 0x00023A, 0x00023B, 0x00021C, 0x00021D, 0x00021E, 0x00021F,
+ 0x000240, 0x000241, 0x000242, 0x000243, 0x000244, 0x000245, 0x000246, 0x000247,
+ 0x000248, 0x000249, 0x00024A, 0x00024B, 0x00024C, 0x00024D, 0x00022E, 0x00022F,
+ 0x000250, 0x000251, 0x000252, 0x000253, 0x000254, 0x000255, 0x000256, 0x000257,
+ 0x000258, 0x000259, 0x00025A, 0x00025B, 0x00025C, 0x00025D, 0x00025E, 0x00025F,
+ 0x000220, 0x000221, 0x000222, 0x000223, 0x000224, 0x000225, 0x000226, 0x000227,
+ 0x0000E8, 0x000229, 0x00022A, 0x00022B, 0x0000EC, 0x000228, 0x0000EE, 0x0000EF,
+ 0x000270, 0x000271, 0x000272, 0x000273, 0x000274, 0x000275, 0x00007A, 0x000277,
+ 0x00022C, 0x00022D, 0x00027A, 0x00027B, 0x00023C, 0x00023D, 0x00023E, 0x00023F,
+ 0x000728, 0x000771, 0x000772, 0x000773, 0x000724, 0x000770, 0x000776, 0x00072F,
+ 0x00046C, 0x00046D, 0x00072A, 0x00072B, 0x00044C, 0x00044D, 0x00044E, 0x00044F,
+ 0x00072C, 0x00072D, 0x000750, 0x000759, 0x000755, 0x000752, 0x00072E, 0x000756,
+ 0x00071E, 0x000761, 0x00075A, 0x00075B, 0x000754, 0x00071C, 0x000777, 0x000760,
+ 0x000460, 0x000461, 0x000462, 0x000463, 0x000465, 0x000392, 0x000466, 0x000467,
+ 0x000468, 0x000469, 0x00046A, 0x00046B, 0x00042C, 0x00042D, 0x00046E, 0x00046F,
+ 0x000726, 0x000721, 0x000720, 0x000725, 0x000474, 0x00047C, 0x000464, 0x000722,
+ 0x000478, 0x000479, 0x00047A, 0x000729, 0x000393, 0x00047D, 0x00047E, 0x00047F,
+ 0x000440, 0x000441, 0x000442, 0x000443, 0x000444, 0x000445, 0x00026E, 0x000447,
+ 0x000268, 0x000269, 0x00026A, 0x00026F, 0x00026C, 0x00026D, 0x00024E, 0x00024F,
+ 0x000470, 0x00047B, 0x000449, 0x000476, 0x000475, 0x000477, 0x000446, 0x000448,
+ 0x000458, 0x000459, 0x00044A, 0x00044B, 0x00045C, 0x00045D, 0x00045E, 0x00045F,
+ 0x000062, 0x000261, 0x000262, 0x000263, 0x000064, 0x000065, 0x000066, 0x000067,
+ 0x000068, 0x000267, 0x00026B, 0x00006B, 0x000396, 0x00006E, 0x00006A, 0x00006F,
+ 0x00027C, 0x000260, 0x000266, 0x000397, 0x000391, 0x00027D, 0x000390, 0x000276,
+ 0x000278, 0x000279, 0x000264, 0x000265, 0x00006C, 0x00006D, 0x00027E, 0x00027F,
+ 0x000692, 0x000698, 0x00069D, 0x000693, 0x000691, 0x00069A, 0x00069B, 0x000697,
+ 0x000690, 0x000696, 0x00A380, 0x00A381, 0x00A383, 0x00A38E, 0x00A384, 0x00A385,
+ 0x00A0EC, 0x00A382, 0x00A388, 0x00A389, 0x00A387, 0x00A38B, 0x00A38C, 0x00A38D,
+ 0x00A38A, 0x00A38F, 0x00A390, 0x00A391, 0x00A392, 0x00A39E, 0x00A394, 0x00A395,
+ 0x00A396, 0x00A397, 0x00A398, 0x00A399, 0x00A065, 0x00A39B, 0x00A39C, 0x00A39D,
+ 0x00A39A, 0x00A39F, 0x000680, 0x000687, 0x00A0EE, 0x00A3C4, 0x000768, 0x000769,
+ 0x000694, 0x00A386, 0x000688, 0x000689, 0x00A3A3, 0x00076C, 0x000695, 0x00069C,
+ 0x00076D, 0x00A0ED, 0x00A3B0, 0x00A3B1, 0x00A3B3, 0x00A3BE, 0x00A3B4, 0x00A3B5,
+ 0x00A3B2, 0x00A3B7, 0x00A3B8, 0x00A3B9, 0x00A3B6, 0x00A3BB, 0x000686, 0x00A3BD,
+ 0x00A3BA, 0x00A3BF, 0x00076E, 0x00076F, 0x00074D, 0x00A3C5, 0x00074E, 0x00074F,
+ 0x00A0E6, 0x00077C, 0x00A0EF, 0x00A0E8, 0x000684, 0x000685, 0x00A0CE, 0x00077D,
+ 0x000758, 0x000778, 0x00077E, 0x00077F, 0x00075C, 0x00075D, 0x00075E, 0x00075F,
+ 0x000779, 0x000765, 0x000762, 0x000763, 0x000774, 0x000775, 0x000766, 0x000767,
+ 0x00076A, 0x00076B, 0x00A3BC, 0x00A3AE, 0x000764, 0x00A0E3, 0x00A3A4, 0x00A3A5,
+ 0x00A0E5, 0x00A0E2, 0x00A3A8, 0x00A3A9, 0x00A3AA, 0x00A3AB, 0x00A3AD, 0x00A0E1,
+ 0x00A3AF, 0x00A0E0, 0x00077B, 0x00A0E7, 0x00077A, 0x00A0E9, 0x00A0F4, 0x00A0E4,
+ 0x00A0F6, 0x00A0F7, 0x000419, 0x000492, 0x000490, 0x000491, 0x00A0FC, 0x00A0FD,
+ 0x00A0EA, 0x00A0EB, 0x00A088, 0x00A0FE, 0x00A08C, 0x000497, 0x00A085, 0x00A084,
+ 0x000493, 0x00A08D, 0x00A098, 0x00A099, 0x00A08B, 0x00A089, 0x00A08E, 0x00A08F,
+ 0x00A09E, 0x00A09F, 0x00A091, 0x00A090, 0x00A093, 0x00A092, 0x00A09A, 0x00A09B,
+ 0x00A097, 0x00A096, 0x00A082, 0x00A083, 0x00A09C, 0x00A09D, 0x00A094, 0x00A095,
+ 0x00A080, 0x00A081, 0x00A0A4, 0x00A0A0, 0x00A0A3, 0x00A0A2, 0x00A0A5, 0x00A0A1,
+ 0x00A086, 0x00A087, 0x000495, 0x00A0A8, 0x00A0AB, 0x00A0AA, 0x00A0F5, 0x000496,
+ 0x00A0AF, 0x00A0AE, 0x00A0B4, 0x00A0B0, 0x00A0B3, 0x00A0B2, 0x00A0B5, 0x00A0B1,
+ 0x00A0B7, 0x00A0B6, 0x00A0BC, 0x00A0B8, 0x00A0BB, 0x00A0BA, 0x00A0BD, 0x00A0B9,
+ 0x00A0BF, 0x00A0BE, 0x00A1C0, 0x00A1C1, 0x00A1E2, 0x00A1E3, 0x00A0C3, 0x00A1E1,
+ 0x00A1E6, 0x00A1E7, 0x00A1E0, 0x00A1C8, 0x00A0C4, 0x00A0CA, 0x00A0C5, 0x00A0DD,
+ 0x000494, 0x00049B, 0x00A0C0, 0x00A0C1, 0x00A0C2, 0x00A0FF, 0x00A0D5, 0x00A0D4,
+ 0x00A0C6, 0x00A0C7, 0x00A0D9, 0x00A0D8, 0x00A0DB, 0x00A0DA, 0x00A1FC, 0x00A0DC,
+ 0x00A0DF, 0x00A0DE, 0x00A1FE, 0x00A1FF, 0x000413, 0x00A0F8, 0x00A0C9, 0x00A0F1,
+ 0x00049A, 0x00A0C8, 0x00A0F2, 0x00A0CB, 0x00A0F3, 0x00A1FA, 0x00A1F8, 0x00A0F0,
+ 0x00A0A6, 0x00A0A7, 0x00A1F0, 0x00A1F1, 0x00A1F2, 0x00A1F3, 0x00A1F4, 0x00A1F5,
+ 0x00A0CF, 0x00A1F9, 0x00A0F9, 0x00A0CC, 0x00A1F6, 0x00A1FB, 0x00A1FD, 0x00A0FB,
+ 0x00A0CD, 0x00A1F7, 0x00A128, 0x00A129, 0x00A12A, 0x00A12B, 0x00A184, 0x00A185,
+ 0x00A124, 0x00A125, 0x00A188, 0x00A189, 0x00A18A, 0x00A18B, 0x00A18C, 0x00A18D,
+ 0x00A18E, 0x00A18F, 0x00A12C, 0x00A12D, 0x00A178, 0x00A179, 0x00A192, 0x00A193,
+ 0x00A114, 0x00A115, 0x00A11A, 0x00A11B, 0x00A118, 0x00A119, 0x00A11E, 0x00A11F,
+ 0x00A12E, 0x00A12F, 0x00A180, 0x00A181, 0x00A182, 0x00A183, 0x00A1A4, 0x00A1A5,
+ 0x00A186, 0x00A187, 0x00A1A8, 0x00A1A9, 0x00A1AA, 0x00A1AB, 0x00A1AC, 0x00A1AD,
+ 0x00A1AE, 0x00A1AF, 0x00A190, 0x00A191, 0x00A1B2, 0x00A1B3, 0x00A194, 0x00A195,
+ 0x00A196, 0x00A197, 0x00A198, 0x00A199, 0x00A19A, 0x00A19B, 0x00A19C, 0x00A19D,
+ 0x00A19E, 0x00A19F, 0x00A1A0, 0x00A1A1, 0x00A1C2, 0x00A1C3, 0x00A1C4, 0x00A1C5,
+ 0x00A1C6, 0x00A1C7, 0x00A153, 0x00A1C9, 0x00A1CA, 0x00A1CB, 0x00A1CC, 0x00A1CD,
+ 0x00A1CE, 0x00A1CF, 0x00A1D0, 0x00A1D1, 0x00A1D2, 0x00A1D3, 0x00A1D4, 0x00A1D5,
+ 0x00A1D6, 0x00A1D7, 0x00A1D8, 0x00A1D9, 0x00A1DA, 0x00A1DB, 0x00A1DC, 0x00A1DD,
+ 0x00A1DE, 0x00A1DF, 0x00A150, 0x00A151, 0x00A152, 0x00A1A3, 0x00A144, 0x00A175,
+ 0x00A157, 0x00A1A2, 0x00A17B, 0x00A14A, 0x00A156, 0x00A14B, 0x00A174, 0x00A17E,
+ 0x00A17A, 0x00A17F, 0x00A1B0, 0x00A1B1, 0x00A1A6, 0x00A1A7, 0x00A1B4, 0x00A1B5,
+ 0x00A1B6, 0x00A1B7, 0x00A1B8, 0x00A1B9, 0x00A1BA, 0x00A1BB, 0x00A1BC, 0x00A1BD,
+ 0x00A1BE, 0x00A1BF, 0x000502, 0x000503, 0x00050A, 0x00050B, 0x000500, 0x000501,
+ 0x00050E, 0x00050F, 0x000508, 0x000509, 0x000504, 0x000505, 0x000506, 0x000507,
+ 0x000519, 0x000518, 0x00A02B, 0x000564, 0x00051D, 0x00051C, 0x00051F, 0x00051E,
+ 0x000521, 0x000520, 0x000523, 0x000527, 0x000525, 0x000524, 0x000522, 0x000526,
+ 0x000529, 0x000528, 0x00052B, 0x00052F, 0x00050C, 0x00050D, 0x00052A, 0x00052E,
+ 0x000531, 0x00053B, 0x000533, 0x000532, 0x00053A, 0x000537, 0x000534, 0x000535,
+ 0x000539, 0x000538, 0x000563, 0x00053F, 0x00053D, 0x00053C, 0x000536, 0x00053E,
+ 0x000541, 0x000540, 0x000543, 0x000542, 0x000545, 0x000544, 0x000547, 0x000546,
+ 0x00057B, 0x000565, 0x00A009, 0x00054A, 0x000575, 0x000481, 0x000549, 0x00057A,
+ 0x000551, 0x000550, 0x000553, 0x000571, 0x000555, 0x000554, 0x000552, 0x000556,
+ 0x000548, 0x000576, 0x000577, 0x00054B, 0x00054C, 0x00054D, 0x00054E, 0x00054F,
+ 0x000579, 0x00A01B, 0x000578, 0x00057E, 0x00052C, 0x00052D, 0x000567, 0x000561,
+ 0x0005EA, 0x0005E9, 0x0004D1, 0x00057F, 0x0005E8, 0x00A163, 0x00A164, 0x00A165,
+ 0x00A162, 0x000570, 0x00A168, 0x00A169, 0x00A16A, 0x00A16B, 0x00A16C, 0x00A16D,
+ 0x00A16E, 0x00A16F, 0x000573, 0x00A011, 0x000572, 0x000566, 0x0004B7, 0x00049F,
+ 0x000582, 0x000583, 0x000580, 0x000581, 0x000586, 0x000587, 0x000584, 0x000585,
+ 0x00A17C, 0x000623, 0x00A000, 0x00A001, 0x0005E6, 0x0005E7, 0x00A004, 0x00A005,
+ 0x000510, 0x000511, 0x000512, 0x000513, 0x000514, 0x000515, 0x000516, 0x000517,
+ 0x00A006, 0x00A007, 0x00051A, 0x00051B, 0x00A012, 0x00A013, 0x00A010, 0x00A00D,
+ 0x00A016, 0x00A017, 0x00A00A, 0x00A008, 0x00A01A, 0x00A00B, 0x00A01C, 0x00A01D,
+ 0x00A00E, 0x00A00F, 0x00A02C, 0x00A02D, 0x00A02E, 0x00A02F, 0x00A024, 0x00A025,
+ 0x00A022, 0x00A023, 0x00A038, 0x00A039, 0x00A02A, 0x00A029, 0x00A027, 0x00A00C,
+ 0x00A03E, 0x00A028, 0x00A030, 0x00A031, 0x00A032, 0x00A033, 0x00A03A, 0x00A03F,
+ 0x00A036, 0x00A037, 0x0005D9, 0x00A049, 0x00A03B, 0x00A021, 0x00A034, 0x00A035,
+ 0x00A03C, 0x00A03D, 0x00A042, 0x00A041, 0x00056C, 0x00A043, 0x00A046, 0x00A040,
+ 0x00A047, 0x0005F1, 0x0005F2, 0x0005F0, 0x00A04A, 0x00A04B, 0x00A044, 0x00A045,
+ 0x00A05B, 0x00A04F, 0x00A052, 0x00A053, 0x00A050, 0x00A051, 0x00A056, 0x00A057,
+ 0x0005DC, 0x00056E, 0x000562, 0x00056F, 0x0005D4, 0x0005D5, 0x0005DA, 0x0005DB,
+ 0x0005D8, 0x000569, 0x00056A, 0x00056B, 0x0005DD, 0x000568, 0x0005DE, 0x0005DF,
+ 0x0005D2, 0x0005D3, 0x0005E1, 0x0005E3, 0x0005E0, 0x0005E5, 0x000574, 0x0005E4,
+ 0x0005D0, 0x0005D1, 0x0005E2, 0x00056D, 0x00057C, 0x00057D, 0x0005D6, 0x0005D7,
+ 0x00A020, 0x00A026, 0x00A058, 0x00A059, 0x00A05A, 0x00A05D, 0x00A054, 0x00A055,
+ 0x00A05E, 0x00A05F, 0x0007CA, 0x00A340, 0x0007CC, 0x0007CD, 0x000631, 0x0007CE,
+ 0x00A346, 0x00A347, 0x00A364, 0x00A365, 0x00A36D, 0x0006B1, 0x00A215, 0x000633,
+ 0x000632, 0x00069E, 0x000683, 0x00A211, 0x00A369, 0x00A36E, 0x00A36C, 0x00069F,
+ 0x00A368, 0x00A210, 0x0007E3, 0x00A36F, 0x000699, 0x00A36A, 0x00A35C, 0x0007E2,
+ 0x0007E4, 0x0007E5, 0x000681, 0x00A21D, 0x0007E8, 0x0007E9, 0x00A37C, 0x00A214,
+ 0x00A362, 0x00A363, 0x0007EA, 0x000682, 0x00A2AB, 0x00A32E, 0x00A32C, 0x00068B,
+ 0x00A213, 0x00A20B, 0x00A21B, 0x00A374, 0x00A37E, 0x00A37F, 0x00A375, 0x00A06C,
+ 0x0004E8, 0x0004ED, 0x00A06B, 0x0004E6, 0x0004E5, 0x0004E7, 0x00A06E, 0x00A06F,
+ 0x00A06A, 0x0004E9, 0x0004CA, 0x00A060, 0x0004E4, 0x00A063, 0x0007E0, 0x0004EE,
+ 0x00A06D, 0x0007D4, 0x00A048, 0x00A35D, 0x00A062, 0x00A067, 0x00A04C, 0x00A04D,
+ 0x00A04E, 0x00A068, 0x0007DA, 0x00A291, 0x000719, 0x0004EC, 0x00A37A, 0x0007CB,
+ 0x00A07E, 0x00A066, 0x0004E2, 0x0004E3, 0x0004E1, 0x00A079, 0x00A05C, 0x00A078,
+ 0x00A07F, 0x0004EF, 0x00A064, 0x00A069, 0x0004FC, 0x0004E0, 0x0004EB, 0x00A07C,
+ 0x00A076, 0x00A061, 0x0004FE, 0x0004EA, 0x0004F4, 0x0004FD, 0x0004F6, 0x0004FF,
+ 0x0004F8, 0x0004F9, 0x0004FA, 0x0004FB, 0x00A072, 0x00A073, 0x00A074, 0x00A075,
+ 0x000480, 0x00A07A, 0x00A07D, 0x00A071, 0x00048C, 0x00048D, 0x00A070, 0x0004F7,
+ 0x00A07B, 0x00A077, 0x00048A, 0x00048B, 0x000718, 0x00071D, 0x00048E, 0x00048F,
+ 0x00A292, 0x00A297, 0x00A2B5, 0x00A2B9, 0x000636, 0x000635, 0x000412, 0x000727,
+ 0x000498, 0x000499, 0x00049E, 0x0004BA, 0x00049C, 0x00049D, 0x000723, 0x000417,
+ 0x0004A1, 0x0004B1, 0x0004B0, 0x0004BB, 0x0004B4, 0x0004B5, 0x0004AD, 0x0004B6,
+ 0x0004AA, 0x0004AB, 0x0004A2, 0x0004A3, 0x0004A8, 0x0004A9, 0x0004A0, 0x0004A5,
+ 0x00041B, 0x000416, 0x0004B2, 0x0004B3, 0x0004A4, 0x0004AF, 0x0004A6, 0x0004A7,
+ 0x0004B8, 0x0004B9, 0x000630, 0x000637, 0x0004BC, 0x0004BD, 0x0004BE, 0x0004BF,
+ 0x000757, 0x000634, 0x000411, 0x00041A, 0x000410, 0x00A2A5, 0x000414, 0x000415,
+ 0x00A2A9, 0x0004C9, 0x0004C8, 0x0004CE, 0x0004CD, 0x000753, 0x0004CC, 0x0004CF,
+ 0x0004D0, 0x0004D6, 0x0004D2, 0x0004D3, 0x0004C1, 0x0004D7, 0x0004DA, 0x0004DB,
+ 0x0004D4, 0x0004D5, 0x0004D8, 0x0004D9, 0x0004DE, 0x0004DF, 0x0004DC, 0x0004DD,
+ 0x0004C0, 0x000710, 0x00071A, 0x000715, 0x0004C4, 0x0004C5, 0x0004C6, 0x0004C7,
+ 0x000716, 0x000714, 0x0004C2, 0x0004C3, 0x000717, 0x0004CB, 0x00A3EE, 0x00A3E4,
+ 0x0004F0, 0x0004F1, 0x00A3E8, 0x00A3EC, 0x00A3EB, 0x0004F5, 0x00A3ED, 0x00A3EF,
+ 0x0004AE, 0x00A3EA, 0x0004F2, 0x0004F3, 0x00071B, 0x0004AC, 0x000712, 0x000713,
+ 0x000782, 0x000783, 0x000780, 0x000781, 0x000785, 0x000787, 0x000784, 0x0007B1,
+ 0x00079C, 0x00079D, 0x00A301, 0x00078B, 0x00A316, 0x00A317, 0x00078F, 0x000786,
+ 0x000791, 0x00079E, 0x00A393, 0x000792, 0x00079F, 0x000790, 0x000796, 0x000795,
+ 0x000798, 0x000799, 0x00079B, 0x00A318, 0x00A312, 0x00A313, 0x000794, 0x00079A,
+ 0x00A314, 0x00A315, 0x00A31A, 0x00A31B, 0x00A311, 0x00A319, 0x00A31E, 0x00A31D,
+ 0x00A31F, 0x00A310, 0x00078A, 0x00A300, 0x000788, 0x000789, 0x0007A3, 0x00078E,
+ 0x00A302, 0x00A303, 0x00A324, 0x00A32B, 0x0007A0, 0x0007A1, 0x00A334, 0x00A325,
+ 0x00A33A, 0x00A33B, 0x0007A2, 0x00A329, 0x00078C, 0x00078D, 0x00A328, 0x00A32D,
+ 0x00A306, 0x00A307, 0x00A335, 0x0007DB, 0x0007D0, 0x0007D5, 0x00A31C, 0x00A30B,
+ 0x00A32A, 0x00A32F, 0x0007D6, 0x0007C3, 0x0007C2, 0x0007C1, 0x0007C7, 0x0007D7,
+ 0x000751, 0x0007C9, 0x0007CF, 0x0007D1, 0x0007DC, 0x0007DD, 0x0007DE, 0x0007DF,
+ 0x0007D8, 0x0007D9, 0x00A359, 0x0007D3, 0x00A352, 0x00A353, 0x0007D2, 0x00071F,
+ 0x00A293, 0x00A35B, 0x00A350, 0x00A351, 0x00A354, 0x00A343, 0x00A341, 0x00A355,
+ 0x00A356, 0x00A357, 0x0007C0, 0x0007C5, 0x0007C8, 0x0007C6, 0x0007A4, 0x0007A5,
+ 0x00A342, 0x0007E1, 0x00A378, 0x00A379, 0x0007C4, 0x00A37B, 0x0007E6, 0x0007E7,
+ 0x00A35E, 0x00A3E5, 0x00A35A, 0x00A35F, 0x00A3E9, 0x00A358, 0x00A33E, 0x00A33F,
+ 0x00040D, 0x000401, 0x000402, 0x000403, 0x000400, 0x000405, 0x000406, 0x000407,
+ 0x000409, 0x000404, 0x00040A, 0x00040B, 0x000797, 0x000408, 0x00040E, 0x00040F,
+ 0x000450, 0x000451, 0x000452, 0x000453, 0x000455, 0x000472, 0x000456, 0x000457,
+ 0x000418, 0x000793, 0x00045B, 0x000454, 0x00041C, 0x00041D, 0x00041E, 0x00041F,
+ 0x000429, 0x000421, 0x000422, 0x000423, 0x000420, 0x000425, 0x000426, 0x000427,
+ 0x0003A8, 0x000424, 0x0003AA, 0x00042B, 0x0003AC, 0x00040C, 0x0003AE, 0x0003AF,
+ 0x00043C, 0x000431, 0x000432, 0x000433, 0x000430, 0x000435, 0x000436, 0x000437,
+ 0x000439, 0x000434, 0x00043A, 0x00043B, 0x000438, 0x00043D, 0x00043E, 0x00043F,
+ 0x0003C0, 0x0003C1, 0x0003C2, 0x0003C3, 0x0003C4, 0x0003C5, 0x0003C6, 0x0003C7,
+ 0x0003C8, 0x0003C9, 0x0003CA, 0x0003CB, 0x0003CC, 0x0003CD, 0x0003CE, 0x0003CF,
+ 0x0003D0, 0x0003D1, 0x0003D2, 0x0003D3, 0x0003D4, 0x0003D5, 0x0003D6, 0x0003D7,
+ 0x0003D8, 0x0003D9, 0x0003DA, 0x0003DB, 0x0003DC, 0x0003DD, 0x0003DE, 0x0003DF,
+ 0x0003E0, 0x0003E1, 0x0003E2, 0x0003E3, 0x0003E4, 0x0003E5, 0x0003E6, 0x0003E7,
+ 0x0003E8, 0x0003E9, 0x0003EA, 0x0003EB, 0x0003EC, 0x0003ED, 0x0003EE, 0x0003EF,
+ 0x0003F0, 0x0003F1, 0x0003F2, 0x0003F3, 0x0003F4, 0x000473, 0x00042A, 0x0003F7,
+ 0x0003F8, 0x0003F9, 0x0003FA, 0x0003FB, 0x0003FC, 0x0003FD, 0x0003FE, 0x0003FF,
+ 0x00A433, 0x00A40E, 0x00A404, 0x00A405, 0x00A435, 0x00A432, 0x00A408, 0x00A409,
+ 0x00A40A, 0x00A40B, 0x00A3C0, 0x00A3C1, 0x00A3E6, 0x00A3E7, 0x00A482, 0x00A483,
+ 0x00A3C6, 0x00A3C7, 0x00A480, 0x00A481, 0x00A48B, 0x00A48A, 0x00A3CC, 0x00A485,
+ 0x00A3CE, 0x00A484, 0x00A40C, 0x00A40D, 0x000802, 0x000801, 0x000803, 0x00A486,
+ 0x0008A2, 0x00A487, 0x00A488, 0x00A489, 0x0008BC, 0x0008BD, 0x0008BA, 0x0008BB,
+ 0x00080B, 0x000852, 0x00A3E0, 0x00A3E1, 0x00A3E2, 0x00A3E3, 0x00A43D, 0x00A46E,
+ 0x00A3A6, 0x00A3A7, 0x0008AB, 0x00A439, 0x000807, 0x000853, 0x00A3FE, 0x0008A7,
+ 0x00A436, 0x00A437, 0x00A3F0, 0x00A3F1, 0x00A3F2, 0x00A3F3, 0x00A3F4, 0x00A3F5,
+ 0x00A434, 0x00A3F7, 0x00A3F8, 0x00A3F9, 0x00A3FA, 0x00A3FB, 0x00A3FC, 0x00A3FD,
+ 0x00A3FF, 0x00A3F6, 0x00A4D0, 0x00A4D1, 0x00A4D2, 0x000806, 0x00A46F, 0x000800,
+ 0x00A4D6, 0x00A4D7, 0x00A3D8, 0x00A46A, 0x0008A0, 0x0008A5, 0x00A3DC, 0x00A3DD,
+ 0x00A43A, 0x00A43F, 0x00A3D0, 0x00A3D1, 0x00A3D2, 0x00A3D3, 0x00A3D4, 0x00A3D5,
+ 0x00A3D6, 0x00A3D7, 0x00A3C3, 0x00A3D9, 0x00A3DA, 0x00A3DB, 0x00A4D3, 0x00A3C2,
+ 0x00A3DE, 0x00A3DF, 0x0008A6, 0x0008AA, 0x0008A1, 0x00A465, 0x00A4E2, 0x00A4E3,
+ 0x0008A9, 0x00A3CD, 0x00A4E1, 0x00A4E6, 0x00A3CA, 0x00A3C9, 0x00A4E0, 0x00A3C8,
+ 0x00A3CF, 0x00A4E7, 0x00A4F1, 0x00A4F3, 0x00A4F0, 0x00A4F2, 0x00A438, 0x00A4F7,
+ 0x00A43B, 0x00A4F6, 0x00A464, 0x000804, 0x00A423, 0x000811, 0x000805, 0x00A43C,
+ 0x00080A, 0x00A46B, 0x00A58A, 0x00A516, 0x00A517, 0x000809, 0x000812, 0x00A589,
+ 0x00080D, 0x00A511, 0x00A50A, 0x00A508, 0x00A503, 0x000813, 0x00A504, 0x00A509,
+ 0x000808, 0x00A502, 0x00080F, 0x00A510, 0x00A513, 0x00A512, 0x00A51C, 0x00A51D,
+ 0x014503, 0x014500, 0x00A519, 0x00A518, 0x00080C, 0x00A51A, 0x014517, 0x000B6C,
+ 0x00A51F, 0x01450B, 0x00A539, 0x00A53F, 0x00A501, 0x00A538, 0x00080E, 0x014519,
+ 0x014518, 0x01451D, 0x01453F, 0x000810, 0x00A588, 0x01450A, 0x00A53A, 0x00A6E6,
+ 0x00A506, 0x00A58F, 0x014507, 0x01452B, 0x00A533, 0x00A532, 0x000815, 0x00A537,
+ 0x00A534, 0x00A535, 0x0008B6, 0x0008B7, 0x0008B0, 0x0008B1, 0x000854, 0x000864,
+ 0x00A522, 0x00A53B, 0x00A54A, 0x00A54B, 0x00A540, 0x0008B4, 0x0008B2, 0x0008B3,
+ 0x00A549, 0x00A576, 0x000AA2, 0x014535, 0x000857, 0x000851, 0x014506, 0x00A562,
+ 0x00A563, 0x000B6D, 0x00A57C, 0x000850, 0x00A557, 0x00A6E7, 0x014522, 0x000814,
+ 0x000861, 0x00A551, 0x00A572, 0x00A573, 0x00A57A, 0x00A57B, 0x00A578, 0x00A579,
+ 0x00A57D, 0x00A556, 0x00A568, 0x00A56D, 0x0008A3, 0x00A56C, 0x00A565, 0x00A564,
+ 0x00A56E, 0x0008B8, 0x00A521, 0x00A548, 0x00A56B, 0x00A54F, 0x00A56F, 0x00A520,
+ 0x00A56A, 0x00A569, 0x000860, 0x000856, 0x0008B9, 0x000865, 0x00A53C, 0x00086A,
+ 0x00A526, 0x00A527, 0x0145EE, 0x00A53D, 0x000A9C, 0x00A58E, 0x00090E, 0x00090F,
+ 0x00A53E, 0x00A54E, 0x01453C, 0x014523, 0x01453E, 0x01453D, 0x000908, 0x000909,
+ 0x000911, 0x000917, 0x000913, 0x000912, 0x000910, 0x00091A, 0x000915, 0x00091B,
+ 0x00A616, 0x0144DB, 0x01449E, 0x00A894, 0x000914, 0x00090D, 0x000916, 0x00090C,
+ 0x01456C, 0x0008AC, 0x00A97A, 0x0144EF, 0x0008AE, 0x0008A4, 0x000936, 0x000937,
+ 0x0008A8, 0x0008AD, 0x00A421, 0x00A585, 0x00A422, 0x00A427, 0x0008AF, 0x00A976,
+ 0x000931, 0x000930, 0x014488, 0x00A974, 0x00A420, 0x00A426, 0x00A944, 0x00A975,
+ 0x00A584, 0x000932, 0x0144BE, 0x000933, 0x0144BF, 0x00A977, 0x00A58B, 0x00A970,
+ 0x00A96B, 0x01448B, 0x01452E, 0x01452F, 0x0144F7, 0x014410, 0x01456E, 0x014564,
+ 0x000958, 0x00A43E, 0x01456F, 0x01457F, 0x00095C, 0x00095D, 0x00095E, 0x00095F,
+ 0x0144D8, 0x00A972, 0x00A971, 0x01456D, 0x014552, 0x00A97B, 0x000959, 0x014553,
+ 0x014545, 0x01454E, 0x014544, 0x01454F, 0x01454C, 0x014549, 0x014548, 0x01454B,
+ 0x01454A, 0x01454D, 0x00096E, 0x00096C, 0x0009EE, 0x00096D, 0x00096F, 0x0009EF,
+ 0x0009EC, 0x0009ED, 0x00A5E8, 0x00A5E5, 0x00A566, 0x00A567, 0x000968, 0x000969,
+ 0x00A5EE, 0x00A5EF, 0x00A5E9, 0x00A561, 0x00A560, 0x014570, 0x00A5ED, 0x00A5EC,
+ 0x00A5EA, 0x000978, 0x014563, 0x000979, 0x00097E, 0x00097C, 0x00097F, 0x00097D,
+ 0x000989, 0x000980, 0x00098A, 0x00098B, 0x000985, 0x000988, 0x000987, 0x000986,
+ 0x00099D, 0x00099F, 0x00A601, 0x00099C, 0x00A603, 0x00A602, 0x00A605, 0x00A604,
+ 0x00A607, 0x00A606, 0x00A609, 0x00A608, 0x000990, 0x00A60A, 0x000997, 0x000993,
+ 0x000999, 0x000998, 0x00099B, 0x00099A, 0x000994, 0x000995, 0x000996, 0x00099E,
+ 0x0009A2, 0x0009A3, 0x00A619, 0x00A618, 0x00098C, 0x0009A1, 0x00A61D, 0x00A61C,
+ 0x00A61F, 0x00A5B5, 0x00A621, 0x00A620, 0x00098F, 0x00A622, 0x00A2E2, 0x00A2E3,
+ 0x00A627, 0x00A626, 0x0009B0, 0x0009B7, 0x0009A8, 0x00A62A, 0x0009A0, 0x0009B6,
+ 0x0009B9, 0x0009B8, 0x0009B2, 0x0009A5, 0x00A2E7, 0x0009A6, 0x0009A7, 0x0009BD,
+ 0x0009E0, 0x0009E1, 0x0009E6, 0x0009E7, 0x0009E9, 0x0009F4, 0x0009EA, 0x0009E8,
+ 0x0009EB, 0x00A2E6, 0x00A2C0, 0x00A2C1, 0x0009CE, 0x0009FC, 0x00A2E0, 0x00A2E1,
+ 0x00A2C7, 0x0009F5, 0x0009F8, 0x0009F9, 0x00A2CC, 0x0009DC, 0x00A2CD, 0x0009F6,
+ 0x0009DD, 0x0009DF, 0x00A2D0, 0x00A2D1, 0x00A2D2, 0x00A2F2, 0x00A2F0, 0x00A2F1,
+ 0x00A2D6, 0x00A2D7, 0x0009AA, 0x0009AE, 0x0009A4, 0x00A2F6, 0x0009AF, 0x00A2F7,
+ 0x00A2CE, 0x00A2CF, 0x00A661, 0x00A660, 0x00A663, 0x00A662, 0x00A665, 0x0009AB,
+ 0x00A667, 0x00A666, 0x00A669, 0x00A668, 0x00A2F3, 0x00A66A, 0x00A66D, 0x00A66C,
+ 0x0009F7, 0x00A66E, 0x0009F0, 0x0009F1, 0x0009AC, 0x0009AD, 0x00A2F4, 0x00A2F5,
+ 0x00A2FE, 0x000B6F, 0x00A2F8, 0x00A2F9, 0x000A05, 0x00A2FF, 0x000A07, 0x000A06,
+ 0x00A2FC, 0x00A2FD, 0x00A692, 0x000A0A, 0x00A693, 0x00A2FB, 0x00A697, 0x00A2FA,
+ 0x00A6EA, 0x000A10, 0x000A13, 0x00A2A1, 0x00A2A2, 0x000A14, 0x000A17, 0x000A16,
+ 0x000A19, 0x000A18, 0x000A1B, 0x000A1A, 0x000A1D, 0x000A1C, 0x000A1F, 0x000A1E,
+ 0x00A290, 0x00A296, 0x00A2A0, 0x00A2D3, 0x00A2A6, 0x00A2A7, 0x00A2BC, 0x00A2BD,
+ 0x00A2BE, 0x000A28, 0x00A2C9, 0x00A2B4, 0x000A2D, 0x000A2C, 0x000A2F, 0x000A2E,
+ 0x000A33, 0x000A30, 0x00A2BA, 0x00A2BF, 0x000A35, 0x00A2BB, 0x000A32, 0x000A36,
+ 0x00A2B8, 0x000A38, 0x00A685, 0x00A2A3, 0x00A6BB, 0x00A6ED, 0x00A2C4, 0x00A2C5,
+ 0x00A6B5, 0x00A68A, 0x00A2C8, 0x00A684, 0x00A699, 0x00A2CB, 0x00A691, 0x00A698,
+ 0x00A690, 0x00A2CA, 0x00A682, 0x00A683, 0x00A6E9, 0x000A99, 0x00A6BD, 0x00A686,
+ 0x00A6BC, 0x00A613, 0x00A688, 0x00A689, 0x00A6CB, 0x00A68F, 0x00A6A0, 0x00A681,
+ 0x000A59, 0x0144DF, 0x000A5B, 0x000A5A, 0x00A6A2, 0x000A5C, 0x00A696, 0x000A5E,
+ 0x00A6E5, 0x000A98, 0x00A6EB, 0x00A6A6, 0x000B5F, 0x00A6A7, 0x000A67, 0x000A66,
+ 0x000A69, 0x000A68, 0x000A6B, 0x000A6A, 0x000A6D, 0x00A2A4, 0x000A6F, 0x000A6E,
+ 0x00A2AE, 0x0144D5, 0x00A2AA, 0x00A2A8, 0x00A6A1, 0x00A612, 0x00A2AC, 0x00A2AD,
+ 0x00A2AF, 0x014529, 0x00A6B8, 0x00A6B7, 0x00A6B2, 0x00A6B3, 0x00A6B4, 0x014524,
+ 0x00A6BE, 0x00A6BF, 0x0144D4, 0x00A6BA, 0x000A85, 0x00A6B9, 0x000A87, 0x000A86,
+ 0x000A89, 0x000A88, 0x000A8B, 0x000A8A, 0x000A8D, 0x000A8C, 0x000A8F, 0x00A7A8,
+ 0x00A722, 0x00A783, 0x00A217, 0x014565, 0x00A6CE, 0x00A212, 0x00A600, 0x000B68,
+ 0x014521, 0x00A6CF, 0x00A617, 0x00A61E, 0x00A782, 0x000B69, 0x00A781, 0x014520,
+ 0x000A93, 0x00A6E3, 0x000A91, 0x00A79E, 0x00A787, 0x00A611, 0x00A79F, 0x00A6E2,
+ 0x00A79C, 0x000AA8, 0x00A780, 0x00A7AA, 0x000AAD, 0x000AAC, 0x000AAF, 0x000AAE,
+ 0x000B74, 0x000AB0, 0x000AB3, 0x000AB2, 0x00A7A9, 0x000B75, 0x000AB7, 0x000AB6,
+ 0x00A786, 0x00A7AB, 0x00A21A, 0x00A610, 0x000A97, 0x00A732, 0x00A73E, 0x00A219,
+ 0x00A735, 0x00A733, 0x00A202, 0x00A203, 0x00A72A, 0x000A9B, 0x00A7AE, 0x00A216,
+ 0x00A73C, 0x00A723, 0x00A625, 0x00A74B, 0x00A6C5, 0x00A762, 0x00A6C8, 0x00A767,
+ 0x000B5C, 0x000AD0, 0x00A761, 0x00A6C4, 0x000AAB, 0x00A6C9, 0x00A744, 0x00A760,
+ 0x00A21E, 0x00A21F, 0x00A6E0, 0x000D93, 0x000B5D, 0x0144C5, 0x000B6E, 0x01448A,
+ 0x00A6D7, 0x00A766, 0x00A218, 0x00A74A, 0x00A6D6, 0x00A624, 0x00A653, 0x00A7FE,
+ 0x000AE9, 0x000AE8, 0x00A7FA, 0x00A76F, 0x000AED, 0x000AEC, 0x000AEF, 0x000AEE,
+ 0x00A765, 0x00A7FF, 0x00A769, 0x00A7FC, 0x000B73, 0x000B77, 0x00A76D, 0x00A768,
+ 0x00A76C, 0x00A76A, 0x000B76, 0x0144DA, 0x000A90, 0x000AB9, 0x00A77C, 0x000B72,
+ 0x00A76E, 0x00A763, 0x00A779, 0x00A6E8, 0x00A7FB, 0x00A778, 0x000B33, 0x000A96,
+ 0x000B19, 0x00A77D, 0x000B18, 0x00A623, 0x000B14, 0x000B30, 0x000B1D, 0x000B32,
+ 0x000B13, 0x00A79B, 0x00A795, 0x000B16, 0x00A794, 0x000B10, 0x000B17, 0x00A60B,
+ 0x000B1A, 0x00A6E1, 0x000B1B, 0x000B15, 0x01441D, 0x00A3CB, 0x00A8A5, 0x00A88D,
+ 0x000B23, 0x00A887, 0x000AB5, 0x000B06, 0x000B07, 0x014412, 0x014413, 0x01441E,
+ 0x000B21, 0x00A3A1, 0x014581, 0x0145B5, 0x000DEB, 0x01441F, 0x014403, 0x01459D,
+ 0x000B1E, 0x014417, 0x000B1F, 0x014411, 0x00A799, 0x014424, 0x014464, 0x014422,
+ 0x014420, 0x014421, 0x014425, 0x014428, 0x014426, 0x014468, 0x014427, 0x01442A,
+ 0x01442B, 0x014429, 0x000B2E, 0x000B0F, 0x014416, 0x014418, 0x01443B, 0x014414,
+ 0x00A79D, 0x014415, 0x000B08, 0x000B09, 0x01446C, 0x00A7A5, 0x01441C, 0x000B0C,
+ 0x000B2A, 0x000B2D, 0x000B2B, 0x000B2C, 0x00A2EE, 0x014405, 0x00A2EF, 0x00A3AC,
+ 0x000B28, 0x014401, 0x014402, 0x014406, 0x014400, 0x00A798, 0x000B1C, 0x00A79A,
+ 0x01444D, 0x01446A, 0x000B22, 0x000B20, 0x000B2F, 0x000B27, 0x014449, 0x00A6EC,
+ 0x014404, 0x00A7A4, 0x00A641, 0x014477, 0x000B24, 0x000B25, 0x000B26, 0x00A6EE,
+ 0x000B71, 0x000B35, 0x014444, 0x00A6EF, 0x00A6D1, 0x00A3A2, 0x000B36, 0x000B37,
+ 0x000B38, 0x000B39, 0x00A2ED, 0x000B3D, 0x00A2EA, 0x00A2EC, 0x014448, 0x00A2E5,
+ 0x00A2E4, 0x00A2E8, 0x00A3A0, 0x00A2E9, 0x014438, 0x014439, 0x014434, 0x01443A,
+ 0x00A2EB, 0x014435, 0x014469, 0x01446B, 0x000BA8, 0x000CB9, 0x0145DB, 0x000AA3,
+ 0x014465, 0x00A99E, 0x00A817, 0x000A95, 0x00A813, 0x000A9F, 0x01448D, 0x00A811,
+ 0x014496, 0x014484, 0x000A9D, 0x014485, 0x014489, 0x014510, 0x01448F, 0x000A94,
+ 0x000BA3, 0x014499, 0x01449F, 0x01448E, 0x01449B, 0x014493, 0x014497, 0x014483,
+ 0x000BAA, 0x014494, 0x01459A, 0x000A9A, 0x014492, 0x01449C, 0x000BA4, 0x014491,
+ 0x01448C, 0x014495, 0x01449D, 0x014590, 0x0145B6, 0x000BA9, 0x0144BB, 0x01458F,
+ 0x0144B6, 0x000BB8, 0x014482, 0x0144B2, 0x000AAA, 0x000BB9, 0x0145A5, 0x000A9E,
+ 0x000BD0, 0x00A810, 0x00AB9A, 0x000BEE, 0x0144B1, 0x0144B3, 0x000BEF, 0x0144B7,
+ 0x014481, 0x000BE8, 0x014486, 0x014487, 0x014498, 0x014480, 0x00A86E, 0x000BED,
+ 0x0144B0, 0x0144B5, 0x00A91E, 0x01449A, 0x0144E0, 0x0145BE, 0x0144E6, 0x00A86F,
+ 0x00A81A, 0x0144E7, 0x0144E8, 0x0144E9, 0x0144EB, 0x000BEC, 0x00A812, 0x00A844,
+ 0x0144EA, 0x00A816, 0x000BEA, 0x000BF0, 0x00A84B, 0x000BE6, 0x000BE7, 0x00A869,
+ 0x00A868, 0x000BEB, 0x0144FE, 0x0144FF, 0x00A863, 0x00A862, 0x0145BF, 0x00A86A,
+ 0x00A864, 0x00A865, 0x00A860, 0x00A861, 0x0144E3, 0x00A867, 0x0144E5, 0x0144E2,
+ 0x00A866, 0x0144E4, 0x000BF2, 0x000BF1, 0x00A86C, 0x000BE9, 0x00A86D, 0x0144E1,
+ 0x0144FC, 0x000C1E, 0x000C1B, 0x000C1C, 0x000C1A, 0x0144F5, 0x0144F3, 0x0144F2,
+ 0x0144B4, 0x0144F4, 0x0144F8, 0x0144F6, 0x0144F9, 0x00A885, 0x0144BA, 0x0144FA,
+ 0x000C12, 0x000C13, 0x0144FB, 0x00A884, 0x014501, 0x000C18, 0x000C1F, 0x014502,
+ 0x000C19, 0x014504, 0x00A889, 0x00A89F, 0x000C1D, 0x00A892, 0x00A893, 0x000C10,
+ 0x000C16, 0x00A89D, 0x00A899, 0x000C17, 0x014511, 0x00A898, 0x014513, 0x014512,
+ 0x00A88B, 0x000C07, 0x00A8AD, 0x014516, 0x00A8AC, 0x00A883, 0x01451E, 0x00A882,
+ 0x01451F, 0x01451C, 0x00A8A1, 0x00A8A8, 0x00A8AE, 0x00A8AF, 0x00A88A, 0x000C15,
+ 0x014525, 0x00A886, 0x014527, 0x014526, 0x00A891, 0x014528, 0x000C14, 0x01452A,
+ 0x00A890, 0x000C59, 0x00A896, 0x00A897, 0x00A89C, 0x000C05, 0x000C06, 0x000C09,
+ 0x000C08, 0x014534, 0x000C0A, 0x000C0B, 0x014539, 0x014538, 0x01453B, 0x01453A,
+ 0x00A88E, 0x000C34, 0x000C24, 0x000C21, 0x000C0C, 0x00A88F, 0x00A888, 0x00A88C,
+ 0x000C5A, 0x000C2A, 0x00A8D3, 0x00A8D0, 0x000C0E, 0x00A8D7, 0x00A8F6, 0x000C0F,
+ 0x00A8D1, 0x00A8D2, 0x000C22, 0x00A8D6, 0x000C36, 0x000C23, 0x000C79, 0x00A8FD,
+ 0x000C20, 0x000C31, 0x000C30, 0x000C38, 0x00A8B2, 0x00A8A3, 0x00A8A2, 0x000C35,
+ 0x000C32, 0x000C33, 0x00A8F2, 0x00A8A0, 0x014561, 0x014560, 0x00A8F7, 0x014562,
+ 0x00A8A6, 0x00A8A7, 0x014567, 0x014566, 0x014569, 0x014568, 0x01456B, 0x01456A,
+ 0x000C99, 0x00A8B3, 0x000C9D, 0x000C9F, 0x00A8FB, 0x000C37, 0x014573, 0x014572,
+ 0x014575, 0x014574, 0x014577, 0x014576, 0x014579, 0x00A902, 0x01457B, 0x01457A,
+ 0x01457D, 0x01457C, 0x00A90B, 0x01457E, 0x00A901, 0x00A903, 0x014583, 0x014582,
+ 0x00A91C, 0x00A90A, 0x00A911, 0x00A910, 0x00A918, 0x00A907, 0x00A905, 0x00A91F,
+ 0x00A917, 0x00A916, 0x00A91D, 0x00A909, 0x014591, 0x00A919, 0x014593, 0x014592,
+ 0x014595, 0x014594, 0x014597, 0x014596, 0x014599, 0x014598, 0x01459B, 0x00A900,
+ 0x00A906, 0x01459C, 0x01459F, 0x01459E, 0x00A93A, 0x00A923, 0x00A908, 0x00A938,
+ 0x00A93C, 0x000C9E, 0x00A935, 0x00A933, 0x00A93E, 0x00A932, 0x00A93B, 0x00A934,
+ 0x00A937, 0x00A90E, 0x00A921, 0x00A93D, 0x00A90F, 0x00A939, 0x00A90C, 0x00A90D,
+ 0x00A93F, 0x0145B4, 0x000C25, 0x000C28, 0x0145B9, 0x0145B8, 0x0145BB, 0x0145BA,
+ 0x000C26, 0x0145BC, 0x00A96C, 0x000C27, 0x000C80, 0x014585, 0x00A964, 0x00A965,
+ 0x00A96E, 0x00A96D, 0x014490, 0x000C3D, 0x0145B7, 0x000C9C, 0x000C98, 0x000C7A,
+ 0x000CF1, 0x000CED, 0x000C2B, 0x000CF2, 0x000CEC, 0x000C39, 0x000CEE, 0x000CEF,
+ 0x000CE9, 0x000CE8, 0x00A920, 0x00A960, 0x00A922, 0x00A962, 0x00A961, 0x00A96F,
+ 0x00A967, 0x00A963, 0x00A966, 0x00A968, 0x00A969, 0x0145E0, 0x0145E3, 0x0145E2,
+ 0x0145E5, 0x0145E4, 0x0145E7, 0x0145E6, 0x0145E9, 0x0145E8, 0x0145EB, 0x0145EA,
+ 0x000D10, 0x000D0B, 0x00A979, 0x00A978, 0x00A96A, 0x000D06, 0x000D07, 0x00A97C,
+ 0x0145F5, 0x0145F4, 0x00A984, 0x000D05, 0x0145F9, 0x0145F8, 0x0145FB, 0x0145FA,
+ 0x00A985, 0x0145FC, 0x0145FF, 0x00A988, 0x000D17, 0x00A98A, 0x000D30, 0x000D16,
+ 0x00A98F, 0x000D18, 0x00A991, 0x00A990, 0x00A993, 0x00A992, 0x000D19, 0x000D15,
+ 0x00A997, 0x00A996, 0x00A999, 0x00A998, 0x000D31, 0x000D0C, 0x000D2F, 0x00A99C,
+ 0x00A99F, 0x000D09, 0x00A9A1, 0x00A9A0, 0x000D0A, 0x00A9A2, 0x000D37, 0x000D08,
+ 0x00A9A7, 0x00A9A6, 0x000D1C, 0x000D1D, 0x000D14, 0x000D33, 0x00A9AD, 0x00A9AC,
+ 0x000D1E, 0x000D1B, 0x000D12, 0x000D13, 0x000D1F, 0x00A9B2, 0x000D1A, 0x000D32,
+ 0x01463F, 0x014635, 0x014636, 0x014637, 0x014633, 0x01461C, 0x01460C, 0x01460D,
+ 0x000C7B, 0x000C7C, 0x01460F, 0x000D6B, 0x000C2C, 0x01461D, 0x01461E, 0x01461F,
+ 0x000D54, 0x000D55, 0x000C58, 0x000D5C, 0x000D5A, 0x00F933, 0x000D5B, 0x000D56,
+ 0x000D5F, 0x000D5D, 0x000D59, 0x00A9D0, 0x00A9D3, 0x000D58, 0x000D7C, 0x000D5E,
+ 0x000D61, 0x00A9D6, 0x000D78, 0x000C2F, 0x000D2C, 0x000D2D, 0x000D7D, 0x000D2E,
+ 0x000D38, 0x000D29, 0x00A9E1, 0x00A9E0, 0x00A9E3, 0x00A9E2, 0x000D28, 0x00A9E4,
+ 0x00A9E7, 0x000D35, 0x000D36, 0x00A9E8, 0x00A9EB, 0x00A9EA, 0x00A9ED, 0x00A9EC,
+ 0x00A9EF, 0x00A9EE, 0x01463B, 0x000D3A, 0x000D34, 0x000D39, 0x000C2E, 0x000C2D,
+ 0x000DB5, 0x000D89, 0x00A9F9, 0x00A9F8, 0x000D8F, 0x000D87, 0x00A9FD, 0x00A9FC,
+ 0x00F90A, 0x000D88, 0x000DBA, 0x000DBB, 0x000D86, 0x000DB4, 0x000D8B, 0x000D85,
+ 0x000D91, 0x000D90, 0x000DB6, 0x000D92, 0x000D95, 0x000D94, 0x00A205, 0x000D96,
+ 0x000D8A, 0x000D8D, 0x000D9B, 0x000D9A, 0x000D9D, 0x000D9C, 0x000D9F, 0x000D9E,
+ 0x00A201, 0x000DA9, 0x000DB3, 0x000DA2, 0x000DA5, 0x000DA7, 0x000DA3, 0x000DB7,
+ 0x000DA4, 0x00A21C, 0x00AAA0, 0x000D8E, 0x000D8C, 0x00AAA2, 0x000DA1, 0x000DAB,
+ 0x000DA0, 0x00AAA7, 0x000DB1, 0x000DA6, 0x00AAAB, 0x000DB0, 0x000DAF, 0x00AAA6,
+ 0x000DAA, 0x000DB8, 0x00A200, 0x000DB9, 0x000DBD, 0x00AA6E, 0x00AAA4, 0x00AAAE,
+ 0x00AAAF, 0x01463C, 0x01463E, 0x000C6E, 0x000C6F, 0x00AAAA, 0x00AAAD, 0x014638,
+ 0x00A207, 0x014634, 0x014627, 0x00AA69, 0x014621, 0x014639, 0x01463A, 0x014620,
+ 0x01463D, 0x01462D, 0x00F9E3, 0x00F90C, 0x00ABE1, 0x00AADB, 0x00F90F, 0x00ABE0,
+ 0x00AA56, 0x00AA6F, 0x00AA6C, 0x00AA6D, 0x00F90D, 0x00AA68, 0x00AA55, 0x00F93D,
+ 0x000C68, 0x00AA54, 0x000DEC, 0x000C66, 0x00F93E, 0x000C67, 0x000DE7, 0x000DE6,
+ 0x000DA8, 0x000DE8, 0x000DEF, 0x000DEA, 0x000DED, 0x000DE9, 0x000DAE, 0x000DEE,
+ 0x000C78, 0x00AA65, 0x00AAA8, 0x00AAA9, 0x00ABE2, 0x000C7D, 0x014622, 0x014623,
+ 0x00AA64, 0x00AA6B, 0x00ABF0, 0x00AA6A, 0x00F9FD, 0x00F9FC, 0x000C7E, 0x00F935,
+ 0x00AAAC, 0x00F9FE, 0x00A204, 0x00F936, 0x00ABF2, 0x00ABF9, 0x00F93F, 0x00ABF8,
+ 0x00A206, 0x00ABF7, 0x00A20E, 0x000E10, 0x00A20F, 0x00A23A, 0x00AABA, 0x00AABB,
+ 0x014626, 0x000E13, 0x00A208, 0x00A209, 0x00A20A, 0x000E11, 0x00AAB5, 0x00A20D,
+ 0x000E12, 0x0006A0, 0x00A230, 0x00A221, 0x0006BC, 0x0006BD, 0x0006BE, 0x0006AF,
+ 0x00A236, 0x00A237, 0x0006A3, 0x0006A1, 0x00A20C, 0x0006D2, 0x000E1A, 0x000E1B,
+ 0x0006A2, 0x00063B, 0x00AA84, 0x00AA85, 0x0006BA, 0x000E16, 0x00AABC, 0x00AABD,
+ 0x0006B0, 0x00AA8A, 0x0006B8, 0x0006BF, 0x00F9EF, 0x000E15, 0x0006B6, 0x0006B7,
+ 0x0006B5, 0x00AA8B, 0x0006B4, 0x0006BB, 0x0006D3, 0x0006B9, 0x00A235, 0x000E17,
+ 0x00AAA5, 0x00A233, 0x00A232, 0x00A23B, 0x00AAB9, 0x00AAA3, 0x0006AC, 0x00A231,
+ 0x00A234, 0x000E14, 0x0006C1, 0x00A254, 0x0006C7, 0x00ABF6, 0x0006C0, 0x00A255,
+ 0x00ABA6, 0x00F9F6, 0x00F9F5, 0x0006C3, 0x00A225, 0x0006C5, 0x00A226, 0x0006C2,
+ 0x000638, 0x00A25F, 0x00A25B, 0x00A241, 0x00A259, 0x00A224, 0x00A25A, 0x0006CF,
+ 0x0006A8, 0x0006A5, 0x00ABD2, 0x00F9C8, 0x0006A6, 0x0006AB, 0x00F908, 0x0006A7,
+ 0x0006AE, 0x0006A9, 0x00F9F4, 0x00F9FF, 0x0006A4, 0x00A223, 0x000639, 0x0006C6,
+ 0x00A220, 0x0006C4, 0x00A23C, 0x0006CE, 0x00A222, 0x00A25E, 0x00063A, 0x00ABA1,
+ 0x0006AD, 0x00F9CC, 0x00ABA0, 0x00A258, 0x00A227, 0x00A23D, 0x0006AA, 0x00ABA7,
+ 0x00A23E, 0x000647, 0x00F9FA, 0x00A239, 0x00A238, 0x00A23F, 0x00AAA1, 0x00A240,
+ 0x00ABCD, 0x00068A, 0x000646, 0x000645, 0x00AB03, 0x00AB02, 0x00AB06, 0x00062E,
+ 0x00F943, 0x000672, 0x00A248, 0x00A249, 0x00A24E, 0x000644, 0x00A24C, 0x00A24D,
+ 0x00068F, 0x00A24F, 0x000649, 0x000671, 0x000648, 0x00067A, 0x00067B, 0x000675,
+ 0x000620, 0x000621, 0x000622, 0x00062F, 0x000625, 0x00062B, 0x000626, 0x000627,
+ 0x00F958, 0x000629, 0x000628, 0x00A261, 0x00A260, 0x00F95F, 0x00062D, 0x000624,
+ 0x00062A, 0x000673, 0x00A22A, 0x00A22B, 0x00068D, 0x00063D, 0x00063C, 0x00062C,
+ 0x00063E, 0x00A22F, 0x0006B3, 0x00A271, 0x00A272, 0x00A273, 0x00068E, 0x00063F,
+ 0x00A276, 0x000EC2, 0x000EC3, 0x00F9C6, 0x000EDC, 0x00AB89, 0x000641, 0x000643,
+ 0x000642, 0x00064A, 0x00A245, 0x00ABA2, 0x00A242, 0x00A243, 0x0006B2, 0x00F9C2,
+ 0x00F9AB, 0x00F9F0, 0x00F9C1, 0x00A25C, 0x00A247, 0x00F9A4, 0x00A25D, 0x00ABB9,
+ 0x00ABB8, 0x00F9F9, 0x00ABBF, 0x00ABB7, 0x00F9FB, 0x00F9DE, 0x00F9DD, 0x00F981,
+ 0x00F980, 0x00F9A6, 0x00F9A5, 0x00F9D4, 0x00F9D5, 0x00F9D8, 0x00F9C5, 0x00F9C0,
+ 0x00F9D9, 0x00F9DA, 0x00F9C3, 0x00F9CF, 0x00F9C7, 0x00F9C4, 0x00F9DF, 0x00F9A2,
+ 0x00A246, 0x00F9AF, 0x00F9A1, 0x00ABCC, 0x00068C, 0x00A244, 0x00F9AE, 0x00F9A7,
+ 0x00F9A8, 0x00ABB3, 0x00F9A3, 0x00F909, 0x00F9AC, 0x00F9CB, 0x00ABBD, 0x00F9BC,
+ 0x00F9F1, 0x00F9AD, 0x00F9AA, 0x00F9F2, 0x00F9BD, 0x00F9BE, 0x00F9A9, 0x00A24A,
+ 0x00F9B8, 0x00A24B, 0x00A805, 0x00A995, 0x0145EC, 0x00F9BF, 0x00F9F7, 0x0145EF,
+ 0x0145ED, 0x000CB0, 0x01458E, 0x00AB96, 0x00A99B, 0x000F31, 0x000F32, 0x000F33,
+ 0x00A99A, 0x00AB90, 0x000F23, 0x00F9D3, 0x00AB93, 0x000F30, 0x000F20, 0x000F21,
+ 0x00AB97, 0x0144C9, 0x00AB91, 0x0144CA, 0x000F27, 0x000C87, 0x000C85, 0x0144CE,
+ 0x000C8B, 0x00AB92, 0x00A801, 0x0144CF, 0x000C86, 0x00A858, 0x000C8F, 0x0144C8,
+ 0x00A85E, 0x000F29, 0x000F2A, 0x000F2B, 0x0144FD, 0x00A80A, 0x000CB3, 0x00A81C,
+ 0x00ABAC, 0x000C89, 0x00F9E9, 0x000C8A, 0x00A818, 0x00A803, 0x00A85B, 0x00F9E8,
+ 0x000F53, 0x00AB99, 0x0144CC, 0x000CB7, 0x000664, 0x00A819, 0x00A81F, 0x00F9D6,
+ 0x00A81D, 0x000CB6, 0x0144DE, 0x00A800, 0x00AB82, 0x00A871, 0x00066E, 0x000C8E,
+ 0x00AB84, 0x00AB85, 0x00ABBE, 0x00ABBB, 0x00A854, 0x00ABD3, 0x00A856, 0x00AB83,
+ 0x00F993, 0x00ABBC, 0x00AB8A, 0x00AB81, 0x00AB80, 0x00AB8B, 0x00F991, 0x00AB8F,
+ 0x000662, 0x000661, 0x00AB98, 0x000663, 0x00AB88, 0x000660, 0x00AB9C, 0x00AB9D,
+ 0x00AB86, 0x00AB9F, 0x000669, 0x00ABB2, 0x000668, 0x000665, 0x000667, 0x00066F,
+ 0x00067D, 0x000674, 0x000F2F, 0x00067C, 0x000676, 0x00AB8E, 0x00ABF3, 0x000677,
+ 0x000678, 0x000679, 0x00067E, 0x000666, 0x00ABBA, 0x00ABB5, 0x00ABB4, 0x00067F,
+ 0x000F5A, 0x00A808, 0x00A85A, 0x00A855, 0x00F997, 0x0144C4, 0x0144CB, 0x00A809,
+ 0x000F89, 0x000F88, 0x000E18, 0x00F98E, 0x00FBAF, 0x00F992, 0x000F8C, 0x000E04,
+ 0x00FBD5, 0x0144CD, 0x000E06, 0x00FBD6, 0x000E24, 0x000E07, 0x000F56, 0x000F57,
+ 0x00FBAC, 0x00FBE2, 0x00FBFB, 0x00A859, 0x00FBAD, 0x000E1C, 0x000E2C, 0x00FBDB,
+ 0x00FBE3, 0x00FBD3, 0x00FB72, 0x00FBE0, 0x00FB49, 0x000E05, 0x00FB70, 0x000F2C,
+ 0x00FB5C, 0x000F28, 0x00A842, 0x00A841, 0x0006EE, 0x000F2D, 0x000F2E, 0x0006EF,
+ 0x0006F4, 0x00FBDA, 0x00F99B, 0x000E0B, 0x00FBA8, 0x0006F5, 0x0006F6, 0x0006F7,
+ 0x0006F8, 0x0006F9, 0x0006FA, 0x0006FB, 0x0006FC, 0x00F995, 0x00A85F, 0x0006FF,
+ 0x0006CD, 0x000F50, 0x000F52, 0x00FBD4, 0x00F9D7, 0x0006F1, 0x00A85D, 0x0006F0,
+ 0x0006C8, 0x0006C9, 0x000F5B, 0x00FBAE, 0x000F55, 0x000E1F, 0x00F990, 0x000F54,
+ 0x000F51, 0x000F41, 0x0006D0, 0x0006D1, 0x000E19, 0x0006D5, 0x0011CD, 0x00FB90,
+ 0x000EC0, 0x000EC1, 0x0006CB, 0x0011C9, 0x0011CF, 0x0006F2, 0x00FB97, 0x0006CA,
+ 0x000CE0, 0x000CE1, 0x000EC4, 0x000C61, 0x000C60, 0x000E51, 0x000CE6, 0x000CE7,
+ 0x000C6A, 0x000C6B, 0x000CEA, 0x000CEB, 0x0006CC, 0x000C69, 0x000C6C, 0x000C6D,
+ 0x00F923, 0x000E40, 0x0011FF, 0x0011F9, 0x0011F4, 0x00FB17, 0x0006F3, 0x00FB14,
+ 0x000E1D, 0x000E45, 0x0011FA, 0x000E53, 0x0011FE, 0x0011FB, 0x000E1E, 0x00F9B0,
+ 0x00FAC7, 0x00F930, 0x00F937, 0x00FD82, 0x00F9B5, 0x00F9B6, 0x00F9B7, 0x00F93A,
+ 0x00F9B9, 0x00F9BA, 0x00F939, 0x00F938, 0x00FB9B, 0x00F93C, 0x0011F2, 0x00FB60,
+ 0x0011C8, 0x00FB64, 0x00FB68, 0x00FAA1, 0x00FB65, 0x00FB66, 0x0011C2, 0x00FB48,
+ 0x00FB6A, 0x00FB69, 0x00FB6B, 0x00FB4C, 0x00FB4D, 0x00FB4E, 0x00FB4F, 0x00FB6C,
+ 0x0011A4, 0x0011AE, 0x0011A2, 0x00FB6E, 0x0011A8, 0x0011A5, 0x0011A6, 0x0011A7,
+ 0x00FB6F, 0x0011A9, 0x0011AA, 0x0011AB, 0x0011AC, 0x0011AF, 0x00FB6D, 0x001114,
+ 0x0011DC, 0x00FD97, 0x00FB63, 0x00FB7C, 0x00FA5D, 0x0011AD, 0x00108E, 0x00FB61,
+ 0x0011B8, 0x0011B9, 0x00FB62, 0x00FDB1, 0x001116, 0x0011BD, 0x0011BE, 0x0011BF,
+ 0x00FB71, 0x00FB7D, 0x00FB7F, 0x00FB74, 0x00FB75, 0x00FB76, 0x0011C3, 0x00FB78,
+ 0x00FB79, 0x00FB7A, 0x00A5E0, 0x00FB7E, 0x00A840, 0x00A84F, 0x00FB7B, 0x00A843,
+ 0x00A846, 0x00A845, 0x00A849, 0x00A5C9, 0x00A5C8, 0x00A5CE, 0x00A848, 0x00A847,
+ 0x00A84E, 0x00A84A, 0x0011D3, 0x0011D2, 0x00A84C, 0x00A873, 0x00A872, 0x00A84D,
+ 0x0014B2, 0x0011DD, 0x00A85C, 0x00A870, 0x0014B3, 0x0011DF, 0x00FA92, 0x00FA82,
+ 0x00A5FE, 0x0011F3, 0x00A5E3, 0x00A5E1, 0x0011DE, 0x00148C, 0x0011D8, 0x00A5F8,
+ 0x00A5E2, 0x0011D1, 0x0011D9, 0x0011D5, 0x0011D4, 0x00A86B, 0x0011D6, 0x0011D7,
+ 0x0011DB, 0x0011DA, 0x00A5F9, 0x00A5F1, 0x00A5F2, 0x00A5F3, 0x00A5F0, 0x00A5F5,
+ 0x00A5F4, 0x00A5FF, 0x0011A3, 0x00A5F6, 0x00A5F7, 0x00A5FB, 0x0011A1, 0x00FB22,
+ 0x00118D, 0x00A5FA, 0x00AB21, 0x00A5A0, 0x00A986, 0x00A98E, 0x00A9A5, 0x00A987,
+ 0x00A989, 0x00A5C5, 0x00AB38, 0x00AB25, 0x00FA91, 0x00A98B, 0x00FA9F, 0x00AB0D,
+ 0x00AB0C, 0x00A5DE, 0x00A5C3, 0x00A5DF, 0x00AB36, 0x00AB37, 0x00A5D8, 0x00AB39,
+ 0x00A5C2, 0x00AB3F, 0x00A99D, 0x00AB3A, 0x00AB3D, 0x00A9B0, 0x0011BA, 0x00AB34,
+ 0x00AB3E, 0x00A5D9, 0x00A5A2, 0x00A5CB, 0x00AB33, 0x00A5A3, 0x00A5A7, 0x00A5CF,
+ 0x00A5BC, 0x00A5C4, 0x00A5CD, 0x00A9A3, 0x00AB31, 0x00A5CC, 0x00A98D, 0x00A5A1,
+ 0x00AB30, 0x00A9B1, 0x00AB35, 0x00A5B1, 0x00AB32, 0x00A5BD, 0x00A5B4, 0x00A5BE,
+ 0x00A5B0, 0x00AB3B, 0x00A5B8, 0x00A5B9, 0x00A5BA, 0x00A5BB, 0x00A5B6, 0x00A5A6,
+ 0x00A5BF, 0x00A5B7, 0x00A9A8, 0x0011C0, 0x00FA81, 0x00AB52, 0x00FA93, 0x00FB40,
+ 0x00AB51, 0x00FB44, 0x00A98C, 0x00FBA4, 0x00FA87, 0x00AB50, 0x00FB46, 0x00FB4A,
+ 0x00FB5D, 0x00FB67, 0x00FB93, 0x00A5D5, 0x00FB73, 0x00FBA6, 0x00FAA5, 0x00FAAB,
+ 0x00FB5E, 0x00FB91, 0x00FB92, 0x00AB53, 0x00FBA9, 0x00FBAA, 0x00A5DB, 0x00A9D1,
+ 0x00A5D4, 0x00A5DC, 0x00A9AA, 0x00FA97, 0x00A9A4, 0x00FBA5, 0x00FB77, 0x00FBA2,
+ 0x00FB21, 0x00FB20, 0x0011F0, 0x00FBA0, 0x00FB25, 0x00FB26, 0x00FB27, 0x00FB2A,
+ 0x00FB28, 0x00A9AB, 0x00FBA1, 0x00FB24, 0x00FB2F, 0x00FB2B, 0x00AA59, 0x0144EE,
+ 0x001180, 0x001183, 0x001182, 0x00FB2C, 0x001181, 0x00119D, 0x0011B2, 0x00A9A9,
+ 0x001185, 0x00AB57, 0x001187, 0x00FBA7, 0x00FB2D, 0x00FB2E, 0x00119E, 0x00119F,
+ 0x001190, 0x001194, 0x001192, 0x001191, 0x00FB4B, 0x00FB47, 0x001196, 0x001197,
+ 0x001199, 0x00119B, 0x001198, 0x00118C, 0x00119C, 0x001195, 0x00A994, 0x00FB52,
+ 0x00FB51, 0x00118B, 0x00FB53, 0x00FB43, 0x00FB50, 0x00148D, 0x00FB57, 0x001186,
+ 0x00FB54, 0x00A58D, 0x00FB56, 0x00AB22, 0x00AB28, 0x001184, 0x00AB24, 0x001188,
+ 0x00AB26, 0x0011B0, 0x00AB20, 0x00AB2B, 0x00AB2A, 0x00AB29, 0x00AB2C, 0x00AB2D,
+ 0x00AB2E, 0x00FB58, 0x0011B4, 0x001189, 0x00FB59, 0x0011D0, 0x00118A, 0x00FB5A,
+ 0x00118F, 0x00FB5B, 0x0011BC, 0x00FB55, 0x00FB41, 0x00FBAB, 0x001130, 0x00FB5F,
+ 0x0011A0, 0x00AB3C, 0x00A58C, 0x00AA40, 0x00AA41, 0x00AA42, 0x00AA4B, 0x00AA45,
+ 0x00F911, 0x00FB82, 0x00F917, 0x00F910, 0x00FB88, 0x00FB8E, 0x00AA44, 0x00F952,
+ 0x00FB81, 0x00AA47, 0x00118E, 0x00F916, 0x00A5B2, 0x00FB8F, 0x00FB80, 0x00FB85,
+ 0x00FB86, 0x00FB87, 0x00AA58, 0x00FB9C, 0x00FB95, 0x00F912, 0x00F913, 0x00AA48,
+ 0x00AA49, 0x00AA4A, 0x00AA66, 0x00FB9D, 0x00FB9E, 0x00FB9F, 0x00A5B3, 0x00F928,
+ 0x00AA74, 0x0011B1, 0x00FBB1, 0x0011B5, 0x00FBA3, 0x00F92E, 0x0011B7, 0x001112,
+ 0x00F941, 0x0011BB, 0x00F92F, 0x00F91A, 0x00F919, 0x00AA72, 0x00F91B, 0x00F942,
+ 0x00F946, 0x00F940, 0x00F951, 0x00AA71, 0x00F94B, 0x00F947, 0x00F915, 0x00FAD7,
+ 0x00AA73, 0x001193, 0x00AB01, 0x00F918, 0x00AB23, 0x00F914, 0x00AB16, 0x00FC41,
+ 0x00F953, 0x00FC43, 0x00FC42, 0x00F91D, 0x00FC44, 0x00FC47, 0x00F91C, 0x00FC49,
+ 0x00FC48, 0x00FC4B, 0x00FC4A, 0x00FC4D, 0x00FC4C, 0x00FC4F, 0x00F91F, 0x00F900,
+ 0x00AB12, 0x00F902, 0x00F903, 0x00AB11, 0x00F901, 0x00AB13, 0x00F907, 0x00F906,
+ 0x00F978, 0x00F90E, 0x00A628, 0x00A629, 0x00FC5C, 0x00F91E, 0x00F95E, 0x00FC61,
+ 0x00FC60, 0x00FC63, 0x00FC62, 0x00FC65, 0x00FC64, 0x00FC67, 0x00A62B, 0x00FC69,
+ 0x00FC68, 0x00FC6B, 0x00FC6A, 0x00FC6D, 0x00FC6C, 0x00FC6F, 0x00FC6E, 0x00FC71,
+ 0x00FC70, 0x00FC73, 0x00FC72, 0x00FC75, 0x00FC74, 0x00FC77, 0x00FC76, 0x00FC79,
+ 0x00FC78, 0x00FC7B, 0x00FC7A, 0x00FC7D, 0x00FC7C, 0x00FC7F, 0x00FC7E, 0x00A912,
+ 0x00A640, 0x00A64F, 0x00A914, 0x00A91B, 0x00A65E, 0x00A643, 0x00A915, 0x00A65C,
+ 0x00A65A, 0x00AB15, 0x00A658, 0x00A65F, 0x00A651, 0x00A652, 0x00A65D, 0x00A650,
+ 0x00A655, 0x00A657, 0x00A659, 0x00A64B, 0x00A642, 0x00A65B, 0x00A64A, 0x00A654,
+ 0x00A656, 0x00A645, 0x00A644, 0x00A664, 0x00A64E, 0x00A64C, 0x00A66B, 0x00A64D,
+ 0x00A646, 0x00A647, 0x00F905, 0x00F904, 0x00A649, 0x00ABCE, 0x00AB04, 0x00A648,
+ 0x00ABC8, 0x00ABCF, 0x00AB0E, 0x00A930, 0x00ABF4, 0x00F90B, 0x00ABF5, 0x00A895,
+ 0x00AB14, 0x00AB05, 0x00F932, 0x00AB0B, 0x00A91A, 0x00AB0A, 0x00F931, 0x00A940,
+ 0x00AB09, 0x00A973, 0x00FB96, 0x00ABC1, 0x00120D, 0x00120C, 0x00ABA4, 0x00ABA5,
+ 0x00F9E1, 0x00F9E2, 0x00F9EE, 0x00F9ED, 0x00ABAE, 0x00F9CD, 0x00AB8C, 0x00AB8D,
+ 0x00F9C9, 0x00F9CA, 0x00ABC4, 0x00F9CE, 0x00ABC2, 0x014419, 0x00F9EB, 0x00ABC5,
+ 0x00ABC6, 0x00ABC9, 0x01443F, 0x00ABC0, 0x00ABCA, 0x00ABCB, 0x00ABC7, 0x00ABAD,
+ 0x00AB9E, 0x00F9EA, 0x00F9DB, 0x00ABAA, 0x00F9EC, 0x00AA46, 0x00ABA8, 0x00ABF1,
+ 0x00ABA3, 0x001230, 0x001233, 0x014407, 0x001235, 0x001234, 0x001237, 0x001236,
+ 0x00F9E5, 0x001238, 0x00123B, 0x00F9E7, 0x00123D, 0x00ABB1, 0x00123F, 0x00123E,
+ 0x001241, 0x001240, 0x001243, 0x001242, 0x001245, 0x00ABB0, 0x001247, 0x001246,
+ 0x00ABB6, 0x00A89E, 0x00F9F3, 0x00124A, 0x00F9F8, 0x00ABD9, 0x00ABD4, 0x00F982,
+ 0x00F985, 0x00F987, 0x00F983, 0x00A9D9, 0x00A9D8, 0x00A943, 0x00F986, 0x00F984,
+ 0x00ABDA, 0x00ABDB, 0x00F98B, 0x00ABD5, 0x00ABD6, 0x00125C, 0x00A9D4, 0x00A9D5,
+ 0x001261, 0x00F98A, 0x001263, 0x001262, 0x001265, 0x00F99C, 0x00F989, 0x001266,
+ 0x001269, 0x00A945, 0x00126B, 0x00126A, 0x00F999, 0x00F998, 0x00F99D, 0x00F9A0,
+ 0x00ABD7, 0x00ABC3, 0x00ABDC, 0x00F98D, 0x00ABDE, 0x00ABDD, 0x00A9E9, 0x00F988,
+ 0x00F98F, 0x00A9FE, 0x00A9F2, 0x00A9F1, 0x00A9F3, 0x00127C, 0x00A9F6, 0x00ABDF,
+ 0x00A9F0, 0x00A9F7, 0x00A942, 0x00ABD0, 0x00ABD8, 0x00A9FB, 0x00ABD1, 0x00A9F5,
+ 0x00A9FA, 0x00A9F4, 0x00ABAB, 0x00ABA9, 0x00128D, 0x00128C, 0x00AB95, 0x00A9AE,
+ 0x00ABAF, 0x00A833, 0x00F9D2, 0x00A913, 0x00A9AF, 0x00F9D0, 0x00AB94, 0x00AB9B,
+ 0x00F9D1, 0x00F9DC, 0x00F9E0, 0x00AB87, 0x00F9E4, 0x00F9E6, 0x01E816, 0x01E815,
+ 0x0012A1, 0x0012A0, 0x0012A3, 0x0012A2, 0x0012A5, 0x0012A4, 0x0012A7, 0x0012A6,
+ 0x0012A9, 0x0012A8, 0x0012AB, 0x0012AA, 0x0012AD, 0x0012AC, 0x0012AF, 0x0012AE,
+ 0x01E811, 0x0012B0, 0x0012B3, 0x0012B2, 0x0012B5, 0x0012B4, 0x01E812, 0x01E810,
+ 0x0012B9, 0x0012B8, 0x0012BB, 0x0012BA, 0x0012BD, 0x0012BC, 0x01E81D, 0x0012BE,
+ 0x01E81F, 0x0012C0, 0x0012C3, 0x0012C2, 0x0012C5, 0x0012C4, 0x01E819, 0x01E818,
+ 0x0012C9, 0x01E81A, 0x0012CB, 0x0012CA, 0x0012CD, 0x0012CC, 0x01E814, 0x0012CE,
+ 0x0012D1, 0x0012D0, 0x0012D3, 0x0012D2, 0x0012D5, 0x0012D4, 0x01E81B, 0x0012D6,
+ 0x0012D9, 0x0012D8, 0x0012DB, 0x0012DA, 0x0012DD, 0x0012DC, 0x0012DF, 0x0012DE,
+ 0x01E82D, 0x01E803, 0x0012E3, 0x0012E2, 0x01E802, 0x01E800, 0x01E828, 0x01E801,
+ 0x01E82E, 0x01E82F, 0x01E804, 0x01E805, 0x01E806, 0x01E809, 0x01E80A, 0x01E80B,
+ 0x0012F1, 0x0012F0, 0x0012F3, 0x0012F2, 0x01E808, 0x01E80F, 0x0012F7, 0x0012F6,
+ 0x01E81E, 0x01E81C, 0x0012FB, 0x0012FA, 0x0012FD, 0x0012FC, 0x01E82A, 0x01E821,
+ 0x01E822, 0x01E851, 0x01E850, 0x01E833, 0x01E826, 0x01E827, 0x01E854, 0x01E82B,
+ 0x01E820, 0x01E823, 0x01E80C, 0x01E80D, 0x01E80E, 0x01E825, 0x01E841, 0x01E83D,
+ 0x01E83C, 0x01E85B, 0x01E853, 0x01E843, 0x01E835, 0x01E836, 0x01E839, 0x01E83A,
+ 0x01E852, 0x01E829, 0x01E838, 0x01E83E, 0x01E83F, 0x01E824, 0x01E860, 0x01E861,
+ 0x01E883, 0x00A931, 0x01E863, 0x01E865, 0x01E866, 0x00A9D7, 0x00A904, 0x00A9D2,
+ 0x01E84C, 0x00A941, 0x00A936, 0x01E84D, 0x00A946, 0x00F996, 0x01E891, 0x01E874,
+ 0x01E893, 0x01E892, 0x01E895, 0x01E894, 0x01E876, 0x01E896, 0x01E899, 0x01E87A,
+ 0x01E89B, 0x01E89A, 0x01E89D, 0x01E89C, 0x00A925, 0x01E89E, 0x01E8A1, 0x01E8A0,
+ 0x01E872, 0x01E8A2, 0x01E8A5, 0x01E8A4, 0x01E8A7, 0x01E8A6, 0x00A924, 0x01E8A8,
+ 0x01E8AB, 0x01E87B, 0x00F99A, 0x01E82C, 0x00F99F, 0x00F99E, 0x00F994, 0x00FE80,
+ 0x01E870, 0x01E877, 0x00FEB9, 0x00FEB8, 0x00FE8F, 0x00FE86, 0x00FE87, 0x00FE88,
+ 0x00FE89, 0x00FE8A, 0x00FE8B, 0x00FEBB, 0x00FE8D, 0x00FE8E, 0x01E8C1, 0x01E8C0,
+ 0x01E842, 0x01E8C2, 0x01E840, 0x01E8C4, 0x01E8C7, 0x01E847, 0x01E8C9, 0x01E8C8,
+ 0x01E8CB, 0x01E84B, 0x01E845, 0x00FE9D, 0x01E8CF, 0x01E846, 0x00FEB5, 0x01E849,
+ 0x01E867, 0x00FEBA, 0x01E85E, 0x01E855, 0x01E856, 0x01E857, 0x01E858, 0x01E859,
+ 0x01E85A, 0x00FE79, 0x01E85C, 0x01E85D, 0x01E84E, 0x01E85F, 0x00FEBF, 0x00FEB0,
+ 0x00FED1, 0x00FED2, 0x00FEB3, 0x00FEB4, 0x00FEB1, 0x00FED6, 0x00FED7, 0x00FEA2,
+ 0x00FEBC, 0x01E871, 0x00148E, 0x00FE78, 0x01E844, 0x00FEB7, 0x00FEB6, 0x00FEA5,
+ 0x01E848, 0x01E84F, 0x00FE72, 0x00FE70, 0x01E873, 0x00FE77, 0x00FEA7, 0x00FEAB,
+ 0x00FE7B, 0x00FE7A, 0x00FEAC, 0x01E84A, 0x00FE74, 0x00FE76, 0x01E901, 0x01E900,
+ 0x01E903, 0x01E902, 0x01E905, 0x01E904, 0x01E907, 0x01E906, 0x01E909, 0x01E908,
+ 0x01E90B, 0x01E90A, 0x01E90D, 0x01E90C, 0x01E90F, 0x01E90E, 0x01E911, 0x01E910,
+ 0x01E913, 0x01E912, 0x00FEA1, 0x00FEA0, 0x00FED0, 0x01E916, 0x01E919, 0x01E918,
+ 0x01E91B, 0x01E91A, 0x00FE71, 0x01E91C, 0x01E91F, 0x01E91E, 0x01E921, 0x01E920,
+ 0x01E923, 0x01E922, 0x00FEA3, 0x00FEA4, 0x00FE73, 0x01E926, 0x01E929, 0x01E928,
+ 0x01E92B, 0x01E92A, 0x00FEBD, 0x01E92C, 0x01E92F, 0x00FEBE, 0x01E931, 0x01E930,
+ 0x01E933, 0x01E932, 0x00FEB2, 0x01E934, 0x01E937, 0x01E936, 0x01E939, 0x01E938,
+ 0x01E93B, 0x01E93A, 0x01E93D, 0x01E93C, 0x01E93F, 0x01E93E, 0x01E941, 0x01E940,
+ 0x01E943, 0x01E942, 0x00FA90, 0x01E864, 0x00FA83, 0x00FAA2, 0x01E86E, 0x00FA80,
+ 0x01E868, 0x01E869, 0x00FAA0, 0x01E86D, 0x01E86C, 0x00FA95, 0x01E951, 0x01E950,
+ 0x01E953, 0x01E952, 0x01E955, 0x01E954, 0x01E957, 0x01E956, 0x01E959, 0x01E958,
+ 0x00FA9B, 0x00FC46, 0x00FE83, 0x00FE84, 0x00148F, 0x00FA86, 0x00FAA7, 0x00FE82,
+ 0x001504, 0x001505, 0x01E87C, 0x00FA8F, 0x00FE81, 0x01E862, 0x00151E, 0x01E87D,
+ 0x00FE85, 0x00FE8C, 0x00FE9C, 0x00151F, 0x01E86A, 0x01E86B, 0x00FA99, 0x01E878,
+ 0x001509, 0x001518, 0x01E875, 0x00151A, 0x01E86F, 0x01E87E, 0x001517, 0x00FE9A,
+ 0x001519, 0x00151C, 0x01E879, 0x00FA85, 0x01E87F, 0x00FE95, 0x00151B, 0x00FE90,
+ 0x00FE9B, 0x00FE92, 0x00FE93, 0x0014AE, 0x0014AF, 0x00FE94, 0x00FE97, 0x001506,
+ 0x00150A, 0x00150B, 0x00FE91, 0x00FE96, 0x00150E, 0x0014A8, 0x001508, 0x00150F,
+ 0x001488, 0x001461, 0x0011CB, 0x00FAB3, 0x001117, 0x0011C5, 0x00FAD1, 0x0011E0,
+ 0x00FAC3, 0x00FAD2, 0x00FAD3, 0x00FE7C, 0x00147C, 0x0014AD, 0x00146C, 0x00FE7D,
+ 0x00FE9E, 0x001440, 0x001443, 0x001442, 0x00FE7E, 0x001441, 0x001447, 0x001444,
+ 0x00FE99, 0x00FE7F, 0x00FE9F, 0x00FE98, 0x00144A, 0x001445, 0x001446, 0x00144B,
+ 0x001470, 0x001479, 0x001478, 0x00147D, 0x001462, 0x00144D, 0x00144E, 0x00147F,
+ 0x001449, 0x00FF4D, 0x00FF4F, 0x00FF4C, 0x001448, 0x00145C, 0x00144F, 0x00FF11,
+ 0x00FF10, 0x00FF13, 0x00FF12, 0x00FF15, 0x00FF14, 0x00FF17, 0x00FF16, 0x00FF19,
+ 0x00147E, 0x001463, 0x00147A, 0x00147B, 0x00FF7D, 0x00FF7E, 0x00FF7F, 0x00FF78,
+ 0x00FF7B, 0x00FF6E, 0x00FF6D, 0x00FF6C, 0x00FF66, 0x00FF67, 0x00FF79, 0x00FF6B,
+ 0x00FF68, 0x00FF7C, 0x00FF6A, 0x00FF6F, 0x00FF69, 0x00FF74, 0x001474, 0x00FF31,
+ 0x00FF30, 0x00FF33, 0x00FF32, 0x00FF35, 0x00FF34, 0x00FF71, 0x00FF73, 0x00FF39,
+ 0x00FF38, 0x00FF72, 0x00FF3A, 0x00FF7A, 0x00FF75, 0x00FF76, 0x00FF77, 0x0011C7,
+ 0x00FF42, 0x0014A0, 0x0014A3, 0x00F96C, 0x00F975, 0x0014A1, 0x0014A4, 0x00FF41,
+ 0x00FF43, 0x00F94A, 0x00F949, 0x0014AB, 0x0014A5, 0x00F962, 0x00F94F, 0x0014A7,
+ 0x00FF47, 0x00FF46, 0x00F94D, 0x00F977, 0x00F94E, 0x0011CE, 0x00F973, 0x00F971,
+ 0x00F948, 0x00F976, 0x00F97B, 0x00F974, 0x00F97A, 0x0011F5, 0x00F97E, 0x00FAB7,
+ 0x00FF45, 0x00F968, 0x00FA9A, 0x00FA94, 0x0145A8, 0x00FB83, 0x00FF44, 0x00F94C,
+ 0x0014A2, 0x0145A4, 0x0014BC, 0x0145AE, 0x0145AB, 0x0145A9, 0x0145A2, 0x0145A3,
+ 0x0145AF, 0x0145AD, 0x00FF4E, 0x0145AA, 0x00FF48, 0x00F96D, 0x00F972, 0x00FF49,
+ 0x00F96E, 0x00FF4B, 0x00FF4A, 0x00F970, 0x0145AC, 0x00F96F, 0x0145BD, 0x00FF81,
+ 0x00FF80, 0x00FF83, 0x00FF82, 0x00FF85, 0x00FAA6, 0x00FF87, 0x00FF86, 0x00FF89,
+ 0x0145D0, 0x0145DF, 0x00FF8A, 0x0145D6, 0x00FF8C, 0x0145C1, 0x0145DC, 0x00FF91,
+ 0x0145D4, 0x00FF93, 0x00FF92, 0x0145DD, 0x00FF94, 0x00FF97, 0x0145D3, 0x00FF99,
+ 0x00FF98, 0x00FF9B, 0x00FF9A, 0x00FF9D, 0x00FF9C, 0x0014A9, 0x0145D2, 0x00FEA9,
+ 0x0145DA, 0x0145D5, 0x0145D7, 0x0145D1, 0x0145C3, 0x00FEAF, 0x00FEA6, 0x0014F4,
+ 0x00FEA8, 0x0014AA, 0x0014FB, 0x0145C2, 0x01E813, 0x0145C6, 0x00FEAA, 0x00FFB1,
+ 0x0145C0, 0x00FFB3, 0x00FFB2, 0x0145C7, 0x00FEAD, 0x00FA22, 0x0145FD, 0x001093,
+ 0x00FA21, 0x00FEAE, 0x001092, 0x001081, 0x0145D8, 0x0145D9, 0x0145DE, 0x0145FE,
+ 0x00FED8, 0x00FFC3, 0x00FFC2, 0x00FFC5, 0x00FFC4, 0x00FFC7, 0x00FFC6, 0x0010B1,
+ 0x001110, 0x00FFCB, 0x00FFCA, 0x00FFCD, 0x00FFCC, 0x00FFCF, 0x00FFCE, 0x00FED4,
+ 0x00FA41, 0x00FA42, 0x0010B2, 0x0010B3, 0x00111C, 0x00FED3, 0x00110C, 0x001113,
+ 0x0015EE, 0x00FA50, 0x001111, 0x00FA84, 0x00FFDC, 0x00FA96, 0x00FEDB, 0x0015EF,
+ 0x00F961, 0x00F960, 0x00F963, 0x00F966, 0x001102, 0x00FA40, 0x00F967, 0x001489,
+ 0x00F969, 0x00F96A, 0x00F96B, 0x001103, 0x0015EC, 0x00148A, 0x00F965, 0x00FA20,
+ 0x001090, 0x001091, 0x00148B, 0x00FED5, 0x00F97D, 0x00FA9D, 0x00FA27, 0x00FEDA,
+ 0x00FEDF, 0x00F979, 0x00FED9, 0x00F97F, 0x0015E6, 0x00FEDE, 0x00FEDD, 0x0015CE,
+ 0x0015EA, 0x010003, 0x010034, 0x0015E4, 0x010007, 0x0015E9, 0x010035, 0x010018,
+ 0x010039, 0x01003A, 0x01003F, 0x01001C, 0x01001D, 0x01001E, 0x01001F, 0x010011,
+ 0x010010, 0x0015E1, 0x010012, 0x010016, 0x010014, 0x0015E5, 0x0015E2, 0x01001B,
+ 0x0015ED, 0x0015E0, 0x01001A, 0x010019, 0x010015, 0x010017, 0x0015E7, 0x010031,
+ 0x0015F0, 0x0015F1, 0x0015F8, 0x0015EB, 0x0015F4, 0x010030, 0x010037, 0x0015F7,
+ 0x0015E8, 0x0015F9, 0x0015FA, 0x0015FB, 0x0015FC, 0x010036, 0x0015FE, 0x0015FF,
+ 0x0015C0, 0x0015C1, 0x0015BF, 0x0015C3, 0x0015B9, 0x0015B4, 0x00158C, 0x0015C5,
+ 0x0015C2, 0x001513, 0x0015BB, 0x0015BA, 0x010032, 0x0015C7, 0x0015C4, 0x010041,
+ 0x0015DE, 0x0015D0, 0x0015B6, 0x0015DF, 0x0015D7, 0x0015DD, 0x0015B5, 0x0015D4,
+ 0x0015D9, 0x0015CB, 0x0015DB, 0x0015D8, 0x0015DC, 0x0015C6, 0x0015DA, 0x010051,
+ 0x0015CF, 0x010059, 0x010052, 0x0015B7, 0x010050, 0x010055, 0x0015B0, 0x010056,
+ 0x01005B, 0x010043, 0x0015CA, 0x0011FC, 0x0015C8, 0x0015C9, 0x010042, 0x010020,
+ 0x0015B3, 0x010022, 0x010023, 0x010026, 0x001501, 0x010054, 0x010021, 0x010029,
+ 0x01002B, 0x01005A, 0x010058, 0x0015B2, 0x010025, 0x010024, 0x01002F, 0x0011F6,
+ 0x010040, 0x0015F3, 0x0011C1, 0x0011F8, 0x01004B, 0x001515, 0x0015F2, 0x010038,
+ 0x0015A8, 0x010028, 0x0015F6, 0x0015FD, 0x01003D, 0x0011C6, 0x0015AE, 0x0015AF,
+ 0x001512, 0x010081, 0x0015E3, 0x010080, 0x010087, 0x001511, 0x010082, 0x01008B,
+ 0x010088, 0x01008F, 0x0011CC, 0x010085, 0x010084, 0x0015F5, 0x010086, 0x0011F7,
+ 0x001500, 0x010093, 0x001502, 0x001503, 0x0015CC, 0x0015A2, 0x001484, 0x001507,
+ 0x0015A0, 0x0011F1, 0x0015CD, 0x0015A3, 0x0011CA, 0x0015AB, 0x0015A6, 0x0015A7,
+ 0x001510, 0x0015A9, 0x0100A0, 0x001516, 0x0015AA, 0x0100A7, 0x0011C4, 0x001514,
+ 0x0015BC, 0x0015BE, 0x00151D, 0x0015AD, 0x0015B8, 0x0015BD, 0x0015A4, 0x0015A5,
+ 0x0100B0, 0x0100B1, 0x0100B2, 0x0100B7, 0x0100B4, 0x0100B5, 0x0100B6, 0x0100BB,
+ 0x0100B8, 0x001641, 0x001602, 0x001603, 0x001605, 0x0100BF, 0x00168E, 0x001606,
+ 0x0100C0, 0x0100C3, 0x001610, 0x010045, 0x010047, 0x0100C7, 0x010046, 0x010048,
+ 0x010049, 0x01004A, 0x01004D, 0x01005C, 0x010044, 0x00168D, 0x01004C, 0x0100D1,
+ 0x0100D0, 0x001613, 0x0100D2, 0x0100D5, 0x0100D4, 0x0100D7, 0x0100D6, 0x0100D9,
+ 0x0100D8, 0x0100DB, 0x0100DA, 0x0100DD, 0x01005D, 0x0100DF, 0x0100DE, 0x001633,
+ 0x0100E0, 0x0100E3, 0x0016B0, 0x001631, 0x001632, 0x0100E7, 0x0016B7, 0x0016B6,
+ 0x0016BE, 0x0016B9, 0x0016BA, 0x0016BB, 0x0016B5, 0x001618, 0x0016BD, 0x0100F1,
+ 0x0100F0, 0x00161D, 0x0100F2, 0x0100F5, 0x0100F4, 0x0100F7, 0x0100F6, 0x0100F9,
+ 0x0100F8, 0x00161A, 0x0100FA, 0x001643, 0x00165C, 0x001646, 0x00161F, 0x001642,
+ 0x01010B, 0x001611, 0x001612, 0x01011C, 0x01011D, 0x001615, 0x010131, 0x001617,
+ 0x010118, 0x001619, 0x01011F, 0x00161B, 0x001614, 0x001616, 0x01011E, 0x010111,
+ 0x00163A, 0x010113, 0x010112, 0x010110, 0x00161C, 0x010117, 0x010116, 0x01011B,
+ 0x010109, 0x01010A, 0x01010D, 0x010114, 0x010115, 0x01011A, 0x010119, 0x010108,
+ 0x010120, 0x01010C, 0x010122, 0x010121, 0x01010F, 0x01010E, 0x010107, 0x010129,
+ 0x00163B, 0x01012B, 0x01012A, 0x010124, 0x010125, 0x010126, 0x010127, 0x00161E,
+ 0x0016B1, 0x00168A, 0x001683, 0x001682, 0x001681, 0x001686, 0x001684, 0x010132,
+ 0x010128, 0x001687, 0x0016B4, 0x01012D, 0x01012C, 0x01012F, 0x01012E, 0x01015D,
+ 0x010140, 0x010141, 0x010142, 0x010147, 0x01015C, 0x00168C, 0x01015E, 0x01E915,
+ 0x001640, 0x001645, 0x01015F, 0x001647, 0x00160C, 0x00164E, 0x001644, 0x010151,
+ 0x010150, 0x010157, 0x010152, 0x010155, 0x010154, 0x010153, 0x010156, 0x010159,
+ 0x001672, 0x001677, 0x01015A, 0x010158, 0x001676, 0x01015B, 0x0016B3, 0x010130,
+ 0x001648, 0x010163, 0x010143, 0x0016B2, 0x001634, 0x001660, 0x00163E, 0x001685,
+ 0x001638, 0x001639, 0x001689, 0x00168B, 0x00163D, 0x00163F, 0x0016EF, 0x010172,
+ 0x010123, 0x010170, 0x010133, 0x010176, 0x010171, 0x010174, 0x010175, 0x0016C3,
+ 0x0016C2, 0x010178, 0x0016C0, 0x001699, 0x0016C6, 0x0016C1, 0x010177, 0x0016C7,
+ 0x0016C5, 0x001691, 0x0016C4, 0x001693, 0x001692, 0x001697, 0x001694, 0x01018B,
+ 0x001698, 0x0016CB, 0x01018A, 0x00169A, 0x0016CA, 0x0016DC, 0x001696, 0x001695,
+ 0x0016E1, 0x0016E0, 0x0016E3, 0x0016E2, 0x0016E7, 0x0016CD, 0x001673, 0x0016F4,
+ 0x0016C9, 0x0016CE, 0x0012C8, 0x001671, 0x0016CC, 0x001485, 0x001674, 0x00164C,
+ 0x0016E5, 0x0016F2, 0x0016F3, 0x0016E4, 0x0016E6, 0x0016F1, 0x0016F7, 0x0016F5,
+ 0x0016E8, 0x0016F0, 0x0016EA, 0x0016E9, 0x0016F8, 0x00164A, 0x0016EE, 0x0016F6,
+ 0x001701, 0x001700, 0x001703, 0x001702, 0x001705, 0x001704, 0x001707, 0x001706,
+ 0x001709, 0x001708, 0x00170B, 0x00170A, 0x001486, 0x00170C, 0x00170F, 0x00170E,
+ 0x001487, 0x001710, 0x001711, 0x001480, 0x001481, 0x001482, 0x001483, 0x00149C,
+ 0x00149D, 0x00125D, 0x00149E, 0x00149F, 0x001498, 0x00167D, 0x00167E, 0x01E92D,
+ 0x001721, 0x001720, 0x001723, 0x001722, 0x001725, 0x001661, 0x001727, 0x001726,
+ 0x001729, 0x001769, 0x00172B, 0x00172A, 0x00176C, 0x00172C, 0x00176E, 0x001667,
+ 0x001731, 0x001730, 0x001499, 0x00167F, 0x001665, 0x001664, 0x00149A, 0x00149B,
+ 0x001494, 0x001669, 0x00166B, 0x001495, 0x00166C, 0x001496, 0x001497, 0x00166F,
+ 0x001741, 0x000F5D, 0x001743, 0x001742, 0x001745, 0x001747, 0x00164F, 0x001744,
+ 0x001649, 0x001740, 0x00174B, 0x00164B, 0x00166A, 0x00174C, 0x001746, 0x00174A,
+ 0x001751, 0x001750, 0x001765, 0x01031C, 0x001766, 0x00164D, 0x010304, 0x01030A,
+ 0x001748, 0x001749, 0x00176A, 0x00176B, 0x001768, 0x00174D, 0x00174E, 0x00174F,
+ 0x000F5C, 0x001670, 0x001678, 0x0012CF, 0x01030F, 0x010307, 0x01031E, 0x010309,
+ 0x010318, 0x01031A, 0x00167C, 0x00167A, 0x001763, 0x010308, 0x010339, 0x001679,
+ 0x001760, 0x001668, 0x001770, 0x001762, 0x010333, 0x01033F, 0x001675, 0x001761,
+ 0x010331, 0x00167B, 0x001662, 0x010332, 0x010335, 0x001663, 0x001666, 0x001767,
+ 0x001781, 0x001784, 0x001783, 0x001782, 0x001785, 0x001780, 0x001787, 0x001786,
+ 0x001799, 0x001798, 0x00178B, 0x00178A, 0x00179D, 0x001789, 0x00179F, 0x00179E,
+ 0x001791, 0x01030E, 0x001793, 0x00178E, 0x00178D, 0x001794, 0x00178F, 0x001792,
+ 0x001790, 0x00179C, 0x00179B, 0x00179A, 0x001788, 0x001795, 0x001796, 0x001797,
+ 0x001490, 0x0017A3, 0x001491, 0x0017A1, 0x0017A6, 0x0017A7, 0x0017A2, 0x0017A5,
+ 0x0017A0, 0x001492, 0x01E92E, 0x0017A9, 0x00178C, 0x0017AC, 0x01E897, 0x00122D,
+ 0x0017B1, 0x0017B2, 0x0017B3, 0x0017B0, 0x010334, 0x0010C0, 0x001231, 0x010338,
+ 0x00122C, 0x01033B, 0x01033A, 0x01030C, 0x01030D, 0x01033E, 0x001493, 0x0010E2,
+ 0x00158D, 0x00156C, 0x010323, 0x010330, 0x01E8B2, 0x0010F3, 0x00123C, 0x01E8B1,
+ 0x001250, 0x00156D, 0x01E8B0, 0x001253, 0x01E8B6, 0x010336, 0x001252, 0x01E8B3,
+ 0x00156E, 0x00156F, 0x0102A7, 0x001255, 0x010295, 0x001225, 0x01E8B7, 0x010298,
+ 0x0102A0, 0x0102A4, 0x01029B, 0x01E8BB, 0x0102A6, 0x0017DC, 0x001251, 0x010292,
+ 0x0017E1, 0x0017E2, 0x0017E3, 0x0017E0, 0x0017E5, 0x0017E6, 0x0017E7, 0x0017E4,
+ 0x0017E9, 0x0017E8, 0x010291, 0x010290, 0x010294, 0x010297, 0x010296, 0x001100,
+ 0x001239, 0x0017F2, 0x0017F0, 0x001568, 0x01E89F, 0x0017F1, 0x0017F3, 0x0017F4,
+ 0x0017F9, 0x001569, 0x0102A2, 0x0102A1, 0x0017F5, 0x0017F8, 0x0017F7, 0x0017F6,
+ 0x000F5E, 0x00186E, 0x001853, 0x001866, 0x001864, 0x001865, 0x001867, 0x00183C,
+ 0x001868, 0x001869, 0x00186A, 0x00186B, 0x000F5F, 0x00186D, 0x000EDD, 0x00186F,
+ 0x001835, 0x000F58, 0x000ED8, 0x000ED9, 0x000EDE, 0x000EDF, 0x01E882, 0x0102E8,
+ 0x0102ED, 0x01E88B, 0x0102EB, 0x0102EC, 0x0102D0, 0x0102EE, 0x0102EF, 0x00156A,
+ 0x001833, 0x001831, 0x00183D, 0x001830, 0x001837, 0x001850, 0x001832, 0x001875,
+ 0x001862, 0x001863, 0x001836, 0x001857, 0x001874, 0x001861, 0x001860, 0x0102E1,
+ 0x0102E4, 0x001852, 0x0102E2, 0x0102E6, 0x0102A5, 0x0102E7, 0x001851, 0x0102A8,
+ 0x0102A9, 0x0102AA, 0x0102AB, 0x0102AC, 0x0102AD, 0x0102C3, 0x0102AF, 0x0102E5,
+ 0x001841, 0x001840, 0x0102E9, 0x001842, 0x001845, 0x001844, 0x001847, 0x001846,
+ 0x001849, 0x001848, 0x00184B, 0x00184A, 0x00182D, 0x0102EA, 0x00184F, 0x00184E,
+ 0x001871, 0x00182C, 0x010313, 0x001872, 0x010364, 0x001870, 0x001877, 0x010348,
+ 0x010349, 0x010368, 0x010369, 0x001876, 0x01036F, 0x00185C, 0x01036B, 0x00184D,
+ 0x001822, 0x001821, 0x001820, 0x001823, 0x001826, 0x001825, 0x00184C, 0x001827,
+ 0x00182A, 0x010312, 0x00182B, 0x010311, 0x00182E, 0x010315, 0x00182F, 0x010321,
+ 0x010320, 0x001829, 0x010322, 0x001828, 0x010360, 0x010361, 0x010362, 0x001834,
+ 0x010366, 0x001873, 0x010367, 0x01032D, 0x00183A, 0x01032F, 0x01032E, 0x00183B,
+ 0x000ED2, 0x014624, 0x000ED3, 0x010374, 0x010375, 0x01E8A3, 0x000ED6, 0x00156B,
+ 0x01462A, 0x001564, 0x000EAE, 0x000EAD, 0x01462B, 0x000EAF, 0x010365, 0x010341,
+ 0x010343, 0x010347, 0x010342, 0x01035D, 0x0103CD, 0x01035F, 0x010340, 0x0103C8,
+ 0x010359, 0x01035C, 0x0103CB, 0x0103CE, 0x0103CC, 0x010346, 0x0103CF, 0x010352,
+ 0x01EE03, 0x010353, 0x0103C3, 0x010350, 0x010351, 0x010354, 0x010355, 0x010310,
+ 0x010358, 0x01035E, 0x01035A, 0x010356, 0x01035B, 0x010357, 0x01EE11, 0x01EE10,
+ 0x01EE13, 0x01EE12, 0x01EE15, 0x01EE14, 0x01EE17, 0x01EE16, 0x01EE19, 0x01EE18,
+ 0x01EE1B, 0x01EE1A, 0x01EE1D, 0x01EE1C, 0x01EE1F, 0x01EE1E, 0x01EE21, 0x010345,
+ 0x010344, 0x01EE22, 0x010372, 0x01EE24, 0x01EE27, 0x010373, 0x01EE29, 0x010371,
+ 0x01EE2B, 0x01EE2A, 0x010370, 0x01EE2C, 0x01EE2F, 0x01034A, 0x01EE31, 0x01EE30,
+ 0x010394, 0x010381, 0x010382, 0x010380, 0x01EE37, 0x010384, 0x010386, 0x01039A,
+ 0x0103CA, 0x0103AF, 0x01038F, 0x010385, 0x01039B, 0x010387, 0x010399, 0x0103A2,
+ 0x01030B, 0x010393, 0x0103C9, 0x01EEA1, 0x01EE47, 0x010392, 0x010302, 0x01038B,
+ 0x01EE4B, 0x010300, 0x010391, 0x010390, 0x010397, 0x010396, 0x010395, 0x010303,
+ 0x0103B4, 0x01EE52, 0x010383, 0x01EE06, 0x0103A7, 0x01EE02, 0x0103B5, 0x00186C,
+ 0x0103B9, 0x0103B8, 0x0103D3, 0x0103BB, 0x0103BD, 0x010319, 0x0103BF, 0x0103B1,
+ 0x0103B0, 0x01EE62, 0x0103B2, 0x01039C, 0x0103B6, 0x0103B7, 0x01EE69, 0x01EE68,
+ 0x010398, 0x01039D, 0x01EE6D, 0x01EE6C, 0x01EE6F, 0x01EE6E, 0x01EE71, 0x01EE70,
+ 0x01031B, 0x0103C0, 0x01EE75, 0x01EE74, 0x01EE77, 0x01EE76, 0x0103C1, 0x010314,
+ 0x01EE7B, 0x010316, 0x001913, 0x0103AD, 0x001901, 0x01031D, 0x010317, 0x001912,
+ 0x01EE91, 0x00190C, 0x01EE90, 0x01EE96, 0x01EE95, 0x01EE97, 0x01EE94, 0x010306,
+ 0x0103D1, 0x0103D2, 0x010301, 0x0103D5, 0x0103D4, 0x0103C2, 0x010305, 0x0103A0,
+ 0x0103A1, 0x010337, 0x0103AB, 0x0103A4, 0x001910, 0x0103A6, 0x01031F, 0x0103A8,
+ 0x001911, 0x0103AA, 0x01EE83, 0x001915, 0x001917, 0x0103A5, 0x0103BE, 0x0103AC,
+ 0x00195A, 0x01EEA2, 0x01EEA5, 0x001956, 0x01EEA7, 0x01EEA6, 0x01EEA9, 0x01EEA8,
+ 0x01EEAB, 0x0103A9, 0x01EEAD, 0x01EEAC, 0x01EEAF, 0x01EEAE, 0x0103AE, 0x00195B,
+ 0x001955, 0x001950, 0x001953, 0x001952, 0x001914, 0x001957, 0x001916, 0x01EE82,
+ 0x001918, 0x001919, 0x00191A, 0x00191B, 0x01EE9B, 0x00191D, 0x00191E, 0x01EE81,
+ 0x01EE80, 0x01EEB6, 0x01EE86, 0x01EE85, 0x01EE84, 0x01EE87, 0x01EE89, 0x01EEB5,
+ 0x01EE88, 0x01EE8B, 0x01EE8D, 0x00185D, 0x01EE8C, 0x01EEB2, 0x01EEB7, 0x001854,
+ 0x01EEB3, 0x01EEB0, 0x001855, 0x01EE8E, 0x001954, 0x01EE8F, 0x001856, 0x01EE9A,
+ 0x001958, 0x001959, 0x00195E, 0x01EE99, 0x01EE98, 0x00195D, 0x01EEB1, 0x00195F,
+ 0x0019B5, 0x001983, 0x001984, 0x0019B6, 0x001986, 0x001981, 0x001982, 0x001985,
+ 0x001989, 0x001980, 0x00198B, 0x00198F, 0x0019D6, 0x001987, 0x00198C, 0x0019BB,
+ 0x001991, 0x001988, 0x001993, 0x001992, 0x0019D1, 0x0019D2, 0x0019D3, 0x00198E,
+ 0x0019D7, 0x001998, 0x00198A, 0x00198D, 0x0019D0, 0x00199C, 0x00199F, 0x00199E,
+ 0x010415, 0x01041A, 0x0019A3, 0x010422, 0x010414, 0x01041F, 0x010416, 0x010420,
+ 0x010421, 0x010424, 0x0019A1, 0x0019A2, 0x010426, 0x010419, 0x01042B, 0x010563,
+ 0x0019D4, 0x010427, 0x0019B3, 0x0019B2, 0x0019D5, 0x0019B0, 0x0019B1, 0x01042F,
+ 0x0019DA, 0x0019BC, 0x0019D8, 0x0019D9, 0x01EE0C, 0x01EE0D, 0x010418, 0x0019B7,
+ 0x010474, 0x0019C3, 0x01EE2D, 0x014601, 0x014600, 0x014606, 0x014607, 0x01EE2E,
+ 0x0019C2, 0x0019C0, 0x010473, 0x01044C, 0x0019C5, 0x0019C1, 0x0019C7, 0x01EE32,
+ 0x010450, 0x010483, 0x01EE34, 0x01EE35, 0x0019C4, 0x01EE36, 0x0019C6, 0x01EEB9,
+ 0x01EE3B, 0x0019C9, 0x01EEB8, 0x00185B, 0x010456, 0x01EE39, 0x00185A, 0x010491,
+ 0x010490, 0x010493, 0x010492, 0x010495, 0x010494, 0x0019A5, 0x0019A6, 0x010499,
+ 0x010498, 0x01049B, 0x01049A, 0x01049D, 0x01049C, 0x010497, 0x010496, 0x0104A1,
+ 0x0104A0, 0x01EE57, 0x0104A2, 0x0104A5, 0x0104A4, 0x0104A7, 0x0104A6, 0x01EE51,
+ 0x01EE59, 0x0019B9, 0x0019BA, 0x01EE54, 0x01EE5B, 0x01EE49, 0x0104A9, 0x0104B1,
+ 0x0104B0, 0x01EE42, 0x0104B2, 0x0104A8, 0x0104B4, 0x0104B7, 0x01EE6A, 0x01EE61,
+ 0x010475, 0x0104BB, 0x01EE67, 0x01EE4D, 0x01EE4E, 0x01EE4F, 0x01EE64, 0x0104C2,
+ 0x01EE72, 0x001B18, 0x001B06, 0x01EE7C, 0x001B14, 0x01EE7E, 0x01EE79, 0x001B1E,
+ 0x01EE7A, 0x0104C1, 0x001B1B, 0x01EE5D, 0x0104C0, 0x01EE5F, 0x0104C3, 0x01EEBA,
+ 0x010470, 0x0104D3, 0x001A82, 0x001A83, 0x001A84, 0x010477, 0x0104C7, 0x0104D9,
+ 0x0104D8, 0x010476, 0x0104DA, 0x0104DD, 0x0104DC, 0x0104DF, 0x0104DE, 0x0104E2,
+ 0x0104E0, 0x0104E3, 0x01EEB4, 0x01EEA3, 0x0104E1, 0x0104E4, 0x0104E5, 0x010428,
+ 0x010425, 0x0104EB, 0x01EEBB, 0x0104E8, 0x0104EF, 0x0104E6, 0x0104E7, 0x0104F1,
+ 0x010451, 0x010452, 0x0104F2, 0x0104F0, 0x0104F4, 0x0104F7, 0x0104F6, 0x0104FB,
+ 0x010472, 0x0104F8, 0x01045B, 0x010471, 0x0104F5, 0x0104FA, 0x0104F9, 0x001A43,
+ 0x001A81, 0x001A41, 0x001A42, 0x001A40, 0x010455, 0x001A46, 0x001A47, 0x010502,
+ 0x010458, 0x001A99, 0x001A96, 0x01045F, 0x001A87, 0x01051C, 0x001A45, 0x010511,
+ 0x010510, 0x010513, 0x001A44, 0x010515, 0x010514, 0x010517, 0x010516, 0x010519,
+ 0x010518, 0x01051B, 0x01051A, 0x01051D, 0x001A4A, 0x01051F, 0x01051E, 0x010501,
+ 0x010500, 0x010507, 0x010522, 0x010520, 0x010521, 0x010527, 0x010506, 0x010505,
+ 0x010503, 0x001A49, 0x001A4B, 0x010524, 0x010525, 0x010526, 0x001A48, 0x001A4F,
+ 0x000AA4, 0x000A21, 0x000A22, 0x000A23, 0x000A15, 0x000AA5, 0x000AA6, 0x000AA7,
+ 0x01047D, 0x000A09, 0x000A08, 0x000A39, 0x000A20, 0x000A27, 0x000A0F, 0x010541,
+ 0x010540, 0x010543, 0x010542, 0x010545, 0x010544, 0x010547, 0x010546, 0x010549,
+ 0x010548, 0x01054B, 0x01054A, 0x01054D, 0x01054C, 0x01054F, 0x01054E, 0x010535,
+ 0x010552, 0x01053D, 0x01050B, 0x010534, 0x010553, 0x010504, 0x010536, 0x010538,
+ 0x010539, 0x01053A, 0x01053B, 0x01053C, 0x01055C, 0x01053E, 0x01053F, 0x010561,
+ 0x010560, 0x000AA1, 0x010562, 0x01F109, 0x01F108, 0x01047A, 0x010479, 0x000AA0,
+ 0x01F10A, 0x010457, 0x01047B, 0x000AB8, 0x001BAE, 0x001BAF, 0x000ABD, 0x010454,
+ 0x01055D, 0x01055E, 0x01055F, 0x010554, 0x010555, 0x010556, 0x001BCF, 0x010532,
+ 0x010537, 0x01055A, 0x010531, 0x010530, 0x010559, 0x010558, 0x01055B, 0x001BC8,
+ 0x010484, 0x001BD0, 0x000E9D, 0x010480, 0x001BD5, 0x001A90, 0x001BD6, 0x001BD7,
+ 0x01048A, 0x010482, 0x001A4D, 0x010485, 0x001A4C, 0x001BDB, 0x001A4E, 0x001A98,
+ 0x001A94, 0x0104B3, 0x014644, 0x000AE1, 0x000E84, 0x001A93, 0x01F10C, 0x0104B8,
+ 0x000AE0, 0x001A91, 0x001A92, 0x001A95, 0x001A97, 0x0104BE, 0x0104BF, 0x000A72,
+ 0x000E9C, 0x000A25, 0x0104A3, 0x000A26, 0x000A73, 0x000AE6, 0x000AE7, 0x010488,
+ 0x000AEA, 0x000AF9, 0x000AEB, 0x0104BA, 0x000A24, 0x01048E, 0x000A74, 0x000A6C,
+ 0x001B0C, 0x001B48, 0x001B46, 0x001B4B, 0x001B45, 0x001B19, 0x001B47, 0x010523,
+ 0x001B09, 0x001B08, 0x001B0B, 0x001B0A, 0x001B0D, 0x001B4A, 0x001B0F, 0x001B0E,
+ 0x001B11, 0x001B10, 0x001B13, 0x001B12, 0x001B15, 0x01442F, 0x001B17, 0x001B16,
+ 0x000E8D, 0x014442, 0x014447, 0x01440F, 0x001B1A, 0x001B1C, 0x014441, 0x014409,
+ 0x001B30, 0x001B20, 0x001B23, 0x001B22, 0x001B25, 0x001B21, 0x001B27, 0x001B24,
+ 0x0104DB, 0x0104D2, 0x0104D0, 0x001B29, 0x001B2A, 0x001B2C, 0x001B26, 0x001B2B,
+ 0x01440D, 0x001B33, 0x01440E, 0x01441B, 0x014432, 0x014536, 0x0144EC, 0x014537,
+ 0x014460, 0x001B32, 0x0144ED, 0x014431, 0x001B31, 0x000A2A, 0x001B49, 0x000A2B,
+ 0x0144AC, 0x014430, 0x000EB3, 0x01447B, 0x014433, 0x010512, 0x000EB2, 0x014437,
+ 0x000F68, 0x000F6C, 0x000F4A, 0x000EB0, 0x01441A, 0x01447C, 0x000F4E, 0x010601,
+ 0x001B51, 0x001B53, 0x010602, 0x010600, 0x001B56, 0x001B54, 0x001B52, 0x001B55,
+ 0x001B50, 0x010604, 0x001B58, 0x010606, 0x010605, 0x001B59, 0x010607, 0x001B57,
+ 0x01440A, 0x01440B, 0x014462, 0x014461, 0x0144D0, 0x014473, 0x014436, 0x010608,
+ 0x010609, 0x01060A, 0x01060B, 0x01060C, 0x01060D, 0x01060E, 0x01447E, 0x014475,
+ 0x014472, 0x014466, 0x01445A, 0x014476, 0x01445C, 0x01444C, 0x000F69, 0x014463,
+ 0x010623, 0x01445D, 0x01443E, 0x01445E, 0x014467, 0x01443C, 0x01445F, 0x010633,
+ 0x001B83, 0x01440C, 0x01443D, 0x01063C, 0x000E8A, 0x01063E, 0x000E87, 0x014423,
+ 0x01063A, 0x01447F, 0x014443, 0x014453, 0x001B8D, 0x001B8C, 0x01063D, 0x010655,
+ 0x010654, 0x001B90, 0x001B93, 0x010656, 0x010657, 0x001B91, 0x001B92, 0x0144AD,
+ 0x01065B, 0x00A804, 0x001B9C, 0x0144AE, 0x01065F, 0x001B95, 0x001B96, 0x001B97,
+ 0x001B84, 0x001A85, 0x001B8E, 0x001B8F, 0x001B88, 0x001B85, 0x001B86, 0x001B87,
+ 0x01F102, 0x010652, 0x010651, 0x001B8B, 0x01F10B, 0x010650, 0x001B8A, 0x001B89,
+ 0x001BB1, 0x001BB0, 0x001BB3, 0x001BB2, 0x001BB5, 0x001BB4, 0x001BB7, 0x001BB6,
+ 0x001BB9, 0x001BB8, 0x001BBB, 0x001BBA, 0x001BBD, 0x001A80, 0x001BBF, 0x001BBE,
+ 0x001BC1, 0x00A832, 0x001BC3, 0x001BC2, 0x001BC5, 0x001BC4, 0x0144AF, 0x001BC6,
+ 0x001BC9, 0x001BC0, 0x001BCB, 0x001BCA, 0x001BCD, 0x001BCC, 0x001BC7, 0x001BCE,
+ 0x001BD1, 0x01F103, 0x001BD3, 0x001BD2, 0x0144D2, 0x0144D1, 0x001A86, 0x014440,
+ 0x001A89, 0x01444B, 0x00A89B, 0x001A88, 0x0144B8, 0x001BDC, 0x00A89A, 0x00A822,
+ 0x001BE1, 0x001BE0, 0x001BE3, 0x001BE2, 0x001BE5, 0x001BE4, 0x00A8D8, 0x00AA9C,
+ 0x014445, 0x001BBC, 0x014452, 0x014616, 0x00A8F3, 0x000E88, 0x01444A, 0x0106A1,
+ 0x0106A0, 0x014446, 0x0106A2, 0x001BA0, 0x0106A4, 0x0106A7, 0x0106A6, 0x0106A9,
+ 0x0106A8, 0x0106AB, 0x0106AA, 0x0106AE, 0x0106A5, 0x0106AF, 0x0106AD, 0x0144B9,
+ 0x001C0D, 0x001C00, 0x001C03, 0x001C06, 0x001C05, 0x001C04, 0x001C07, 0x001C0C,
+ 0x001C09, 0x001C18, 0x001C0B, 0x0106AC, 0x001C0A, 0x001C0F, 0x001C1E, 0x0106DF,
+ 0x001C11, 0x001C10, 0x001C13, 0x001C12, 0x001C16, 0x001C17, 0x0106C3, 0x001C14,
+ 0x001C19, 0x001C1A, 0x001C1B, 0x001C1C, 0x001C1D, 0x001C15, 0x001C1F, 0x0106D3,
+ 0x0106D0, 0x0106D1, 0x0106D2, 0x0106D7, 0x0106D4, 0x0106D5, 0x0106D6, 0x0106DB,
+ 0x01F101, 0x0106D9, 0x0106DA, 0x01F100, 0x0106D8, 0x0106DC, 0x0106DE, 0x001C08,
+ 0x001C20, 0x001C21, 0x001C22, 0x001C23, 0x001C74, 0x001C71, 0x001C76, 0x001C77,
+ 0x001C60, 0x001C61, 0x001C62, 0x001C63, 0x001C0E, 0x001C75, 0x0106FF, 0x0106F1,
+ 0x0106F0, 0x0106F7, 0x0106F2, 0x0106F5, 0x01F107, 0x01F106, 0x0106F6, 0x01F105,
+ 0x0106F8, 0x0106F9, 0x0106FA, 0x0106F4, 0x0106DD, 0x0106FB, 0x001C54, 0x010710,
+ 0x010711, 0x001C50, 0x001C53, 0x010717, 0x001C51, 0x010715, 0x010716, 0x001C52,
+ 0x001C5A, 0x001C5B, 0x001C56, 0x001C59, 0x001C5F, 0x001C55, 0x010714, 0x001C57,
+ 0x001C40, 0x001C41, 0x001C42, 0x001C43, 0x001C44, 0x001C45, 0x01F104, 0x001C47,
+ 0x001C70, 0x001C49, 0x001C72, 0x001C73, 0x001C5C, 0x010712, 0x001C46, 0x010721,
+ 0x010720, 0x001C5D, 0x010722, 0x010725, 0x010724, 0x010727, 0x010726, 0x010718,
+ 0x01071F, 0x01072B, 0x01071A, 0x010728, 0x010729, 0x01071E, 0x001C58, 0x001C5E,
+ 0x00A8B0, 0x00A8B1, 0x00A8AB, 0x00A8A9, 0x0145E1, 0x00A8D5, 0x00A8A4, 0x00A8D9,
+ 0x001C82, 0x00A8AA, 0x00AA86, 0x001C83, 0x01071B, 0x01072F, 0x010719, 0x001C81,
+ 0x001C85, 0x010743, 0x001C80, 0x001C86, 0x000C9B, 0x001C87, 0x001C84, 0x000C97,
+ 0x001565, 0x000C93, 0x001C88, 0x014584, 0x01444E, 0x001566, 0x014589, 0x010751,
+ 0x010750, 0x000C9A, 0x010752, 0x010755, 0x010754, 0x0145B1, 0x0145B2, 0x0145B3,
+ 0x0145B0, 0x014515, 0x014514, 0x00AA80, 0x000F25, 0x014533, 0x01451B, 0x01458C,
+ 0x000F24, 0x01458D, 0x014618, 0x00AA89, 0x01450C, 0x01462C, 0x000C92, 0x014603,
+ 0x014630, 0x000CB2, 0x000C96, 0x000C95, 0x00A8F4, 0x000CB8, 0x00AA88, 0x01462E,
+ 0x01442E, 0x01450D, 0x01450E, 0x01450F, 0x000D6D, 0x014610, 0x000F22, 0x000F42,
+ 0x000D68, 0x00AA9E, 0x000D6E, 0x014505, 0x014631, 0x000F40, 0x001567, 0x01461A,
+ 0x000C94, 0x001560, 0x014602, 0x000D6C, 0x001561, 0x000C90, 0x00A80F, 0x01455E,
+ 0x0145CC, 0x0145C5, 0x01071C, 0x014478, 0x01071D, 0x01444F, 0x014540, 0x000CA8,
+ 0x00A8D4, 0x001C6C, 0x010703, 0x0145CD, 0x014479, 0x001C65, 0x001C66, 0x001C67,
+ 0x014474, 0x001C69, 0x001C6A, 0x01446F, 0x01455F, 0x001CEC, 0x001CEF, 0x001CEE,
+ 0x001CF1, 0x001CF0, 0x01447A, 0x001562, 0x001CF5, 0x0145F2, 0x0145F3, 0x001CF6,
+ 0x0145F6, 0x014531, 0x0145F7, 0x014532, 0x014530, 0x00A8F5, 0x01460E, 0x014578,
+ 0x001D01, 0x001D02, 0x001D03, 0x001D00, 0x001D05, 0x001D06, 0x001D07, 0x001D04,
+ 0x001D0C, 0x001D0A, 0x001D0B, 0x000D0F, 0x001D09, 0x001D1D, 0x001D0F, 0x001D0D,
+ 0x001D11, 0x001D10, 0x001D13, 0x001D12, 0x001D15, 0x001D14, 0x001D17, 0x001D08,
+ 0x001D19, 0x001D18, 0x001D1B, 0x001D1A, 0x001D1E, 0x001D1F, 0x001D16, 0x001D1C,
+ 0x001D21, 0x001D24, 0x001D23, 0x001D22, 0x000D27, 0x001D20, 0x001D27, 0x001D26,
+ 0x001D29, 0x001D2A, 0x001D2B, 0x000D23, 0x000D0E, 0x001D25, 0x001D0E, 0x000D2B,
+ 0x000D21, 0x000D76, 0x000D22, 0x000D25, 0x000D26, 0x01446E, 0x001563, 0x00A815,
+ 0x001D28, 0x000D24, 0x000D7B, 0x000D6F, 0x01462F, 0x00157C, 0x000D75, 0x000D3D,
+ 0x000DC0, 0x000D20, 0x000D77, 0x000D6A, 0x000DC4, 0x000D67, 0x000D73, 0x000D69,
+ 0x000D66, 0x000D71, 0x000D4E, 0x000D72, 0x000D70, 0x000D60, 0x000D2A, 0x010801,
+ 0x010803, 0x010820, 0x010802, 0x010800, 0x010826, 0x010804, 0x010805, 0x010818,
+ 0x01080B, 0x01081A, 0x01080A, 0x010814, 0x010808, 0x01081C, 0x01080C, 0x010811,
+ 0x010817, 0x01081B, 0x010812, 0x010810, 0x001D74, 0x001D6D, 0x001D6C, 0x001D6F,
+ 0x001D6B, 0x001D79, 0x001D7A, 0x001D7B, 0x001D6E, 0x001D7D, 0x001D7E, 0x001D7F,
+ 0x010834, 0x010835, 0x001D73, 0x001D72, 0x010827, 0x001D71, 0x010822, 0x010838,
+ 0x001D70, 0x01083C, 0x010821, 0x001D75, 0x010823, 0x001D77, 0x001D76, 0x001D7C,
+ 0x001D81, 0x010833, 0x001D83, 0x001D82, 0x001D85, 0x010832, 0x010831, 0x001D86,
+ 0x010819, 0x001D98, 0x010837, 0x010830, 0x01080F, 0x001D8C, 0x01081F, 0x01085B,
+ 0x001D91, 0x001D90, 0x001D93, 0x001D92, 0x001D95, 0x001D94, 0x001D97, 0x001D96,
+ 0x01085F, 0x01085D, 0x01083F, 0x010842, 0x01085A, 0x001D99, 0x001D9A, 0x010840,
+ 0x010841, 0x010853, 0x010852, 0x010847, 0x010845, 0x010846, 0x010851, 0x010850,
+ 0x010854, 0x01084A, 0x01084B, 0x010855, 0x010844, 0x010859, 0x010843, 0x01084F,
+ 0x010875, 0x010849, 0x01082C, 0x01087B, 0x010825, 0x010824, 0x01087F, 0x010828,
+ 0x010829, 0x01082A, 0x01087A, 0x01082E, 0x01082D, 0x01082B, 0x01082F, 0x010873,
+ 0x010872, 0x010862, 0x010863, 0x010860, 0x010861, 0x010871, 0x010867, 0x010858,
+ 0x010870, 0x010865, 0x010874, 0x01085C, 0x010866, 0x01085E, 0x010876, 0x010881,
+ 0x014632, 0x010883, 0x010882, 0x010885, 0x000DC6, 0x000DC5, 0x010886, 0x010889,
+ 0x010888, 0x01088B, 0x01088A, 0x00A821, 0x000DAC, 0x01088F, 0x000DC3, 0x010891,
+ 0x00AA99, 0x000D7A, 0x010892, 0x010895, 0x00AA9A, 0x00A814, 0x010896, 0x010899,
+ 0x010898, 0x01089B, 0x01089A, 0x000DC2, 0x00AA9F, 0x00AA83, 0x000D7E, 0x000DC1,
+ 0x014613, 0x000D7F, 0x00AA87, 0x014625, 0x0108AC, 0x0108A7, 0x000CB5, 0x000D74,
+ 0x00AA81, 0x0108AB, 0x0108AA, 0x0108A8, 0x0108A9, 0x0108AF, 0x00A835, 0x000DAD,
+ 0x014611, 0x001E61, 0x001E62, 0x001E63, 0x00A834, 0x001E65, 0x001E66, 0x00AA98,
+ 0x01461B, 0x014615, 0x014619, 0x014612, 0x001E7C, 0x001E7D, 0x001E6C, 0x01086A,
+ 0x001E1D, 0x01084D, 0x001E7E, 0x001E7F, 0x001E1F, 0x01084E, 0x001E14, 0x01086D,
+ 0x001E78, 0x010848, 0x001E1B, 0x001E1A, 0x001E1E, 0x001E18, 0x0108E3, 0x0108FC,
+ 0x0108FD, 0x010868, 0x001E74, 0x001EAD, 0x01086C, 0x01086E, 0x001EAE, 0x01084C,
+ 0x0108FB, 0x001EBD, 0x0108FE, 0x001EAA, 0x001EAF, 0x0108FF, 0x001E79, 0x0108E1,
+ 0x0108E0, 0x001EBE, 0x0108E2, 0x0108E5, 0x0108E4, 0x0108E7, 0x0108E6, 0x001EBF,
+ 0x0108E8, 0x0108EB, 0x0108EA, 0x001EB9, 0x0108EC, 0x0108F4, 0x0108EE, 0x0108F2,
+ 0x001ED8, 0x01087C, 0x001E43, 0x0108F1, 0x01087D, 0x001ED4, 0x01086F, 0x010879,
+ 0x010869, 0x01086B, 0x001EDA, 0x0108F0, 0x01087E, 0x010864, 0x0108F5, 0x001ED5,
+ 0x001E40, 0x001E41, 0x001E42, 0x001E4D, 0x001E44, 0x001E45, 0x001E46, 0x001E47,
+ 0x001E48, 0x001E49, 0x001E4A, 0x001E4B, 0x001E7A, 0x001E5C, 0x001E4E, 0x001E4F,
+ 0x001E70, 0x001E73, 0x001E72, 0x001ED9, 0x001EDD, 0x001E71, 0x001E76, 0x001EDF,
+ 0x010901, 0x010902, 0x001E7B, 0x001E75, 0x001E4C, 0x001E77, 0x010907, 0x010922,
+ 0x010920, 0x001EDB, 0x010913, 0x010927, 0x010921, 0x010924, 0x010925, 0x010929,
+ 0x010928, 0x01092B, 0x01092A, 0x001EDE, 0x01092C, 0x010926, 0x01092E, 0x010910,
+ 0x010911, 0x010912, 0x001E83, 0x010914, 0x001E82, 0x010916, 0x010917, 0x010918,
+ 0x001E85, 0x001E81, 0x01091B, 0x01092D, 0x010915, 0x001E8A, 0x01092F, 0x001E86,
+ 0x001E8C, 0x001EBA, 0x001E90, 0x010900, 0x010905, 0x010906, 0x001E93, 0x001EB8,
+ 0x001E92, 0x001E8E, 0x01090B, 0x010904, 0x001E8B, 0x001E9C, 0x001E88, 0x001E84,
+ 0x001EA3, 0x001EB1, 0x001EB2, 0x001EB0, 0x001EB4, 0x001EA2, 0x001EB6, 0x001EB7,
+ 0x001EA1, 0x001E89, 0x001EA5, 0x001EBB, 0x001EB5, 0x001E8D, 0x001EA7, 0x001E8F,
+ 0x001EA8, 0x00A820, 0x001EA6, 0x001E91, 0x001E97, 0x00AA11, 0x00AA82, 0x010930,
+ 0x010931, 0x010932, 0x001EAB, 0x001EA4, 0x001EAC, 0x001EB3, 0x010937, 0x001EBC,
+ 0x001ED0, 0x001EC2, 0x001EC1, 0x001ED3, 0x00AA13, 0x001ED1, 0x001ED2, 0x00AA9D,
+ 0x01446D, 0x001ED6, 0x00AAB6, 0x014617, 0x001ED7, 0x001ECC, 0x014614, 0x00AAB1,
+ 0x010980, 0x001E94, 0x001E9D, 0x010985, 0x010984, 0x010987, 0x001E96, 0x001E95,
+ 0x001E98, 0x001E99, 0x001E9A, 0x001E9B, 0x001EFD, 0x001E9F, 0x001E9E, 0x000CAF,
+ 0x001EF0, 0x001EF1, 0x000CA3, 0x00A850, 0x001EF4, 0x001EF5, 0x001EF6, 0x001EF7,
+ 0x001EF8, 0x001EF9, 0x001EFA, 0x001EFB, 0x000CA2, 0x001EFF, 0x001EFE, 0x0109A1,
+ 0x0109A0, 0x0109A3, 0x0109A2, 0x0109A6, 0x001EF3, 0x0109A7, 0x0109A5, 0x0109AB,
+ 0x0109A8, 0x0109A9, 0x0109AA, 0x0109A4, 0x0109AC, 0x010923, 0x0109AE, 0x001EF2,
+ 0x001F2C, 0x001F2D, 0x001F2E, 0x010934, 0x010935, 0x010936, 0x001F24, 0x010938,
+ 0x010939, 0x001F28, 0x001F2F, 0x0109BD, 0x0109AD, 0x0109AF, 0x0109BE, 0x0109EC,
+ 0x000E52, 0x001F10, 0x014608, 0x01460B, 0x001F1D, 0x001F14, 0x000E50, 0x0109C3,
+ 0x0109EF, 0x001F18, 0x001F1B, 0x0109ED, 0x001F68, 0x001F19, 0x001F1A, 0x0109D5,
+ 0x0109DC, 0x001F23, 0x0109D2, 0x0109D3, 0x0109D4, 0x0109D7, 0x0109D6, 0x001F22,
+ 0x0109D8, 0x0109DB, 0x0109DA, 0x0109DE, 0x001F26, 0x001F21, 0x0109D9, 0x0109F0,
+ 0x0109F1, 0x0109F2, 0x0109E2, 0x0109E1, 0x0109E0, 0x0109E7, 0x0109F7, 0x0109EA,
+ 0x0109E5, 0x0109E8, 0x0109E9, 0x0109E4, 0x0109EE, 0x0109E6, 0x0109DD, 0x001F25,
+ 0x0109EB, 0x000E81, 0x001F43, 0x001F42, 0x000F43, 0x001F41, 0x001F40, 0x0109DF,
+ 0x000E09, 0x000E82, 0x001F78, 0x00AAE9, 0x00A81B, 0x001F44, 0x001F4C, 0x00AAE8,
+ 0x001F51, 0x001F50, 0x001F53, 0x001F52, 0x001F55, 0x001F54, 0x001F57, 0x001F56,
+ 0x001F59, 0x001F49, 0x001F5B, 0x001F4B, 0x001F5D, 0x001F45, 0x001F5F, 0x001F4D,
+ 0x010A00, 0x010A13, 0x001F6C, 0x010A15, 0x001F62, 0x00AA1B, 0x010A16, 0x001F63,
+ 0x001F48, 0x00AA14, 0x001F4A, 0x010A1F, 0x001F60, 0x001F61, 0x010A1D, 0x010A23,
+ 0x001F65, 0x001F66, 0x001F73, 0x001F72, 0x001F76, 0x001F71, 0x001F74, 0x001F75,
+ 0x000E9E, 0x001F69, 0x001F7B, 0x001F6D, 0x001F79, 0x001F7C, 0x001F7D, 0x010A31,
+ 0x00AA10, 0x010A33, 0x010A32, 0x010A30, 0x00157D, 0x000E0D, 0x000E0E, 0x00157E,
+ 0x001F98, 0x000E08, 0x000E0A, 0x00AA27, 0x000E0F, 0x00AA21, 0x00AA20, 0x001F9E,
+ 0x001F91, 0x001F93, 0x00157F, 0x001F90, 0x001F96, 0x001F94, 0x001F92, 0x001F95,
+ 0x001F99, 0x000F8B, 0x001F9B, 0x001F9A, 0x001F9D, 0x000F8A, 0x001F9F, 0x001F97,
+ 0x000E21, 0x000E22, 0x000E23, 0x000F59, 0x000E25, 0x000E9F, 0x000E27, 0x000E20,
+ 0x000F26, 0x000CAE, 0x000E2A, 0x000E2B, 0x000E28, 0x000E29, 0x000E26, 0x000E2F,
+ 0x000E99, 0x001578, 0x001579, 0x00157A, 0x00157B, 0x001574, 0x001575, 0x001576,
+ 0x001577, 0x001570, 0x001571, 0x000E96, 0x001572, 0x000E2D, 0x000E2E, 0x000E97,
+ 0x000F00, 0x001573, 0x001FC3, 0x001FC2, 0x00154C, 0x001FC4, 0x001FC7, 0x001FC6,
+ 0x001FC9, 0x00154D, 0x001FCB, 0x001FCA, 0x00154E, 0x001FCC, 0x00154F, 0x001548,
+ 0x000E54, 0x001549, 0x00154A, 0x00154B, 0x000E55, 0x000E56, 0x000E57, 0x000CDE,
+ 0x001544, 0x000E59, 0x001545, 0x001546, 0x000E58, 0x001547, 0x001540, 0x001541,
+ 0x001542, 0x001543, 0x00155C, 0x00152E, 0x00152F, 0x001528, 0x00158E, 0x00158F,
+ 0x001588, 0x001584, 0x001591, 0x00126D, 0x00127E, 0x00127F, 0x001278, 0x001279,
+ 0x00127A, 0x00127B, 0x001FF3, 0x001FF2, 0x001274, 0x001FF4, 0x001FF7, 0x001FF6,
+ 0x001FF9, 0x001FF8, 0x001FFB, 0x001FFA, 0x001275, 0x001276, 0x00AA25, 0x001277,
+ 0x00AA24, 0x001270, 0x00AA28, 0x001271, 0x001272, 0x001273, 0x00124C, 0x00124D,
+ 0x01E8AC, 0x01E8AD, 0x01E8BC, 0x01E8BD, 0x01E8BF, 0x01E8B5, 0x00AA57, 0x010AC1,
+ 0x010AC0, 0x010AC3, 0x010AC2, 0x010AC5, 0x010AC4, 0x010AC7, 0x010AC6, 0x00120E,
+ 0x00120F, 0x010ACB, 0x001208, 0x010ACD, 0x010ACC, 0x010ACF, 0x010ACE, 0x010AD1,
+ 0x001209, 0x010AD3, 0x00AA52, 0x00AA53, 0x00AA50, 0x00AA51, 0x010AD6, 0x010AD9,
+ 0x00120A, 0x001201, 0x010ADA, 0x010ADD, 0x010ADC, 0x001202, 0x010ADE, 0x010AE1,
+ 0x010AE0, 0x010AE3, 0x010AE2, 0x0012E8, 0x010AE4, 0x00FC5D, 0x00FC5E, 0x00FC58,
+ 0x00FC3F, 0x010AEB, 0x00FC3B, 0x010AED, 0x010AEC, 0x010AEF, 0x010AEE, 0x00FC34,
+ 0x00FC35, 0x00FC36, 0x00FC37, 0x00FC30, 0x00FC31, 0x00FC32, 0x00FC0C, 0x00FC0D,
+ 0x00FC0E, 0x00FC13, 0x00FCEC, 0x00FCED, 0x00FCEE, 0x00FCEA, 0x00FCA5, 0x010B10,
+ 0x010B11, 0x010B1C, 0x00FCA6, 0x010B14, 0x010B15, 0x010B16, 0x010B17, 0x010B18,
+ 0x010B19, 0x010B1A, 0x010B1B, 0x00FCA0, 0x010B1D, 0x010B1E, 0x010B1F, 0x010B02,
+ 0x010B01, 0x010B13, 0x010B12, 0x010B00, 0x010B05, 0x00FC8D, 0x010B07, 0x00FC8E,
+ 0x00FC85, 0x010B04, 0x010B0A, 0x010B06, 0x00FC86, 0x0013BD, 0x0013BE, 0x0013BF,
+ 0x0013B8, 0x0013B9, 0x010B03, 0x0013BA, 0x0013BB, 0x0013B4, 0x0013B5, 0x0013B6,
+ 0x0013B7, 0x0013B0, 0x0013B1, 0x0013B2, 0x0013B3, 0x00138C, 0x010B09, 0x00FD53,
+ 0x00FD2C, 0x00FD2D, 0x00FD2E, 0x00FD2F, 0x00FD28, 0x00FD29, 0x00FD2A, 0x00FD2B,
+ 0x00FD24, 0x00FD25, 0x00FD26, 0x00FD27, 0x00FD20, 0x00FD21, 0x00FD22, 0x00FD23,
+ 0x010B23, 0x00FD3C, 0x010B33, 0x00106F, 0x00FD38, 0x00FD39, 0x00FD3A, 0x00FD3B,
+ 0x00FD36, 0x00FD37, 0x00FD31, 0x00FD32, 0x00FD0B, 0x00FD00, 0x00FD01, 0x010B30,
+ 0x010B31, 0x010B32, 0x010B52, 0x010B34, 0x010B35, 0x010B50, 0x010B51, 0x010B54,
+ 0x010B58, 0x010B5B, 0x010B5F, 0x010B55, 0x010B0B, 0x00FD02, 0x010B08, 0x00FD03,
+ 0x010B0D, 0x010B0E, 0x00FD1C, 0x00FD1D, 0x00FD1E, 0x00FD19, 0x00FD1A, 0x00105D,
+ 0x00105A, 0x00105B, 0x001054, 0x001055, 0x001050, 0x001051, 0x010B0F, 0x001052,
+ 0x001053, 0x001028, 0x00FDFA, 0x00FDF3, 0x00103F, 0x00FDC4, 0x00FDC5, 0x00FDC6,
+ 0x00FDC7, 0x00FDC0, 0x00FDC1, 0x010B0C, 0x00FDC2, 0x00100D, 0x00100E, 0x00100F,
+ 0x001008, 0x010B83, 0x001009, 0x00100A, 0x010B82, 0x00100B, 0x001004, 0x001005,
+ 0x001006, 0x001007, 0x001000, 0x010B81, 0x001001, 0x001002, 0x001003, 0x010B80,
+ 0x00101C, 0x010B91, 0x010B90, 0x010B84, 0x010B85, 0x010B86, 0x010B87, 0x010B88,
+ 0x010B89, 0x010B8A, 0x010B8B, 0x010B8E, 0x010B8D, 0x00FDB3, 0x010B8F, 0x00FD8A,
+ 0x010BAC, 0x00FD83, 0x00FD9D, 0x00FD9E, 0x010BAE, 0x00FD9F, 0x00FD98, 0x010BA9,
+ 0x010BAB, 0x010BAF, 0x010BAA, 0x00FD99, 0x010B8C, 0x00FD9A, 0x010BAD, 0x00FD95,
+ 0x0010C1, 0x0010C2, 0x0010DF, 0x002102, 0x0010D8, 0x00FA43, 0x002107, 0x00FA5C,
+ 0x00FA5E, 0x00FA5F, 0x00210B, 0x00210A, 0x00210D, 0x00210C, 0x00210F, 0x00210E,
+ 0x00FA58, 0x00FA59, 0x00FA5A, 0x00FA5B, 0x00FA54, 0x00FA55, 0x00FA56, 0x00FA51,
+ 0x00FA52, 0x00FA53, 0x00FA2C, 0x00FA2D, 0x00FA2E, 0x00211C, 0x00FA29, 0x00FA2A,
+ 0x00115D, 0x00115E, 0x00115F, 0x001158, 0x001159, 0x00115A, 0x00115B, 0x001154,
+ 0x001155, 0x001156, 0x001157, 0x001150, 0x001151, 0x00212C, 0x001152, 0x001153,
+ 0x002131, 0x002130, 0x002133, 0x002132, 0x002135, 0x002134, 0x002137, 0x002136,
+ 0x00112C, 0x002138, 0x00112D, 0x00112E, 0x00213D, 0x00112F, 0x00213F, 0x00213E,
+ 0x001128, 0x001129, 0x00112A, 0x00112B, 0x001124, 0x001125, 0x002147, 0x002146,
+ 0x001126, 0x001127, 0x001120, 0x002148, 0x00214E, 0x001121, 0x001122, 0x001123,
+ 0x002151, 0x00113C, 0x002153, 0x002152, 0x002155, 0x002154, 0x00110D, 0x00110E,
+ 0x00110F, 0x002158, 0x001108, 0x00110B, 0x00215D, 0x00215C, 0x00215F, 0x00215E,
+ 0x002171, 0x001104, 0x002163, 0x002162, 0x0011B6, 0x002161, 0x0011B3, 0x00119A,
+ 0x00FB23, 0x00FB3C, 0x00FB3E, 0x00FB38, 0x00FB39, 0x00FB3A, 0x00FB3B, 0x00216C,
+ 0x00FB34, 0x00FB35, 0x00FB36, 0x00FB30, 0x00FB31, 0x00FB32, 0x00FB33, 0x00FB04,
+ 0x00FB05, 0x00FB06, 0x00FB00, 0x00FB01, 0x00FB02, 0x00217C, 0x00FB03, 0x00FB1D,
+ 0x00FB1F, 0x000E44, 0x002183, 0x00FB15, 0x002182, 0x002184, 0x00FB16, 0x002181,
+ 0x002189, 0x002185, 0x000E41, 0x000E42, 0x002188, 0x000E43, 0x00FB13, 0x002186,
+ 0x00FBEC, 0x00FBED, 0x00FBEE, 0x00FBE9, 0x00FBEA, 0x00FBF3, 0x000E30, 0x000E32,
+ 0x000E33, 0x000E0C, 0x00FBD7, 0x000E01, 0x000E02, 0x000E03, 0x00AA67, 0x00AA60,
+ 0x00AA61, 0x00AA62, 0x00AA63, 0x00AA7E, 0x00AA7F, 0x00AA7A, 0x00FBB0, 0x00AA75,
+ 0x00AA76, 0x00FB8C, 0x00FB8D, 0x00AA8F, 0x00FB89, 0x00FB8A, 0x00FB8B, 0x00FB84,
+ 0x00FB98, 0x00FB99, 0x00FB9A, 0x00FB94, 0x000ED4, 0x000ED5, 0x000ED7, 0x000ED0,
+ 0x000ED1, 0x00AA26, 0x00AA22, 0x00AA23, 0x000EAA, 0x000EAB, 0x000EA5, 0x000EA7,
+ 0x000EA1, 0x000EA2, 0x00AA8D, 0x000EA3, 0x000EBD, 0x00AA8C, 0x00AA0C, 0x00AA0D,
+ 0x00AA8E, 0x00AA0E, 0x00AA0F, 0x00AA08, 0x00AA09, 0x00AA0B, 0x00AA06, 0x00AA00,
+ 0x00AA01, 0x00AA03, 0x00AA1D, 0x00AA1F, 0x00AA18, 0x00AA1A, 0x00AA15, 0x00AA12,
+ 0x000E9A, 0x000E9B, 0x000E94, 0x000E95, 0x00AAEA, 0x00AAE4, 0x00AAE5, 0x00AAE7,
+ 0x00AAE0, 0x00AAE1, 0x00AA17, 0x000F6A, 0x000F6B, 0x000F64, 0x000F65, 0x000F66,
+ 0x000F67, 0x000F60, 0x000F61, 0x000F62, 0x000F63, 0x014645, 0x014646, 0x014640,
+ 0x014641, 0x014642, 0x014643, 0x000F4C, 0x000F4D, 0x000F4F, 0x00AAC2, 0x000F49,
+ 0x000F4B, 0x000F44, 0x000F45, 0x000F46, 0x000F47, 0x014609, 0x01460A, 0x014604,
+ 0x014605, 0x00AA9B, 0x00AA94, 0x00AA95, 0x00AA16, 0x00AA96, 0x00AA97, 0x00AA90,
+ 0x00AA1E, 0x00AA91, 0x00AA92, 0x00AA93, 0x00AB64, 0x00AB65, 0x00AB60, 0x00AB61,
+ 0x00AB62, 0x00AB63, 0x00AB7C, 0x00AB7D, 0x00AB7E, 0x00AB7F, 0x00AB78, 0x00AB79,
+ 0x00AB7A, 0x00AB7B, 0x00AB74, 0x00AB75, 0x00AB76, 0x00AB77, 0x00AB70, 0x00AB71,
+ 0x00AB72, 0x00AB73, 0x00AB4C, 0x00AB4D, 0x00AB4E, 0x00AB4F, 0x00AB48, 0x00AB49,
+ 0x00AB4A, 0x00AB4B, 0x00AB44, 0x00AB45, 0x00AB46, 0x00AB47, 0x00AB40, 0x00AB41,
+ 0x00AB42, 0x00AB43, 0x00AB58, 0x00AB59, 0x00AB5A, 0x00AB54, 0x00AB55, 0x00AB56,
+ 0x00F964, 0x00F97C, 0x00F944, 0x00F945, 0x00F95C, 0x00F95D, 0x00F95B, 0x00F954,
+ 0x00F955, 0x00F956, 0x00F957, 0x00F950, 0x00F92C, 0x00F92D, 0x00F929, 0x00F92A,
+ 0x00F92B, 0x00F924, 0x00AAC0, 0x00F925, 0x00AAE2, 0x00AAE6, 0x00F926, 0x00F927,
+ 0x00F920, 0x00F921, 0x00F922, 0x00F93B, 0x00F934, 0x00F9BB, 0x00F9B4, 0x00F9B1,
+ 0x00F9B2, 0x00F9B3, 0x00F98C, 0x00A857, 0x00A851, 0x00A852, 0x00A853, 0x000CAC,
+ 0x000CAD, 0x000CAA, 0x000CAB, 0x000CA4, 0x000CA5, 0x000CA6, 0x00AADC, 0x000CA7,
+ 0x000CA0, 0x000CA1, 0x000CBD, 0x00A830, 0x00A831, 0x00A80C, 0x00A80D, 0x00A80E,
+ 0x000CB1, 0x000C8C, 0x00A807, 0x000C88, 0x00A81E, 0x01447D, 0x014470, 0x014471,
+ 0x014458, 0x014459, 0x01445B, 0x014454, 0x014455, 0x014456, 0x014457, 0x014450,
+ 0x014451, 0x01442C, 0x01442D, 0x014408, 0x0144F0, 0x0144F1, 0x00AAE3, 0x0144C6,
+ 0x0144C7, 0x0144C0, 0x0144C1, 0x0144C2, 0x0144C3, 0x0144DC, 0x0144DD, 0x0144D9,
+ 0x0144D6, 0x0144D7, 0x0144D3, 0x0144A8, 0x0144A9, 0x0144AA, 0x0144AB, 0x0144A4,
+ 0x0144A5, 0x0144A6, 0x0144A7, 0x0144A0, 0x00AA1C, 0x0144A1, 0x0144A2, 0x0144A3,
+ 0x0144BC, 0x0144BD, 0x00AA19, 0x014571, 0x014546, 0x014547, 0x014541, 0x014542,
+ 0x014543, 0x01455C, 0x01455D, 0x014558, 0x014559, 0x01455A, 0x01455B, 0x014554,
+ 0x014555, 0x014556, 0x014557, 0x014550, 0x014551, 0x01452C, 0x01452D, 0x014508,
+ 0x014509, 0x01451A, 0x0145F0, 0x0145F1, 0x0145CE, 0x0145CF, 0x0145C8, 0x0145C9,
+ 0x0145CA, 0x0145CB, 0x0145C4, 0x0145A6, 0x0145A7, 0x0145A0, 0x0145A1, 0x014588,
+ 0x01458A, 0x01458B, 0x014586, 0x014587, 0x014580, 0x00A61A, 0x00A61B, 0x00A614,
+ 0x00A615, 0x00A6E4, 0x000B6A, 0x000B6B, 0x000B66, 0x000B67, 0x000B60, 0x000B61,
+ 0x00A6CC, 0x00A6CD, 0x00A6CA, 0x00A6C6, 0x00A6C7, 0x00A6C0, 0x00A6C1, 0x00A6C2,
+ 0x00A6C3, 0x00A6DC, 0x00A6DD, 0x00A6DE, 0x00A6DF, 0x00A6D8, 0x00A6D9, 0x00A6DA,
+ 0x00A6DB, 0x00A6D4, 0x00A6D5, 0x00A6D0, 0x00A6D2, 0x00A6D3, 0x00A6AC, 0x00A6AD,
+ 0x00A6AE, 0x00AA02, 0x00A6AF, 0x00A6A8, 0x00A6A9, 0x00A6AA, 0x00A6AB, 0x00A6A4,
+ 0x00A6A5, 0x00A6A3, 0x00A6B6, 0x00A6B0, 0x00A6B1, 0x00A68C, 0x00A68D, 0x00A68E,
+ 0x00A68B, 0x00A687, 0x00AAF2, 0x00A680, 0x000B0A, 0x000B0B, 0x000B05, 0x00A69A,
+ 0x00A69B, 0x00A694, 0x00A695, 0x00A76B, 0x00A764, 0x00A77E, 0x00A77F, 0x00A77A,
+ 0x00A77B, 0x00A774, 0x00A775, 0x00A776, 0x00A777, 0x00A771, 0x00A772, 0x00A773,
+ 0x00A74C, 0x00A74D, 0x00A74E, 0x00A74F, 0x00AA07, 0x00A748, 0x00A749, 0x00A745,
+ 0x00A746, 0x00A747, 0x00A740, 0x00A741, 0x00A742, 0x00A743, 0x00A75C, 0x00A75D,
+ 0x00A75E, 0x00A75F, 0x00A758, 0x00A759, 0x00A75A, 0x00A75B, 0x00A754, 0x00A755,
+ 0x00A756, 0x00A757, 0x00A750, 0x00A751, 0x00A752, 0x00A753, 0x00A72C, 0x00A72D,
+ 0x00A72E, 0x00A72F, 0x00A728, 0x00A729, 0x00A72B, 0x00A724, 0x00A725, 0x00A726,
+ 0x00A727, 0x000BAE, 0x000BAF, 0x00A73D, 0x00A73F, 0x00A738, 0x00A739, 0x00A73A,
+ 0x00A73B, 0x00A734, 0x00A736, 0x00A737, 0x00A730, 0x00A731, 0x000BB4, 0x000BB5,
+ 0x000BB6, 0x000BB7, 0x000BB0, 0x000BB1, 0x000BB2, 0x000BB3, 0x000B8E, 0x000B8F,
+ 0x000B88, 0x000B89, 0x000B8A, 0x000B85, 0x000B86, 0x000B87, 0x000B83, 0x000B9C,
+ 0x000B9E, 0x000B9F, 0x000B99, 0x000B9A, 0x000B94, 0x000B95, 0x000B90, 0x000B92,
+ 0x000B93, 0x000868, 0x000869, 0x00A7FD, 0x000866, 0x000867, 0x000862, 0x000863,
+ 0x00A7F7, 0x00084C, 0x00084D, 0x00084E, 0x00084F, 0x000848, 0x000849, 0x00084A,
+ 0x00084B, 0x000844, 0x00AA04, 0x00AA0A, 0x000845, 0x000846, 0x00AA05, 0x000847,
+ 0x000840, 0x000841, 0x000842, 0x000843, 0x000858, 0x00A7AC, 0x00A7AD, 0x000855,
+ 0x00A7A6, 0x00A7A7, 0x00A7A0, 0x00A7A1, 0x00A7A2, 0x00A7A3, 0x00A7B4, 0x00A7B5,
+ 0x00A7B6, 0x00A7B7, 0x00A7B0, 0x00A7B1, 0x00A7B2, 0x00A7B3, 0x00A78C, 0x00A78D,
+ 0x00A78E, 0x00A78F, 0x00A78B, 0x00A784, 0x00A785, 0x00A796, 0x00A797, 0x00A790,
+ 0x00A791, 0x00A792, 0x00A793, 0x00A46C, 0x00A46D, 0x00A468, 0x00A469, 0x00A466,
+ 0x00A467, 0x00A460, 0x00A461, 0x00A462, 0x00A463, 0x00A47C, 0x00A47D, 0x00A47E,
+ 0x00A47F, 0x00A478, 0x00A479, 0x00A47A, 0x00A47B, 0x00A474, 0x00A475, 0x00A476,
+ 0x00A477, 0x00A470, 0x00A471, 0x00A472, 0x00A473, 0x00A44C, 0x00A44D, 0x00A44E,
+ 0x00A44F, 0x00A448, 0x00A449, 0x00A44A, 0x00A44B, 0x00A444, 0x00A445, 0x00A446,
+ 0x00A447, 0x00A440, 0x00A441, 0x00A442, 0x00A443, 0x00A45C, 0x00A45D, 0x00A45E,
+ 0x00A45F, 0x00A458, 0x00A459, 0x00A45A, 0x00A45B, 0x00A454, 0x00A455, 0x00A456,
+ 0x00A457, 0x00A450, 0x00A451, 0x00A452, 0x00A453, 0x00A42C, 0x00A42D, 0x00A42E,
+ 0x00A42F, 0x00A428, 0x00A429, 0x00A42A, 0x00A42B, 0x00A424, 0x00A425, 0x00A430,
+ 0x00A431, 0x00A40F, 0x00A406, 0x00A407, 0x00A400, 0x00A401, 0x00A402, 0x00A403,
+ 0x00A41C, 0x00A41D, 0x00A41E, 0x00A41F, 0x00A418, 0x00A419, 0x00A41A, 0x00A41B,
+ 0x00A414, 0x00A415, 0x00A416, 0x00A417, 0x00A410, 0x00A411, 0x00A412, 0x00A413,
+ 0x00A4EC, 0x00A4ED, 0x00A4EE, 0x00A4EF, 0x00A4E8, 0x00A4E9, 0x00A4EA, 0x00A4EB,
+ 0x00A4E4, 0x00A4E5, 0x00096A, 0x00096B, 0x000966, 0x000967, 0x000960, 0x000961,
+ 0x00A4F4, 0x00A4F5, 0x00097A, 0x00097B, 0x000974, 0x000975, 0x000976, 0x000977,
+ 0x000972, 0x000973, 0x00A4DC, 0x00A4DD, 0x00A4DE, 0x00A4DF, 0x00A4D8, 0x00A4D9,
+ 0x00A4DA, 0x00A4DB, 0x00A4D4, 0x00A4D5, 0x00095A, 0x00095B, 0x000950, 0x00092C,
+ 0x00092D, 0x00092E, 0x00092F, 0x000928, 0x000929, 0x00092A, 0x00092B, 0x000924,
+ 0x000925, 0x000926, 0x000927, 0x000920, 0x000921, 0x000922, 0x000923, 0x00093D,
+ 0x000938, 0x000939, 0x00A48C, 0x000934, 0x000935, 0x00090A, 0x00090B, 0x000904,
+ 0x000905, 0x000906, 0x000907, 0x00091C, 0x00091D, 0x00091E, 0x00091F, 0x000918,
+ 0x000919, 0x00A57E, 0x00A57F, 0x00A574, 0x00A575, 0x00A577, 0x00A570, 0x00A571,
+ 0x00A54C, 0x00A54D, 0x00A544, 0x00A545, 0x00A546, 0x00A547, 0x00A541, 0x00A542,
+ 0x00A543, 0x00A55C, 0x00A55D, 0x00A55E, 0x00A55F, 0x00A558, 0x00A559, 0x00A55A,
+ 0x00A55B, 0x002460, 0x00A554, 0x00A555, 0x00A550, 0x002464, 0x002467, 0x00A552,
+ 0x002469, 0x002468, 0x00246B, 0x00246A, 0x00246D, 0x00246C, 0x00246F, 0x00246E,
+ 0x00A553, 0x002470, 0x00A52C, 0x00A52D, 0x002475, 0x002474, 0x002477, 0x002476,
+ 0x002479, 0x002478, 0x00247B, 0x00247A, 0x00247D, 0x00A52E, 0x00247F, 0x00247E,
+ 0x00A52F, 0x00A528, 0x00A529, 0x00A52A, 0x00A52B, 0x00A524, 0x00A525, 0x00A523,
+ 0x00A536, 0x00A530, 0x00A531, 0x00A50C, 0x00A50D, 0x00A50E, 0x00A50F, 0x00A50B,
+ 0x00A505, 0x00A507, 0x00A500, 0x00A51E, 0x00A51B, 0x00A514, 0x00A515, 0x00A5EB,
+ 0x00A5E4, 0x00A5E6, 0x00A5E7, 0x00A5FC, 0x00A5FD, 0x00A5CA, 0x00A5C6, 0x00A5C7,
+ 0x00A5C0, 0x00A5C1, 0x00A5DD, 0x00A5DA, 0x00A5D6, 0x00A5D7, 0x00A5D0, 0x00A5D1,
+ 0x00A5D2, 0x00A5D3, 0x00A5AC, 0x00A5AD, 0x00A5AE, 0x00A5AF, 0x00A5A8, 0x00A5A9,
+ 0x00A5AA, 0x00A5AB, 0x00A5A4, 0x00A5A5, 0x00A586, 0x00A587, 0x00A580, 0x00A581,
+ 0x00A582, 0x00A583, 0x00A59C, 0x00A59D, 0x00A59E, 0x00A59F, 0x00A598, 0x00A599,
+ 0x00A59A, 0x00A59B, 0x00A594, 0x00A595, 0x00A596, 0x00A597, 0x00A590, 0x00A591,
+ 0x00A592, 0x00A593, 0x00A26C, 0x00A26D, 0x00A26E, 0x00A26F, 0x00A268, 0x00A269,
+ 0x00A26A, 0x00A26B, 0x00A264, 0x00A265, 0x00A266, 0x00A267, 0x00A262, 0x00A263,
+ 0x00A27C, 0x00A27D, 0x00A27E, 0x00A27F, 0x00A278, 0x00A279, 0x00A27A, 0x00A27B,
+ 0x00A274, 0x00A275, 0x00A277, 0x00A270, 0x00A256, 0x00A257, 0x00A250, 0x00A251,
+ 0x00A252, 0x00A253, 0x00A22C, 0x00A22D, 0x00A22E, 0x0024EC, 0x00A228, 0x00A229,
+ 0x00A2C6, 0x0024F0, 0x00A2C2, 0x00A2C3, 0x0024F5, 0x0024F4, 0x0024F7, 0x0024F6,
+ 0x0024F9, 0x0024F8, 0x0024FB, 0x0024FA, 0x0024FD, 0x00A2DC, 0x0024FF, 0x0024FE,
+ 0x00A2DD, 0x00A2DE, 0x00A2DF, 0x00A2D8, 0x00A2D9, 0x00A2DA, 0x00A2DB, 0x00A2D4,
+ 0x00A2D5, 0x00A2B6, 0x00A2B7, 0x00A2B0, 0x00A2B1, 0x00A2B2, 0x00A2B3, 0x00A28C,
+ 0x00A28D, 0x00A28E, 0x00A28F, 0x00A288, 0x00A289, 0x00A28A, 0x00A28B, 0x00A284,
+ 0x00A285, 0x00A286, 0x00A287, 0x00A280, 0x00A281, 0x00A282, 0x00A283, 0x00A29C,
+ 0x00A29D, 0x00A29E, 0x00A29F, 0x00A298, 0x00A299, 0x00A29A, 0x00A29B, 0x00A294,
+ 0x014628, 0x00A295, 0x00A36B, 0x00A366, 0x00A367, 0x00A360, 0x00A361, 0x00A37D,
+ 0x00A376, 0x00A377, 0x00A370, 0x00A371, 0x00A372, 0x00A373, 0x00A34C, 0x00A34D,
+ 0x00A34E, 0x00A34F, 0x00A348, 0x00A349, 0x00A34A, 0x00A34B, 0x00A344, 0x00A345,
+ 0x00A326, 0x00A327, 0x00A320, 0x00A321, 0x00A322, 0x00A323, 0x00A33C, 0x00A33D,
+ 0x00A338, 0x014629, 0x00A339, 0x00A336, 0x00A337, 0x00A330, 0x00A331, 0x00A332,
+ 0x00A333, 0x00A30C, 0x00A30D, 0x011005, 0x00A30E, 0x00A30F, 0x011006, 0x011009,
+ 0x011008, 0x00A308, 0x01100A, 0x01100D, 0x01100C, 0x01100F, 0x01100E, 0x00A309,
+ 0x00A30A, 0x00A304, 0x00A305, 0x00A002, 0x00A003, 0x00A01E, 0x00A01F, 0x00A018,
+ 0x00A019, 0x00A014, 0x00A0FA, 0x00A0D6, 0x00A0D7, 0x00A0D0, 0x00A0D1, 0x00A0D2,
+ 0x00A0D3, 0x00A0AC, 0x00A0AD, 0x00A0A9, 0x00A08A, 0x00A166, 0x00A167, 0x00A160,
+ 0x00A161, 0x00A17D, 0x00A176, 0x00A177, 0x00A170, 0x00A171, 0x00A172, 0x00A173,
+ 0x00A14C, 0x011033, 0x00A14D, 0x00A14E, 0x00A14F, 0x00A148, 0x00A149, 0x00A145,
+ 0x00A146, 0x00A147, 0x00A140, 0x00A141, 0x00A142, 0x00A143, 0x00A15C, 0x00A15D,
+ 0x00A15E, 0x00A15F, 0x00A158, 0x00A159, 0x00A15A, 0x00A15B, 0x00A154, 0x00A155,
+ 0x00A126, 0x00A127, 0x00A120, 0x00A121, 0x00A122, 0x00A123, 0x00A13C, 0x00A13D,
+ 0x00A13E, 0x00A13F, 0x00A138, 0x00A139, 0x00A13A, 0x00A13B, 0x00A134, 0x00A135,
+ 0x00A136, 0x00A137, 0x00A130, 0x00A131, 0x00A132, 0x00A133, 0x00A10C, 0x00A10D,
+ 0x00A10E, 0x00A10F, 0x00A108, 0x00A109, 0x00A10A, 0x00A10B, 0x00A104, 0x00A105,
+ 0x00A106, 0x00A107, 0x00A100, 0x00A101, 0x00A102, 0x00A103, 0x00A11C, 0x00A11D,
+ 0x00A116, 0x00A117, 0x00A110, 0x00A111, 0x00A112, 0x00A113, 0x00A1EC, 0x00A1ED,
+ 0x00A1EE, 0x00A1EF, 0x00A1E8, 0x00A1E9, 0x00A1EA, 0x00A1EB, 0x00A1E4, 0x00A1E5,
+ 0x00021A, 0x00021B, 0x000214, 0x000215, 0x000216, 0x000217, 0x000210, 0x000211,
+ 0x000212, 0x000213, 0x0002AC, 0x0002AD, 0x0002AE, 0x0002AF, 0x0002A8, 0x0002A9,
+ 0x0002AA, 0x0002AB, 0x0002A4, 0x0002A5, 0x0002A6, 0x0002A7, 0x0002A0, 0x0002A1,
+ 0x0002A2, 0x0002A3, 0x00028C, 0x00028D, 0x00028E, 0x00028F, 0x000288, 0x000289,
+ 0x00028A, 0x00028B, 0x000284, 0x000285, 0x000286, 0x000287, 0x000280, 0x000281,
+ 0x000282, 0x000283, 0x00029C, 0x00029D, 0x00029E, 0x00029F, 0x000298, 0x000299,
+ 0x00029A, 0x00029B, 0x000294, 0x000295, 0x000296, 0x000297, 0x000290, 0x000291,
+ 0x000292, 0x000293, 0x00037C, 0x00037D, 0x00037F, 0x00037B, 0x000376, 0x000377,
+ 0x000370, 0x000371, 0x000372, 0x000373, 0x01D66C, 0x01D66D, 0x01D66E, 0x01D66F,
+ 0x01D668, 0x01D669, 0x01D66A, 0x01D66B, 0x01D664, 0x01D665, 0x01D666, 0x01D667,
+ 0x01D660, 0x01D661, 0x01D662, 0x01D663, 0x01D67C, 0x01D67D, 0x01D67E, 0x01D67F,
+ 0x01D678, 0x01D679, 0x01D67A, 0x01D67B, 0x01D674, 0x01D675, 0x01D676, 0x01D677,
+ 0x01D670, 0x01D671, 0x01D654, 0x01D600, 0x01D613, 0x01D6E9, 0x01D6EA, 0x01D6EB,
+ 0x01D6E5, 0x01D6E6, 0x01D6E7, 0x01D6E0, 0x01D6E1, 0x000395, 0x01D6C6, 0x000063,
+ 0x01D6C2, 0x01D6C3, 0x01D6DC, 0x01D6DD, 0x01D6D9, 0x000075, 0x000041, 0x01D6A2,
+ 0x01D6A3, 0x01D6BC, 0x01D6BD, 0x01D6B9, 0x01D6B2, 0x01D6B3, 0x01D68C, 0x01D68D,
+ 0x01D68E, 0x01D68F, 0x01D688, 0x011105, 0x011104, 0x011107, 0x011106, 0x011109,
+ 0x011108, 0x01110B, 0x01110A, 0x01110D, 0x01110C, 0x01110F, 0x01110E, 0x01D689,
+ 0x01D68A, 0x01D68B, 0x01D684, 0x01D685, 0x01D686, 0x01D687, 0x01D680, 0x01D681,
+ 0x01D682, 0x01D683, 0x01D69C, 0x01D69D, 0x01D698, 0x01D699, 0x01D692, 0x011121,
+ 0x011120, 0x011123, 0x011122, 0x01D693, 0x01D76C, 0x01D76D, 0x01D76E, 0x01D768,
+ 0x01D769, 0x01D76A, 0x01D76B, 0x01D764, 0x01D765, 0x01D766, 0x01D767, 0x01D760,
+ 0x01D761, 0x01D762, 0x01D763, 0x01D77C, 0x01D77D, 0x011137, 0x011136, 0x011139,
+ 0x011138, 0x01113B, 0x01113A, 0x01113D, 0x01113C, 0x01113F, 0x01113E, 0x01D77E,
+ 0x01D77F, 0x01D778, 0x01D779, 0x01D77A, 0x01D77B, 0x01D774, 0x01D775, 0x01D776,
+ 0x01D777, 0x01D770, 0x01D771, 0x0000E9, 0x01D755, 0x01D732, 0x01D733, 0x011151,
+ 0x011150, 0x01D70C, 0x011152, 0x011155, 0x011154, 0x011157, 0x011156, 0x011159,
+ 0x011158, 0x01115B, 0x01115A, 0x01115D, 0x01115C, 0x01115F, 0x01115E, 0x01D70D,
+ 0x01D70E, 0x01D70F, 0x01D709, 0x01D70A, 0x01D70B, 0x01D704, 0x01D705, 0x01D706,
+ 0x01D707, 0x01D700, 0x01D701, 0x01D71D, 0x01D71E, 0x01D719, 0x01D71A, 0x01D714,
+ 0x01D716, 0x01D717, 0x01E924, 0x01E925, 0x01D712, 0x01E927, 0x01D713, 0x01D7EC,
+ 0x01D7ED, 0x01D7EE, 0x01D7EF, 0x01D7E8, 0x01D7E9, 0x01D7EA, 0x01D7EB, 0x01D7E4,
+ 0x01D7E5, 0x01D7E6, 0x01D7E7, 0x011185, 0x011184, 0x011187, 0x011186, 0x011189,
+ 0x011188, 0x01118B, 0x01118A, 0x01118D, 0x01118C, 0x01118F, 0x01118E, 0x01D7E0,
+ 0x01D7E1, 0x01D7E2, 0x01D7E3, 0x01D7FC, 0x01D7FD, 0x01D7FE, 0x01D7FF, 0x01D7F8,
+ 0x01D7F9, 0x01D7FA, 0x01D7FB, 0x01D7F4, 0x01D7F5, 0x01D7F6, 0x01D7F7, 0x01D7F0,
+ 0x01D7F1, 0x0111A3, 0x00016E, 0x00016F, 0x00017D, 0x00014B, 0x00012B, 0x0001F7,
+ 0x01D4F2, 0x01D4F3, 0x01D4CC, 0x01D4CD, 0x01D4CE, 0x01D4CF, 0x01D4C8, 0x01D4C9,
+ 0x01D4CA, 0x01D4CB, 0x01D4C5, 0x01D4C6, 0x01D4C7, 0x01D4C0, 0x01D4C1, 0x01D4C2,
+ 0x01D4C3, 0x01D4DC, 0x01D4DD, 0x01D4DE, 0x01D4DF, 0x01D4D8, 0x01D4D9, 0x01D4DA,
+ 0x01D4DB, 0x01D4D4, 0x01D4D5, 0x01D4D6, 0x01D4D7, 0x01D4D0, 0x01D4D1, 0x01D4D2,
+ 0x01D4D3, 0x01D4AC, 0x01D4AE, 0x01D4AF, 0x01D4A9, 0x01D4AA, 0x01D4AB, 0x01D4A5,
+ 0x01D4A6, 0x01D4A2, 0x01D4BD, 0x01D4BE, 0x01D4BF, 0x01D4B8, 0x01D4B9, 0x01D4BB,
+ 0x01D4B4, 0x01D4B5, 0x01D4B6, 0x01D4B7, 0x01D4B0, 0x01D4B1, 0x01D4B2, 0x01D4B3,
+ 0x01D48C, 0x01D48D, 0x01D48E, 0x01D48F, 0x01D488, 0x01D489, 0x01D48A, 0x01D48B,
+ 0x01D484, 0x01D485, 0x01D486, 0x01D487, 0x01D480, 0x01D481, 0x01D482, 0x01D483,
+ 0x01D49C, 0x01D49E, 0x01D49F, 0x01D498, 0x01D499, 0x01D49A, 0x01D49B, 0x01D494,
+ 0x01D495, 0x01D496, 0x01D497, 0x01D490, 0x01D491, 0x01D492, 0x01D493, 0x01D56C,
+ 0x01D56D, 0x01D56E, 0x01D56F, 0x01D568, 0x01D569, 0x01D56A, 0x01D56B, 0x01D564,
+ 0x01D565, 0x01D566, 0x01D567, 0x01D560, 0x01D561, 0x01D562, 0x01D563, 0x01D57C,
+ 0x01D57D, 0x01D57E, 0x01D57F, 0x01D578, 0x01D579, 0x01D57A, 0x01D57B, 0x01D574,
+ 0x01D575, 0x01D576, 0x01D577, 0x01D570, 0x01D571, 0x01D572, 0x01D573, 0x01D54C,
+ 0x01D54D, 0x01D54E, 0x01D54F, 0x01D54A, 0x01D54B, 0x01D544, 0x002777, 0x002776,
+ 0x002779, 0x002778, 0x00277B, 0x00277A, 0x00277D, 0x00277C, 0x00277F, 0x00277E,
+ 0x002781, 0x002780, 0x002783, 0x002782, 0x002785, 0x002784, 0x002787, 0x002786,
+ 0x002789, 0x002788, 0x00278B, 0x00278A, 0x00278D, 0x01D546, 0x00278F, 0x00278E,
+ 0x002791, 0x01D540, 0x002793, 0x002792, 0x01D541, 0x01D542, 0x01D543, 0x01D55C,
+ 0x01D55D, 0x01D55E, 0x01D55F, 0x01D558, 0x01D559, 0x01D55A, 0x01D55B, 0x01D554,
+ 0x01D555, 0x01D556, 0x01D557, 0x01D550, 0x01D552, 0x01D553, 0x01D52C, 0x01D52D,
+ 0x01D52E, 0x01D52F, 0x01D528, 0x01D529, 0x01D52A, 0x01D52B, 0x01D524, 0x01D525,
+ 0x01D526, 0x01D527, 0x01E914, 0x01D520, 0x01D521, 0x01E917, 0x01D522, 0x01D523,
+ 0x01D53C, 0x01D53D, 0x01D53E, 0x01E91D, 0x01D538, 0x01D539, 0x01D53B, 0x01D534,
+ 0x01D535, 0x01D536, 0x01D537, 0x01D530, 0x01D531, 0x01D532, 0x01D533, 0x01D50D,
+ 0x01D50E, 0x01D50F, 0x01D508, 0x01D509, 0x01D50A, 0x01D504, 0x01D505, 0x01D507,
+ 0x01D500, 0x01D501, 0x01D502, 0x01E935, 0x01D503, 0x01D51C, 0x01D51E, 0x01D51F,
+ 0x01D518, 0x01D519, 0x01D51A, 0x01D51B, 0x01D514, 0x01D516, 0x01D517, 0x01D510,
+ 0x01D511, 0x01D512, 0x01D513, 0x01D5EC, 0x01D5ED, 0x01D5EE, 0x01D5EF, 0x01D5E8,
+ 0x01D5E9, 0x01D5EA, 0x01D5EB, 0x01D5E4, 0x01D5E5, 0x01D5E6, 0x01D5E7, 0x01D5E0,
+ 0x01D5E1, 0x01D5E2, 0x01D5E3, 0x01D5FC, 0x01D5FD, 0x01D5FE, 0x01D5FF, 0x01D5F8,
+ 0x01D5F9, 0x01D5FA, 0x01D5FB, 0x01D5F4, 0x01D5F5, 0x01D5F6, 0x01D5F7, 0x01D5F0,
+ 0x01D5F1, 0x01D5F2, 0x01D5F3, 0x01D5CC, 0x01D5CD, 0x01D5CE, 0x01D5CF, 0x01D5C8,
+ 0x01D5C9, 0x01D5CA, 0x01D5CB, 0x01D5C4, 0x01D5C5, 0x01D5C6, 0x01D5C7, 0x01D5C0,
+ 0x01D5C1, 0x01D5C2, 0x01D5C3, 0x01D5DC, 0x01D5DD, 0x01D5DE, 0x01D5DF, 0x01D5D8,
+ 0x01D5D9, 0x01D5DA, 0x01D5DB, 0x01D5D4, 0x01D5D5, 0x01D5D6, 0x01D5D7, 0x01D5D0,
+ 0x01D5D1, 0x01D5D2, 0x01D5D3, 0x01D5AC, 0x01D5AD, 0x01D5AE, 0x01D5AF, 0x01D5A8,
+ 0x01D5A9, 0x01D5AA, 0x01D5AB, 0x01D5A4, 0x01D5A5, 0x01D5A6, 0x01D5A7, 0x01D5A0,
+ 0x01D5A1, 0x01D5A2, 0x01D5A3, 0x01D5BC, 0x01D5BD, 0x01D5BE, 0x01D5BF, 0x01D5B8,
+ 0x01D5B9, 0x01D5BA, 0x01D5BB, 0x01D5B4, 0x01D5B5, 0x01D5B6, 0x01D5B7, 0x01D5B0,
+ 0x01D5B1, 0x01D5B2, 0x01D5B3, 0x01D58C, 0x01D58D, 0x01D58E, 0x01D58F, 0x01D588,
+ 0x01D589, 0x01D58A, 0x01D58B, 0x01D584, 0x01D585, 0x01E8AF, 0x01D586, 0x01D587,
+ 0x01D580, 0x01D581, 0x01D582, 0x01D583, 0x01D59C, 0x01D59D, 0x01D59E, 0x01D59F,
+ 0x01D598, 0x01D599, 0x01D59A, 0x01D59B, 0x01D594, 0x01D595, 0x01D596, 0x01D597,
+ 0x01D590, 0x01D591, 0x01D592, 0x01D593, 0x01D36C, 0x01D36D, 0x01D36E, 0x01D36F,
+ 0x01D368, 0x01D369, 0x01D36A, 0x01D36B, 0x01D364, 0x01D365, 0x01D366, 0x01D367,
+ 0x01D360, 0x01D361, 0x01D362, 0x01D363, 0x01D370, 0x01D371, 0x01342C, 0x01342D,
+ 0x01342E, 0x013428, 0x013429, 0x01342A, 0x01342B, 0x013424, 0x013425, 0x013426,
+ 0x013427, 0x013420, 0x013421, 0x013422, 0x013423, 0x01340C, 0x01340D, 0x01340E,
+ 0x01340F, 0x013408, 0x013409, 0x01340A, 0x01340B, 0x013404, 0x013405, 0x013406,
+ 0x013407, 0x013400, 0x013401, 0x013402, 0x013403, 0x01341C, 0x01341D, 0x01341E,
+ 0x01341F, 0x013418, 0x013419, 0x01341A, 0x01341B, 0x013414, 0x013415, 0x013416,
+ 0x013417, 0x013410, 0x013411, 0x013412, 0x013413, 0x01326C, 0x01326D, 0x01326E,
+ 0x01326F, 0x013268, 0x013269, 0x01326A, 0x01326B, 0x013264, 0x013265, 0x013266,
+ 0x013267, 0x013260, 0x013261, 0x013262, 0x013263, 0x01327C, 0x01327D, 0x01327E,
+ 0x01327F, 0x013278, 0x013279, 0x01327A, 0x01327B, 0x013274, 0x013275, 0x013276,
+ 0x013277, 0x013270, 0x013271, 0x013272, 0x013273, 0x01324C, 0x01324D, 0x01324E,
+ 0x01324F, 0x013248, 0x013249, 0x01324A, 0x01324B, 0x013244, 0x013245, 0x013246,
+ 0x013247, 0x013240, 0x013241, 0x013242, 0x013243, 0x01325C, 0x01325D, 0x01325E,
+ 0x01325F, 0x013258, 0x013259, 0x01B012, 0x01B013, 0x01325A, 0x01325B, 0x013254,
+ 0x013255, 0x01B010, 0x01B011, 0x013256, 0x013257, 0x013250, 0x013251, 0x01B016,
+ 0x01B017, 0x013252, 0x013253, 0x01322C, 0x01322D, 0x01322E, 0x01322F, 0x01B014,
+ 0x01B015, 0x013228, 0x013229, 0x01322A, 0x01322B, 0x013224, 0x013225, 0x013226,
+ 0x013227, 0x01B039, 0x01B03E, 0x01B038, 0x01B03F, 0x01B034, 0x01B035, 0x01B024,
+ 0x01B025, 0x01B02A, 0x01B02B, 0x01B03A, 0x01B03B, 0x01B01C, 0x01B02F, 0x01B03D,
+ 0x01B02E, 0x01B01A, 0x01B019, 0x01B01B, 0x01B018, 0x01B01E, 0x01B002, 0x01B01F,
+ 0x01B003, 0x01B000, 0x01B001, 0x01B028, 0x01B029, 0x013220, 0x01B01D, 0x01B006,
+ 0x01B007, 0x013221, 0x013222, 0x013223, 0x01323C, 0x01323D, 0x01323E, 0x01323F,
+ 0x013238, 0x013239, 0x01323A, 0x01323B, 0x013234, 0x013235, 0x013236, 0x013237,
+ 0x013230, 0x013231, 0x013232, 0x01B053, 0x01B052, 0x013233, 0x01320C, 0x01320D,
+ 0x01320E, 0x01B059, 0x01320F, 0x01B05E, 0x013208, 0x013209, 0x01B05F, 0x01320A,
+ 0x01320B, 0x01B020, 0x01B021, 0x01B022, 0x01B023, 0x01B065, 0x01B064, 0x01B026,
+ 0x01B027, 0x01B069, 0x01B068, 0x01B06B, 0x01B06A, 0x01B06D, 0x01B06C, 0x01B06F,
+ 0x01B06E, 0x013204, 0x013205, 0x013206, 0x013207, 0x013200, 0x013201, 0x013202,
+ 0x013203, 0x01321C, 0x01321D, 0x01321E, 0x01321F, 0x01B03C, 0x013218, 0x013219,
+ 0x01321A, 0x01321B, 0x013214, 0x013215, 0x013216, 0x013217, 0x013210, 0x011411,
+ 0x011410, 0x011413, 0x011412, 0x011415, 0x011414, 0x011417, 0x011416, 0x013211,
+ 0x013212, 0x01141B, 0x01141A, 0x013213, 0x0132EC, 0x0132ED, 0x0132EE, 0x0132EF,
+ 0x0132E8, 0x0132E9, 0x0132EA, 0x0132EB, 0x0132E4, 0x0132E5, 0x0132E6, 0x0132E7,
+ 0x0132E0, 0x0132E1, 0x0132E2, 0x0132E3, 0x0132FC, 0x0132FD, 0x0132FE, 0x0132FF,
+ 0x0132F8, 0x0132F9, 0x0132FA, 0x0132FB, 0x0132F4, 0x0132F5, 0x0132F6, 0x0132F7,
+ 0x0132F0, 0x0132F1, 0x0132F2, 0x0132F3, 0x0132CC, 0x0132CD, 0x0132CE, 0x0132CF,
+ 0x0132C8, 0x0132C9, 0x0132CA, 0x0132CB, 0x0132C4, 0x0132C5, 0x0132C6, 0x0132C7,
+ 0x0132C0, 0x0132C1, 0x0132C2, 0x0132C3, 0x0132DC, 0x0132DD, 0x0132DE, 0x0132DF,
+ 0x0132D8, 0x0132D9, 0x0132DA, 0x0132DB, 0x0132D4, 0x0132D5, 0x0132D6, 0x0132D7,
+ 0x0132D0, 0x0132D1, 0x0132D2, 0x0132D3, 0x0132AC, 0x0132AD, 0x0132AE, 0x0132AF,
+ 0x0132A8, 0x0132A9, 0x0132AA, 0x0132AB, 0x0132A4, 0x0132A5, 0x0132A6, 0x0132A7,
+ 0x0132A0, 0x0132A1, 0x0132A2, 0x01B0EE, 0x01B0EF, 0x01B0E5, 0x01B0E4, 0x0132A3,
+ 0x0132BC, 0x01B0E9, 0x01B0E8, 0x0132BD, 0x0132BE, 0x0132BF, 0x0132B8, 0x01B0EA,
+ 0x01B0EB, 0x0132B9, 0x0132BA, 0x0132BB, 0x0132B4, 0x0132B5, 0x0132B6, 0x011482,
+ 0x011483, 0x01B0EC, 0x01B0ED, 0x01149C, 0x01149D, 0x01149E, 0x01149F, 0x011498,
+ 0x011499, 0x01B101, 0x01B100, 0x01B103, 0x01B102, 0x01149A, 0x01149B, 0x01B107,
+ 0x01B106, 0x011493, 0x011492, 0x011490, 0x011491, 0x011497, 0x011496, 0x011494,
+ 0x011495, 0x01B111, 0x01B110, 0x01B113, 0x01B112, 0x01B115, 0x01B114, 0x01B117,
+ 0x01B116, 0x01B119, 0x01B118, 0x01B11B, 0x01B11A, 0x01B11D, 0x01B11C, 0x011481,
+ 0x01B11E, 0x011480, 0x01148B, 0x011485, 0x011486, 0x011484, 0x011487, 0x0114A0,
+ 0x0114A1, 0x0114A2, 0x0114A3, 0x01148C, 0x01148D, 0x01148E, 0x01148F, 0x0114AB,
+ 0x0114A5, 0x01148A, 0x0114A4, 0x0114A6, 0x011489, 0x0114A7, 0x011488, 0x0114C4,
+ 0x0132B7, 0x0132B0, 0x0132B1, 0x0114D6, 0x0114D7, 0x0114C7, 0x0114C5, 0x0132B2,
+ 0x0132B3, 0x01328C, 0x01328D, 0x01328E, 0x01328F, 0x013288, 0x013289, 0x0114D2,
+ 0x0114D3, 0x0114D0, 0x0114D1, 0x01328A, 0x0114D4, 0x01328B, 0x0114D5, 0x0114D9,
+ 0x0114D8, 0x013284, 0x013285, 0x013286, 0x013287, 0x013280, 0x013281, 0x013282,
+ 0x013283, 0x01329C, 0x01329D, 0x01329E, 0x01329F, 0x013298, 0x013299, 0x0114A8,
+ 0x0114A9, 0x0114AA, 0x01329A, 0x0114AC, 0x0114AD, 0x0114AE, 0x0114AF, 0x01329B,
+ 0x013294, 0x013295, 0x013296, 0x013297, 0x013290, 0x013291, 0x013292, 0x013293,
+ 0x01336C, 0x01336D, 0x01336E, 0x01336F, 0x013368, 0x013369, 0x01336A, 0x01336B,
+ 0x013364, 0x013365, 0x013366, 0x013367, 0x013360, 0x013361, 0x013362, 0x013363,
+ 0x01337C, 0x01337D, 0x01337E, 0x01337F, 0x013378, 0x013379, 0x01337A, 0x01337B,
+ 0x013374, 0x013375, 0x013376, 0x013377, 0x013370, 0x013371, 0x013372, 0x013373,
+ 0x01334C, 0x01334D, 0x01334E, 0x01334F, 0x013348, 0x013349, 0x01334A, 0x01334B,
+ 0x013344, 0x013345, 0x013346, 0x013347, 0x013340, 0x013341, 0x013342, 0x013343,
+ 0x01335C, 0x01335D, 0x01335E, 0x01335F, 0x013358, 0x013359, 0x01335A, 0x01335B,
+ 0x013354, 0x013355, 0x013356, 0x013357, 0x013350, 0x013351, 0x013352, 0x013353,
+ 0x01332C, 0x01332D, 0x01332E, 0x01332F, 0x013328, 0x013329, 0x01332A, 0x01332B,
+ 0x013324, 0x013325, 0x013326, 0x013327, 0x013320, 0x013321, 0x013322, 0x013323,
+ 0x01333C, 0x01333D, 0x01333E, 0x01333F, 0x013338, 0x013339, 0x01333A, 0x01333B,
+ 0x013334, 0x013335, 0x013336, 0x013337, 0x013330, 0x013331, 0x013332, 0x013333,
+ 0x01330C, 0x01330D, 0x01330E, 0x01330F, 0x013308, 0x013309, 0x01330A, 0x01330B,
+ 0x013304, 0x013305, 0x013306, 0x013307, 0x013300, 0x013301, 0x013302, 0x013303,
+ 0x01331C, 0x01331D, 0x01331E, 0x01331F, 0x013318, 0x013319, 0x01331A, 0x01331B,
+ 0x013314, 0x013315, 0x013316, 0x013317, 0x013310, 0x013311, 0x013312, 0x013313,
+ 0x0133EC, 0x0133ED, 0x0133EE, 0x0133EF, 0x0133E8, 0x0133E9, 0x0133EA, 0x011581,
+ 0x011580, 0x011583, 0x011582, 0x0133EB, 0x011584, 0x011587, 0x011586, 0x011589,
+ 0x011588, 0x01158B, 0x01158A, 0x01158D, 0x01158C, 0x01158F, 0x01158E, 0x0133E4,
+ 0x0133E5, 0x0133E6, 0x0133E7, 0x0133E0, 0x0133E1, 0x0133E2, 0x0133E3, 0x011599,
+ 0x011598, 0x0133FC, 0x0133FD, 0x01159D, 0x01159C, 0x01159F, 0x01159E, 0x0133FE,
+ 0x0133FF, 0x0133F8, 0x0133F9, 0x0133FA, 0x0133FB, 0x0133F4, 0x0133F5, 0x0133F6,
+ 0x0133F7, 0x0133F0, 0x0133F1, 0x0133F2, 0x0133F3, 0x0133CC, 0x0133CD, 0x0133CE,
+ 0x0133CF, 0x0133C8, 0x0133C9, 0x0133CA, 0x0133CB, 0x0133C4, 0x0133C5, 0x0133C6,
+ 0x0133C7, 0x0133C0, 0x0133C1, 0x0133C2, 0x0133C3, 0x0133DC, 0x0133DD, 0x0133DE,
+ 0x0133DF, 0x0133D8, 0x0133D9, 0x0133DA, 0x0133DB, 0x0133D4, 0x0133D5, 0x0133D6,
+ 0x0133D7, 0x0133D0, 0x0133D1, 0x0133D2, 0x0133D3, 0x0133AC, 0x0133AD, 0x0133AE,
+ 0x0133AF, 0x0133A8, 0x0133A9, 0x0133AA, 0x0133AB, 0x0133A4, 0x0133A5, 0x0133A6,
+ 0x0133A7, 0x0133A0, 0x0133A1, 0x0133A2, 0x0133A3, 0x0133BC, 0x0133BD, 0x0133BE,
+ 0x0133BF, 0x0133B8, 0x0133B9, 0x0133BA, 0x0133BB, 0x0133B4, 0x0133B5, 0x0133B6,
+ 0x0133B7, 0x0133B0, 0x0133B1, 0x0133B2, 0x0133B3, 0x01338C, 0x01338D, 0x01338E,
+ 0x01338F, 0x013388, 0x013389, 0x01338A, 0x01338B, 0x013384, 0x013385, 0x013386,
+ 0x013387, 0x013380, 0x013381, 0x013382, 0x013383, 0x01339C, 0x01339D, 0x01339E,
+ 0x01339F, 0x011603, 0x013398, 0x013399, 0x01339A, 0x01339B, 0x013394, 0x013395,
+ 0x013396, 0x013397, 0x013390, 0x013391, 0x013392, 0x013393, 0x01306C, 0x011611,
+ 0x011610, 0x011613, 0x011612, 0x011615, 0x011614, 0x011617, 0x011616, 0x011619,
+ 0x011618, 0x01161B, 0x01161A, 0x01161D, 0x01161C, 0x01161F, 0x01161E, 0x011621,
+ 0x011620, 0x01306D, 0x011622, 0x011625, 0x011624, 0x011627, 0x011626, 0x011629,
+ 0x011628, 0x01162B, 0x01162A, 0x01162D, 0x01162C, 0x01162F, 0x01162E, 0x01306E,
+ 0x01306F, 0x013068, 0x013069, 0x01306A, 0x01306B, 0x013064, 0x013065, 0x013066,
+ 0x013067, 0x013060, 0x013061, 0x013062, 0x013063, 0x01307C, 0x01307D, 0x01307E,
+ 0x01307F, 0x013078, 0x013079, 0x01307A, 0x011644, 0x01307B, 0x013074, 0x013075,
+ 0x013076, 0x013077, 0x013070, 0x013071, 0x013072, 0x013073, 0x01304C, 0x011651,
+ 0x011650, 0x011653, 0x011652, 0x011655, 0x011654, 0x011657, 0x011656, 0x011659,
+ 0x011658, 0x01304D, 0x01304E, 0x01304F, 0x013048, 0x013049, 0x01304A, 0x01304B,
+ 0x013044, 0x013045, 0x013046, 0x013047, 0x013040, 0x013041, 0x013042, 0x013043,
+ 0x01305C, 0x01305D, 0x01305E, 0x01305F, 0x013058, 0x013059, 0x01305A, 0x01305B,
+ 0x013054, 0x013055, 0x013056, 0x013057, 0x013050, 0x013051, 0x013052, 0x013053,
+ 0x01302C, 0x01302D, 0x01302E, 0x01302F, 0x013028, 0x013029, 0x01302A, 0x01302B,
+ 0x013024, 0x011683, 0x013025, 0x013026, 0x013027, 0x013020, 0x013021, 0x013022,
+ 0x013023, 0x01303C, 0x01303D, 0x01303E, 0x01303F, 0x013038, 0x013039, 0x011691,
+ 0x011690, 0x011693, 0x011692, 0x011695, 0x011694, 0x011697, 0x01303A, 0x011699,
+ 0x011698, 0x01169B, 0x01169A, 0x01169D, 0x01169C, 0x01169F, 0x01303B, 0x0116A1,
+ 0x0116A0, 0x013034, 0x0116A2, 0x0116A5, 0x0116A4, 0x0116A7, 0x0116A6, 0x0116A9,
+ 0x0116A8, 0x013035, 0x0116AA, 0x013036, 0x013037, 0x013030, 0x013031, 0x013032,
+ 0x013033, 0x01300C, 0x01300D, 0x01300E, 0x01300F, 0x013008, 0x013009, 0x01300A,
+ 0x01300B, 0x013004, 0x013005, 0x013006, 0x013007, 0x013000, 0x013001, 0x0116C1,
+ 0x0116C0, 0x0116C3, 0x0116C2, 0x0116C5, 0x0116C4, 0x0116C7, 0x0116C6, 0x0116C9,
+ 0x0116C8, 0x013002, 0x013003, 0x01301C, 0x01301D, 0x01301E, 0x01301F, 0x013018,
+ 0x013019, 0x01301A, 0x01301B, 0x013014, 0x013015, 0x013016, 0x013017, 0x013010,
+ 0x013011, 0x013012, 0x013013, 0x0130EC, 0x0130ED, 0x0130EE, 0x0130EF, 0x0130E8,
+ 0x0130E9, 0x0130EA, 0x0130EB, 0x0130E4, 0x0130E5, 0x0130E6, 0x0130E7, 0x0130E0,
+ 0x0130E1, 0x0130E2, 0x0130E3, 0x0130FC, 0x0130FD, 0x0130FE, 0x0130FF, 0x0130F8,
+ 0x0130F9, 0x0130FA, 0x0130FB, 0x0130F4, 0x0130F5, 0x0130F6, 0x0130F7, 0x0130F0,
+ 0x0130F1, 0x0130F2, 0x0130F3, 0x0130CC, 0x0130CD, 0x0130CE, 0x0130CF, 0x0130C8,
+ 0x0130C9, 0x0130CA, 0x0130CB, 0x0130C4, 0x0130C5, 0x0130C6, 0x0130C7, 0x0130C0,
+ 0x0130C1, 0x0130C2, 0x0130C3, 0x0130DC, 0x0130DD, 0x0130DE, 0x0130DF, 0x0130D8,
+ 0x0130D9, 0x0130DA, 0x0130DB, 0x0130D4, 0x0130D5, 0x0130D6, 0x0130D7, 0x0130D0,
+ 0x0130D1, 0x0130D2, 0x0130D3, 0x0130AC, 0x0130AD, 0x0130AE, 0x0130AF, 0x0130A8,
+ 0x0130A9, 0x0130AA, 0x0130AB, 0x0130A4, 0x0130A5, 0x0130A6, 0x0130A7, 0x0130A0,
+ 0x0130A1, 0x0130A2, 0x0130A3, 0x0130BC, 0x0130BD, 0x0130BE, 0x0130BF, 0x0130B8,
+ 0x002C81, 0x002C80, 0x002C83, 0x002C82, 0x002C85, 0x0130B9, 0x002C87, 0x002C86,
+ 0x002C89, 0x0130BA, 0x0130BB, 0x002C8A, 0x0130B4, 0x0130B5, 0x0130B6, 0x0130B7,
+ 0x002C91, 0x002C90, 0x002C93, 0x002C92, 0x002C95, 0x002C94, 0x002C97, 0x002C96,
+ 0x002C99, 0x002C98, 0x002C9B, 0x002C9A, 0x002C9D, 0x002C9C, 0x002C9F, 0x002C9E,
+ 0x0130B0, 0x0130B1, 0x0130B2, 0x0130B3, 0x01308C, 0x01308D, 0x01308E, 0x01308F,
+ 0x013088, 0x013089, 0x01308A, 0x01308B, 0x013084, 0x013085, 0x013086, 0x013087,
+ 0x013080, 0x013081, 0x013082, 0x013083, 0x002CB5, 0x01309C, 0x01309D, 0x01309E,
+ 0x01309F, 0x013098, 0x013099, 0x01309A, 0x01309B, 0x013094, 0x013095, 0x013096,
+ 0x013097, 0x013090, 0x013091, 0x013092, 0x013093, 0x01316C, 0x01316D, 0x01316E,
+ 0x01316F, 0x013168, 0x013169, 0x01316A, 0x01316B, 0x013164, 0x013165, 0x013166,
+ 0x013167, 0x013160, 0x013161, 0x013162, 0x013163, 0x01317C, 0x01317D, 0x01317E,
+ 0x01317F, 0x013178, 0x013179, 0x01317A, 0x01317B, 0x013174, 0x013175, 0x013176,
+ 0x013177, 0x013170, 0x013171, 0x013172, 0x013173, 0x01314C, 0x01314D, 0x01314E,
+ 0x01314F, 0x013148, 0x013149, 0x01314A, 0x01314B, 0x013144, 0x013145, 0x013146,
+ 0x013147, 0x013140, 0x013141, 0x013142, 0x013143, 0x01315C, 0x01315D, 0x01315E,
+ 0x01315F, 0x013158, 0x013159, 0x01315A, 0x01315B, 0x013154, 0x013155, 0x013156,
+ 0x013157, 0x013150, 0x013151, 0x013152, 0x013153, 0x01312C, 0x01312D, 0x01312E,
+ 0x01312F, 0x013128, 0x013129, 0x01312A, 0x01312B, 0x002D0C, 0x013124, 0x013125,
+ 0x002D11, 0x002D10, 0x002D13, 0x002D12, 0x002D15, 0x013126, 0x002D17, 0x002D16,
+ 0x002D19, 0x013127, 0x002D1B, 0x002D1A, 0x013120, 0x013121, 0x013122, 0x013123,
+ 0x01313C, 0x01313D, 0x01313E, 0x01313F, 0x013138, 0x013139, 0x01313A, 0x01313B,
+ 0x013134, 0x013135, 0x013136, 0x013137, 0x013130, 0x013131, 0x013132, 0x013133,
+ 0x002D31, 0x002D30, 0x002D33, 0x002D32, 0x002D35, 0x01310C, 0x002D37, 0x002D36,
+ 0x002D39, 0x01310D, 0x01310E, 0x002D3A, 0x01310F, 0x013108, 0x013109, 0x01310A,
+ 0x002D41, 0x002D40, 0x002D43, 0x002D42, 0x002D45, 0x002D44, 0x002D47, 0x002D46,
+ 0x002D49, 0x002D48, 0x002D4B, 0x002D4A, 0x002D4D, 0x002D4C, 0x002D4F, 0x002D4E,
+ 0x01310B, 0x013104, 0x013105, 0x013106, 0x013107, 0x013100, 0x013101, 0x013102,
+ 0x013103, 0x01311C, 0x01311D, 0x01311E, 0x01311F, 0x002D5C, 0x013118, 0x013119,
+ 0x01311A, 0x01311B, 0x013114, 0x013115, 0x013116, 0x013117, 0x013110, 0x013111,
+ 0x013112, 0x013113, 0x0131EC, 0x0131ED, 0x0131EE, 0x0131EF, 0x0131E8, 0x0131E9,
+ 0x0131EA, 0x0131EB, 0x0131E4, 0x0131E5, 0x0131E6, 0x0131E7, 0x0131E0, 0x0131E1,
+ 0x0131E2, 0x0131E3, 0x0131FC, 0x0131FD, 0x0131FE, 0x0131FF, 0x0131F8, 0x0131F9,
+ 0x0131FA, 0x0131FB, 0x0131F4, 0x0131F5, 0x0131F6, 0x0131F7, 0x0131F0, 0x0131F1,
+ 0x0131F2, 0x0131F3, 0x0131CC, 0x0131CD, 0x0131CE, 0x0131CF, 0x0131C8, 0x0131C9,
+ 0x0131CA, 0x0131CB, 0x0131C4, 0x0131C5, 0x0131C6, 0x0131C7, 0x0131C0, 0x0131C1,
+ 0x0131C2, 0x0131C3, 0x0131DC, 0x0131DD, 0x0131DE, 0x0131DF, 0x0131D8, 0x0131D9,
+ 0x0131DA, 0x0131DB, 0x0131D4, 0x0131D5, 0x0131D6, 0x0131D7, 0x0131D0, 0x0131D1,
+ 0x0131D2, 0x0131D3, 0x0131AC, 0x0131AD, 0x0131AE, 0x0131AF, 0x0131A8, 0x0131A9,
+ 0x0131AA, 0x0131AB, 0x0131A4, 0x0131A5, 0x0131A6, 0x0131A7, 0x0131A0, 0x0131A1,
+ 0x0131A2, 0x0131A3, 0x0131BC, 0x0131BD, 0x0131BE, 0x0131BF, 0x0131B8, 0x0131B9,
+ 0x002DC1, 0x002DC0, 0x002DC3, 0x002DC2, 0x002DC5, 0x002DC4, 0x0131BA, 0x002DC6,
+ 0x002DC9, 0x002DC8, 0x002DCB, 0x002DCA, 0x002DCD, 0x002DCC, 0x0131BB, 0x002DCE,
+ 0x0131B4, 0x0131B5, 0x0131B6, 0x0131B7, 0x0131B0, 0x0131B1, 0x0131B2, 0x0131B3,
+ 0x01318C, 0x01318D, 0x01318E, 0x01318F, 0x013188, 0x002DDC, 0x013189, 0x01318A,
+ 0x01318B, 0x013184, 0x013185, 0x013186, 0x013187, 0x013180, 0x013181, 0x013182,
+ 0x013183, 0x01319C, 0x01319D, 0x01319E, 0x01319F, 0x013198, 0x013199, 0x01319A,
+ 0x01319B, 0x013194, 0x013195, 0x013196, 0x013197, 0x013190, 0x013191, 0x013192,
+ 0x013193, 0x02FA0C, 0x02FA0D, 0x02FA0E, 0x02FA0F, 0x02FA08, 0x02FA09, 0x02FA0A,
+ 0x02FA0B, 0x02FA04, 0x02FA05, 0x02FA06, 0x02FA07, 0x02FA00, 0x02FA01, 0x02FA02,
+ 0x02FA03, 0x02FA1C, 0x02FA1D, 0x02FA18, 0x02FA19, 0x02FA1A, 0x02FA1B, 0x02FA14,
+ 0x02FA15, 0x02FA16, 0x02FA17, 0x02FA10, 0x02FA11, 0x02FA12, 0x02FA13, 0x01246C,
+ 0x01246D, 0x01246E, 0x012468, 0x012469, 0x01246A, 0x01246B, 0x012464, 0x012465,
+ 0x012466, 0x012467, 0x012460, 0x012461, 0x012462, 0x012463, 0x01244C, 0x01244D,
+ 0x01244E, 0x01244F, 0x012448, 0x012449, 0x01244A, 0x01244B, 0x012444, 0x012445,
+ 0x012446, 0x012447, 0x012440, 0x012441, 0x012442, 0x012443, 0x01245C, 0x01245D,
+ 0x01245E, 0x01245F, 0x012458, 0x012459, 0x01245A, 0x01245B, 0x012454, 0x012455,
+ 0x012456, 0x012457, 0x012450, 0x012451, 0x012452, 0x012453, 0x01242C, 0x01242D,
+ 0x01242E, 0x01242F, 0x012428, 0x012429, 0x01242A, 0x01242B, 0x012424, 0x012425,
+ 0x012426, 0x012427, 0x012420, 0x012421, 0x012422, 0x012423, 0x01243C, 0x01243D,
+ 0x01243E, 0x01243F, 0x012438, 0x012439, 0x01243A, 0x01243B, 0x012434, 0x012435,
+ 0x012436, 0x012437, 0x012430, 0x012431, 0x012432, 0x012433, 0x01240C, 0x01240D,
+ 0x01240E, 0x01240F, 0x012408, 0x012409, 0x01240A, 0x01240B, 0x012404, 0x012405,
+ 0x012406, 0x012407, 0x012400, 0x012401, 0x012402, 0x012403, 0x01241C, 0x01241D,
+ 0x01241E, 0x01241F, 0x012418, 0x012419, 0x01241A, 0x01241B, 0x012414, 0x012415,
+ 0x012416, 0x012417, 0x012410, 0x012411, 0x012412, 0x012413, 0x0124EC, 0x0124ED,
+ 0x0124EE, 0x0124EF, 0x0124E8, 0x0124E9, 0x0124EA, 0x0124EB, 0x0124E4, 0x0124E5,
+ 0x0124E6, 0x0124E7, 0x0124E0, 0x0124E1, 0x0124E2, 0x0124E3, 0x0124FC, 0x0124FD,
+ 0x0124FE, 0x0124FF, 0x0124F8, 0x0124F9, 0x0124FA, 0x0124FB, 0x0124F4, 0x0124F5,
+ 0x0124F6, 0x0124F7, 0x0124F0, 0x0124F1, 0x0124F2, 0x0124F3, 0x0124CC, 0x0124CD,
+ 0x0124CE, 0x0124CF, 0x0124C8, 0x0124C9, 0x0124CA, 0x0124CB, 0x0124C4, 0x0124C5,
+ 0x0124C6, 0x0124C7, 0x0124C0, 0x0124C1, 0x0124C2, 0x0124C3, 0x0124DC, 0x0124DD,
+ 0x0124DE, 0x0124DF, 0x0124D8, 0x0124D9, 0x0124DA, 0x0124DB, 0x0124D4, 0x0124D5,
+ 0x0124D6, 0x0124D7, 0x0124D0, 0x0124D1, 0x0124D2, 0x0124D3, 0x0124AC, 0x0124AD,
+ 0x0124AE, 0x0124AF, 0x0124A8, 0x0124A9, 0x0124AA, 0x0124AB, 0x0124A4, 0x0124A5,
+ 0x0124A6, 0x0124A7, 0x0124A0, 0x0124A1, 0x0124A2, 0x0124A3, 0x0124BC, 0x0124BD,
+ 0x0124BE, 0x0124BF, 0x0124B8, 0x0124B9, 0x0124BA, 0x0124BB, 0x0124B4, 0x0124B5,
+ 0x0124B6, 0x0124B7, 0x0124B0, 0x0124B1, 0x0124B2, 0x0124B3, 0x01248C, 0x01248D,
+ 0x01248E, 0x01248F, 0x012488, 0x012489, 0x01248A, 0x01248B, 0x012484, 0x012485,
+ 0x012486, 0x012487, 0x012480, 0x012481, 0x012482, 0x012483, 0x01249C, 0x01249D,
+ 0x01249E, 0x01249F, 0x012498, 0x012499, 0x01249A, 0x01249B, 0x012494, 0x012495,
+ 0x012496, 0x012497, 0x012490, 0x012491, 0x012492, 0x012493, 0x012540, 0x012541,
+ 0x012542, 0x012543, 0x01252C, 0x01252D, 0x01252E, 0x01252F, 0x012528, 0x012539,
+ 0x01253A, 0x01253B, 0x012534, 0x02F84F, 0x016801, 0x016800, 0x016803, 0x016802,
+ 0x016805, 0x016804, 0x016807, 0x016806, 0x016809, 0x016808, 0x01680B, 0x01680A,
+ 0x01680D, 0x01680C, 0x01680F, 0x01680E, 0x016811, 0x016810, 0x016813, 0x016812,
+ 0x016815, 0x016814, 0x016817, 0x016816, 0x016819, 0x016818, 0x01681B, 0x01681A,
+ 0x01681D, 0x016849, 0x01681F, 0x01681E, 0x016821, 0x016820, 0x016823, 0x016822,
+ 0x016825, 0x016824, 0x016827, 0x016826, 0x016829, 0x016828, 0x01682B, 0x01682A,
+ 0x01682D, 0x01682C, 0x01682F, 0x01682E, 0x016831, 0x016862, 0x016833, 0x016832,
+ 0x016835, 0x016842, 0x016837, 0x01686B, 0x01687D, 0x016838, 0x01684E, 0x01684D,
+ 0x01683D, 0x01683C, 0x01683F, 0x01683E, 0x011A00, 0x016840, 0x01681C, 0x01685E,
+ 0x016843, 0x011A0B, 0x016844, 0x011A0E, 0x011A0F, 0x01684B, 0x01685F, 0x011A11,
+ 0x011A10, 0x011A13, 0x011A12, 0x011A15, 0x011A1B, 0x011A17, 0x016857, 0x016852,
+ 0x011A14, 0x011A18, 0x01686F, 0x016855, 0x01685D, 0x011A16, 0x011A1A, 0x016853,
+ 0x016851, 0x011A32, 0x016850, 0x01684F, 0x01685C, 0x011A22, 0x011A23, 0x01683A,
+ 0x01686D, 0x016834, 0x016860, 0x011A24, 0x011A2B, 0x016861, 0x01687C, 0x011A21,
+ 0x011A27, 0x011A1C, 0x011A3A, 0x01687E, 0x011A0D, 0x011A1E, 0x01684A, 0x01685B,
+ 0x011A19, 0x016854, 0x016856, 0x016859, 0x011A1D, 0x011A1F, 0x01685A, 0x01687F,
+ 0x016878, 0x016836, 0x016877, 0x016830, 0x011A31, 0x011A30, 0x016883, 0x016882,
+ 0x016881, 0x016886, 0x016885, 0x016880, 0x016884, 0x01688D, 0x01687A, 0x01687B,
+ 0x01689C, 0x01688C, 0x01688F, 0x01688E, 0x016892, 0x016895, 0x016893, 0x011A0C,
+ 0x011A50, 0x016896, 0x016897, 0x016891, 0x016890, 0x01689D, 0x016899, 0x016894,
+ 0x016898, 0x01689E, 0x01689F, 0x01689A, 0x011A20, 0x01686E, 0x011A5D, 0x011A5C,
+ 0x016875, 0x011A5E, 0x011A5F, 0x016874, 0x0168B8, 0x0168B9, 0x016839, 0x011A71,
+ 0x011A73, 0x011A2E, 0x011A72, 0x011A70, 0x0168B1, 0x011A25, 0x0168B3, 0x0168B2,
+ 0x0168B5, 0x0168B4, 0x0168B7, 0x0168B6, 0x0168B0, 0x0168BA, 0x0168BB, 0x011A81,
+ 0x011A80, 0x011A83, 0x011A82, 0x01686C, 0x0168C5, 0x011A87, 0x0168C1, 0x011A89,
+ 0x016871, 0x0168C4, 0x0168C7, 0x0168C6, 0x011A88, 0x011A86, 0x0168C2, 0x0168C3,
+ 0x0168C0, 0x0168E4, 0x01684C, 0x016870, 0x0168C8, 0x016858, 0x016848, 0x016841,
+ 0x011AC7, 0x016845, 0x016846, 0x016847, 0x0168C9, 0x0168D8, 0x0168CA, 0x0168CB,
+ 0x0168DD, 0x0168DC, 0x0168DF, 0x0168DE, 0x0168E5, 0x016872, 0x0168E6, 0x0168E7,
+ 0x0168E0, 0x0168E1, 0x0168E2, 0x0168E3, 0x016876, 0x0168E8, 0x0168EC, 0x0168ED,
+ 0x0168EE, 0x0168EF, 0x0168EA, 0x0168EB, 0x016864, 0x0168E9, 0x016867, 0x011A76,
+ 0x0168FC, 0x0168FD, 0x011A2F, 0x016873, 0x0168FE, 0x0168FF, 0x011A2A, 0x011AC1,
+ 0x011AC0, 0x011AC3, 0x011AC2, 0x011AC5, 0x011AC4, 0x011A77, 0x011AC6, 0x011AC9,
+ 0x011AC8, 0x011ACB, 0x011ACA, 0x011ACD, 0x011ACC, 0x011ACF, 0x011ACE, 0x011AD2,
+ 0x011AD7, 0x011AD3, 0x011AD1, 0x011AD5, 0x011AD4, 0x011AD0, 0x011AD6, 0x011AD9,
+ 0x011AD8, 0x011ADB, 0x011ADA, 0x011ADD, 0x011ADC, 0x011ADF, 0x011ADE, 0x011AE1,
+ 0x011AE0, 0x011AE3, 0x011AE2, 0x011AE5, 0x011AE4, 0x011AE7, 0x011AE6, 0x011AE9,
+ 0x011AE8, 0x011AEB, 0x011AEA, 0x011AED, 0x011AEC, 0x011AEF, 0x011AEE, 0x011AF1,
+ 0x011AF0, 0x011AF3, 0x011AF2, 0x011AF5, 0x011AF4, 0x011AF7, 0x011AF6, 0x003043,
+ 0x011AF8, 0x003041, 0x003042, 0x003045, 0x003048, 0x003082, 0x003046, 0x003047,
+ 0x003022, 0x003021, 0x003023, 0x003080, 0x003044, 0x00304D, 0x003057, 0x003056,
+ 0x00304F, 0x003038, 0x003007, 0x00304B, 0x003055, 0x00305C, 0x00304A, 0x003049,
+ 0x003066, 0x003065, 0x00304E, 0x003061, 0x003067, 0x00305D, 0x003006, 0x00305E,
+ 0x003059, 0x0030A7, 0x003058, 0x003039, 0x00304C, 0x00316D, 0x00305F, 0x011A2C,
+ 0x003072, 0x003073, 0x011A26, 0x00303A, 0x016961, 0x016960, 0x003054, 0x011A29,
+ 0x00305B, 0x016869, 0x016863, 0x016866, 0x00305A, 0x01696D, 0x003071, 0x00303C,
+ 0x01696E, 0x01696C, 0x01696F, 0x003092, 0x00111E, 0x00111F, 0x003090, 0x011A28,
+ 0x003081, 0x016865, 0x001118, 0x001119, 0x011A2D, 0x016879, 0x01686A, 0x011A6F,
+ 0x00111A, 0x01697F, 0x003094, 0x01697E, 0x011A7D, 0x011A7C, 0x001115, 0x003093,
+ 0x011A79, 0x011A7A, 0x00111B, 0x011A78, 0x011A7E, 0x003095, 0x011A7F, 0x011A7B,
+ 0x011A6C, 0x001101, 0x0030A3, 0x0030A2, 0x001133, 0x0030A1, 0x001106, 0x001107,
+ 0x0030B8, 0x0030B9, 0x00110A, 0x011A6E, 0x001105, 0x00111D, 0x011A63, 0x011A62,
+ 0x0030BA, 0x0030B5, 0x0030BD, 0x0030BF, 0x00308E, 0x0030B4, 0x0030B7, 0x0030B6,
+ 0x0030BB, 0x00308D, 0x003083, 0x00308F, 0x003088, 0x011A74, 0x0030BC, 0x0030BE,
+ 0x011A61, 0x011A60, 0x001142, 0x00309F, 0x011A66, 0x003096, 0x011A67, 0x011A68,
+ 0x011A6B, 0x011A6A, 0x011A69, 0x011A75, 0x011A65, 0x011A64, 0x011A6D, 0x001109,
+ 0x001140, 0x001141, 0x001144, 0x001143, 0x003091, 0x001145, 0x001146, 0x001147,
+ 0x001138, 0x001149, 0x00113A, 0x00114B, 0x00115C, 0x00113D, 0x00113E, 0x00113F,
+ 0x0011EC, 0x001139, 0x001134, 0x00113B, 0x003064, 0x0011ED, 0x0011EE, 0x0011EF,
+ 0x003068, 0x003069, 0x00306A, 0x00306B, 0x00306C, 0x0011E9, 0x0011EA, 0x0011E8,
+ 0x003070, 0x001131, 0x001132, 0x001137, 0x003074, 0x003075, 0x003076, 0x003077,
+ 0x003078, 0x003079, 0x00307A, 0x001135, 0x001136, 0x00307D, 0x00307E, 0x00307F,
+ 0x0011E5, 0x003176, 0x0011E4, 0x0011EB, 0x003105, 0x00311D, 0x003107, 0x003106,
+ 0x003109, 0x003108, 0x00310B, 0x00310A, 0x00310D, 0x00310C, 0x00310F, 0x00310E,
+ 0x003114, 0x003115, 0x003116, 0x003117, 0x003112, 0x003113, 0x003162, 0x003161,
+ 0x003110, 0x003111, 0x00311E, 0x00311F, 0x003119, 0x00311C, 0x00311A, 0x00311B,
+ 0x003121, 0x003120, 0x003123, 0x003122, 0x003125, 0x016A2D, 0x003127, 0x003126,
+ 0x003129, 0x00317D, 0x00312B, 0x0011E6, 0x016A28, 0x00312C, 0x016A2F, 0x0011E7,
+ 0x003131, 0x003118, 0x003133, 0x003132, 0x003135, 0x003134, 0x003137, 0x003136,
+ 0x003139, 0x003138, 0x00313B, 0x00313A, 0x00313D, 0x00313C, 0x00313F, 0x00313E,
+ 0x003141, 0x003140, 0x003143, 0x003142, 0x016A54, 0x0011E2, 0x00317E, 0x003146,
+ 0x003145, 0x016A55, 0x003144, 0x003149, 0x003170, 0x0011E1, 0x00314B, 0x003147,
+ 0x003151, 0x003150, 0x003153, 0x003152, 0x003155, 0x003154, 0x003157, 0x003156,
+ 0x003159, 0x003158, 0x00315B, 0x00315A, 0x00315D, 0x00315C, 0x00315F, 0x00315E,
+ 0x011C52, 0x00312A, 0x00316B, 0x00314D, 0x016A57, 0x011C1B, 0x003173, 0x00314F,
+ 0x00316C, 0x003148, 0x00314A, 0x003124, 0x011C1A, 0x011C51, 0x00314E, 0x003172,
+ 0x003177, 0x016A50, 0x011C13, 0x003163, 0x003171, 0x003174, 0x011C12, 0x00312E,
+ 0x011C57, 0x003128, 0x003178, 0x011C10, 0x011C15, 0x00317F, 0x016A52, 0x011C50,
+ 0x003182, 0x003180, 0x003183, 0x003185, 0x003186, 0x003181, 0x003187, 0x003188,
+ 0x00318C, 0x00318A, 0x00318B, 0x00318E, 0x003184, 0x003189, 0x00318D, 0x0030A4,
+ 0x0030AC, 0x003193, 0x011C40, 0x003192, 0x003195, 0x003194, 0x0030AE, 0x0030AD,
+ 0x0030A8, 0x016A58, 0x0030AA, 0x0030AB, 0x0030AF, 0x0030A9, 0x00316E, 0x00316F,
+ 0x0031B0, 0x0031A0, 0x0031A3, 0x0031A2, 0x0031A5, 0x0031A1, 0x0031A7, 0x0031A6,
+ 0x0031A9, 0x0031A8, 0x0031AB, 0x0031AA, 0x0031A4, 0x0031AE, 0x0031AF, 0x0030A6,
+ 0x0031B5, 0x0031B2, 0x0031B3, 0x0031B4, 0x0031B8, 0x0031B1, 0x0031B7, 0x0031B6,
+ 0x003169, 0x0031BA, 0x0031B9, 0x003168, 0x0031AC, 0x0031AD, 0x00312D, 0x0030A5,
+ 0x0030D0, 0x016A5C, 0x0030D2, 0x0030D1, 0x0030D7, 0x00314C, 0x0030D4, 0x011C18,
+ 0x0030DA, 0x0030D9, 0x011C1F, 0x0030DB, 0x0030DE, 0x016A2E, 0x0030D6, 0x0030D5,
+ 0x003165, 0x0030D3, 0x016A2C, 0x011C1D, 0x011C17, 0x011C11, 0x016A56, 0x016A5A,
+ 0x011C82, 0x011C83, 0x011C73, 0x003164, 0x011C19, 0x0011FD, 0x0011E3, 0x011C80,
+ 0x0030DD, 0x016ADD, 0x003160, 0x003167, 0x0031FC, 0x016AD8, 0x00317C, 0x003175,
+ 0x016ADF, 0x003179, 0x00317A, 0x00317B, 0x0031FD, 0x0030DF, 0x0031FE, 0x0031FF,
+ 0x0031F1, 0x0031F0, 0x0031F3, 0x0031F2, 0x00316A, 0x003166, 0x0031F5, 0x0030D8,
+ 0x0031F4, 0x0031F8, 0x0031FB, 0x0031FA, 0x0031F9, 0x011C81, 0x0031F6, 0x0031F7,
+ 0x016ADC, 0x011C16, 0x011C14, 0x016A68, 0x011C0B, 0x016ADE, 0x011C87, 0x011C1C,
+ 0x011C04, 0x011C06, 0x016A51, 0x016A53, 0x011C05, 0x011C1E, 0x016A42, 0x016A5B,
+ 0x016A41, 0x016A59, 0x016A40, 0x016A43, 0x016B26, 0x016B6F, 0x016B20, 0x011C54,
+ 0x016B27, 0x003285, 0x016A44, 0x0010B5, 0x011C55, 0x011C56, 0x003286, 0x003287,
+ 0x003288, 0x0010B7, 0x003284, 0x011C53, 0x016A45, 0x016B29, 0x016A49, 0x016B2A,
+ 0x016B25, 0x016A47, 0x016B24, 0x0010B6, 0x016A5D, 0x011C03, 0x016B2B, 0x016A5E,
+ 0x0010B0, 0x011C58, 0x016A4B, 0x003289, 0x016A62, 0x016A63, 0x016B23, 0x016B22,
+ 0x016B65, 0x016B2D, 0x016B2E, 0x016B64, 0x016B21, 0x016B28, 0x016B6B, 0x016B2F,
+ 0x016A4A, 0x016B69, 0x016A60, 0x016A61, 0x0032BC, 0x011C07, 0x011C5F, 0x0010BA,
+ 0x0010BB, 0x016A65, 0x016A66, 0x016A67, 0x011C5B, 0x016A69, 0x016B2C, 0x011D02,
+ 0x011D17, 0x016B8C, 0x011D01, 0x011D1C, 0x016B50, 0x016B59, 0x016B56, 0x016B55,
+ 0x011D1E, 0x011D1A, 0x011D1B, 0x016B57, 0x011D19, 0x011D18, 0x011D00, 0x016B08,
+ 0x016B5B, 0x011D13, 0x016B13, 0x016B06, 0x016B54, 0x011D12, 0x016B5D, 0x011D10,
+ 0x011D11, 0x011D14, 0x011D1F, 0x016B05, 0x011D15, 0x011D16, 0x016B52, 0x016B53,
+ 0x016B5E, 0x016B5F, 0x011D03, 0x016B51, 0x011D21, 0x011D22, 0x016B60, 0x011D29,
+ 0x011D2B, 0x016B04, 0x011D20, 0x016B66, 0x016B6A, 0x011D26, 0x011D2D, 0x016B63,
+ 0x011D1D, 0x011D30, 0x016B68, 0x011D24, 0x016B73, 0x016B61, 0x016B12, 0x016B67,
+ 0x016B72, 0x016B71, 0x016B7D, 0x011D52, 0x016B58, 0x011D2A, 0x016B7E, 0x016B7F,
+ 0x016B0E, 0x016B0D, 0x016B0F, 0x011C01, 0x011C00, 0x016B80, 0x016B83, 0x016B82,
+ 0x016B87, 0x016B81, 0x016B89, 0x016B8B, 0x011C0F, 0x016B8D, 0x016B88, 0x016B8A,
+ 0x016B86, 0x001080, 0x016B8F, 0x016B8E, 0x011D53, 0x001011, 0x011C0C, 0x011C0A,
+ 0x016B84, 0x016B85, 0x011C0E, 0x0010A3, 0x011C08, 0x0010EC, 0x0010B4, 0x0010A0,
+ 0x0010A4, 0x0010A2, 0x0032B1, 0x011C26, 0x011C2B, 0x001013, 0x011C25, 0x011D2C,
+ 0x011D28, 0x011C24, 0x011C0D, 0x011D2F, 0x001012, 0x0010BC, 0x011D2E, 0x0010A6,
+ 0x003283, 0x0010C4, 0x001010, 0x0010C3, 0x0010C5, 0x0010C7, 0x0010D3, 0x011C28,
+ 0x011C29, 0x011C2A, 0x0010ED, 0x011C2C, 0x0010CD, 0x003282, 0x001098, 0x001017,
+ 0x001096, 0x001095, 0x001094, 0x011D04, 0x011D05, 0x011D06, 0x001097, 0x011D08,
+ 0x011D09, 0x001099, 0x011D0B, 0x011D0C, 0x011D0D, 0x011D0E, 0x011D0F, 0x0010DC,
+ 0x0010D2, 0x003281, 0x0010E1, 0x0010E3, 0x0010E6, 0x0010E7, 0x0010D1, 0x0010E0,
+ 0x0010E8, 0x0010E9, 0x0010EA, 0x0010EB, 0x0010E5, 0x0010FD, 0x0010E4, 0x0010EF,
+ 0x016B5C, 0x0010F0, 0x011D23, 0x0010F2, 0x0010F5, 0x0010F1, 0x0010F7, 0x0010F4,
+ 0x0010F8, 0x0010EE, 0x0010FA, 0x0010F9, 0x0010FF, 0x0010FE, 0x003280, 0x0010F6,
+ 0x016B6C, 0x016B6D, 0x016B6E, 0x001022, 0x016B70, 0x001020, 0x001026, 0x001027,
+ 0x016B74, 0x016B75, 0x016B76, 0x016B77, 0x00100C, 0x001025, 0x001024, 0x001029,
+ 0x001310, 0x001315, 0x001312, 0x001313, 0x001014, 0x001015, 0x001016, 0x00101D,
+ 0x001018, 0x001019, 0x00101A, 0x00101B, 0x00102A, 0x00101F, 0x00101E, 0x011D50,
+ 0x011D51, 0x001163, 0x001162, 0x00117D, 0x001167, 0x001161, 0x011D57, 0x00117E,
+ 0x001178, 0x001160, 0x001179, 0x00117A, 0x001168, 0x00117F, 0x001166, 0x00116A,
+ 0x00116C, 0x001021, 0x00116E, 0x001023, 0x001174, 0x001165, 0x001164, 0x00116D,
+ 0x00117B, 0x001170, 0x001169, 0x00116B, 0x00117C, 0x001175, 0x001176, 0x00116F,
+ 0x001040, 0x001041, 0x001042, 0x001043, 0x001047, 0x00114D, 0x00114E, 0x00114F,
+ 0x001049, 0x001044, 0x00114A, 0x001302, 0x001045, 0x001148, 0x00114C, 0x001046,
+ 0x001318, 0x001304, 0x001303, 0x001334, 0x001314, 0x00131C, 0x001306, 0x001301,
+ 0x001048, 0x001319, 0x00131A, 0x00131B, 0x00105C, 0x00131D, 0x00131E, 0x00131F,
+ 0x001172, 0x001061, 0x00133C, 0x001332, 0x001065, 0x001333, 0x001177, 0x001066,
+ 0x001331, 0x00130C, 0x001352, 0x001353, 0x001330, 0x001351, 0x00106E, 0x001337,
+ 0x001070, 0x001171, 0x001300, 0x001173, 0x001324, 0x001075, 0x001076, 0x001077,
+ 0x00107C, 0x001079, 0x00107A, 0x00107B, 0x001078, 0x00107D, 0x00107E, 0x00107F,
+ 0x001380, 0x001381, 0x001382, 0x001383, 0x001384, 0x001385, 0x001386, 0x001387,
+ 0x001388, 0x001389, 0x00138A, 0x00138B, 0x0013E9, 0x00138D, 0x00138E, 0x00138F,
+ 0x001308, 0x001309, 0x00130E, 0x00130D, 0x00130F, 0x001305, 0x001336, 0x001307,
+ 0x0013E8, 0x0013ED, 0x00130A, 0x00130B, 0x0013EC, 0x0013AD, 0x0013EE, 0x0013EF,
+ 0x0013A0, 0x0010A1, 0x0013A2, 0x0013A3, 0x0013A1, 0x0010A5, 0x0013A4, 0x0010A7,
+ 0x0010A8, 0x0010A9, 0x0010AA, 0x0010AB, 0x0010AC, 0x0010AD, 0x0010AE, 0x0010AF,
+ 0x0013A8, 0x0013A9, 0x0013AE, 0x0013AF, 0x0013AC, 0x0013A5, 0x0013A6, 0x0013A7,
+ 0x0010B8, 0x0010B9, 0x0013AA, 0x0013AB, 0x0013BC, 0x0010BD, 0x0010BE, 0x0010BF,
+ 0x0013C1, 0x0013C2, 0x0013C3, 0x0013D6, 0x0013C5, 0x0013D5, 0x0013C7, 0x0013D7,
+ 0x0013D8, 0x0013D9, 0x0013C0, 0x0013DB, 0x0013C6, 0x0013DD, 0x0013DA, 0x0013DF,
+ 0x0010D0, 0x0013D4, 0x0013D3, 0x0013DC, 0x0010D4, 0x0010D5, 0x0010D6, 0x0010D7,
+ 0x0013D2, 0x0010D9, 0x0010DA, 0x0010DB, 0x0013D1, 0x0010DD, 0x0010DE, 0x0013D0,
+ 0x0013E0, 0x0013E1, 0x0013E2, 0x0013E3, 0x0013C4, 0x0013E5, 0x0013E6, 0x0013E7,
+ 0x0013C8, 0x0013C9, 0x0013CA, 0x0013CB, 0x0013CC, 0x0013CD, 0x0013CE, 0x0013CF,
+ 0x0013F0, 0x0013F1, 0x0013F2, 0x0013F3, 0x0013F4, 0x0013F5, 0x0013E4, 0x0013EA,
+ 0x0013F8, 0x0013F9, 0x0013FA, 0x0013FB, 0x0013FC, 0x0013FD, 0x0013DE, 0x0013EB,
+ 0x02F848, 0x02F849, 0x02F84A, 0x02F84B, 0x02F844, 0x02F845, 0x02F846, 0x02F847,
+ 0x02F840, 0x02F841, 0x02F842, 0x02F843, 0x02F85C, 0x02F85D, 0x02F85E, 0x02F82F,
+ 0x02F828, 0x02F829, 0x02F82A, 0x02F82B, 0x02F824, 0x02F825, 0x02F826, 0x02F827,
+ 0x02F820, 0x02F821, 0x02F822, 0x02F823, 0x02F83C, 0x02F83D, 0x02F83E, 0x02F83F,
+ 0x001524, 0x001520, 0x02F838, 0x001523, 0x02F839, 0x001521, 0x001522, 0x02F83A,
+ 0x00152B, 0x02F83B, 0x02F834, 0x02F835, 0x00152C, 0x001525, 0x001526, 0x001527,
+ 0x02F836, 0x001529, 0x02F837, 0x02F830, 0x001534, 0x00153D, 0x02F831, 0x00152D,
+ 0x001538, 0x00153B, 0x00153A, 0x00152A, 0x00153C, 0x001539, 0x00153E, 0x00153F,
+ 0x02F832, 0x02F833, 0x02F80C, 0x02F80D, 0x02F80E, 0x02F80F, 0x02F808, 0x02F809,
+ 0x02F80A, 0x02F80B, 0x02F804, 0x02F805, 0x02F806, 0x02F807, 0x02F800, 0x02F801,
+ 0x001553, 0x02F802, 0x001554, 0x02F803, 0x001556, 0x001551, 0x001552, 0x02F81C,
+ 0x001550, 0x02F81D, 0x00155A, 0x00155B, 0x001558, 0x001555, 0x02F81E, 0x001557,
+ 0x02F81F, 0x001260, 0x02F818, 0x02F819, 0x02F81A, 0x001267, 0x02F81B, 0x02F814,
+ 0x001268, 0x02F815, 0x02F816, 0x02F817, 0x00126C, 0x02F810, 0x00126E, 0x00126F,
+ 0x00155D, 0x001559, 0x02F811, 0x02F812, 0x02F813, 0x02F8EC, 0x00155E, 0x00155F,
+ 0x02F8ED, 0x02F8EE, 0x02F8EF, 0x02F8E8, 0x02F8E9, 0x02F8EA, 0x02F8EB, 0x02F8E4,
+ 0x02F8E5, 0x02F8E6, 0x02F8E7, 0x02F8E0, 0x001284, 0x02F8E1, 0x02F8E2, 0x02F8E3,
+ 0x001288, 0x02F8FC, 0x00128A, 0x00128B, 0x02F8FD, 0x02F8FE, 0x02F8FF, 0x02F8F8,
+ 0x02F8F9, 0x02F8FA, 0x02F8FB, 0x02F8F4, 0x02F8F5, 0x02F8F6, 0x02F8F7, 0x02F8F0,
+ 0x001298, 0x001299, 0x02F8F1, 0x01230E, 0x01230F, 0x00129D, 0x00129E, 0x00129F,
+ 0x012308, 0x012309, 0x01230A, 0x01230B, 0x012304, 0x012305, 0x012306, 0x012307,
+ 0x012300, 0x012301, 0x012302, 0x012303, 0x01231C, 0x01231D, 0x01231E, 0x01231F,
+ 0x012318, 0x012319, 0x01231A, 0x01231B, 0x012314, 0x012315, 0x012316, 0x012317,
+ 0x012310, 0x012311, 0x012312, 0x012313, 0x01238C, 0x01238D, 0x01238E, 0x01238F,
+ 0x012388, 0x012389, 0x01238A, 0x01238B, 0x012384, 0x012385, 0x012386, 0x012387,
+ 0x012380, 0x012381, 0x012382, 0x012383, 0x012398, 0x012399, 0x012394, 0x012395,
+ 0x012396, 0x012397, 0x012390, 0x012391, 0x012392, 0x012393, 0x01206C, 0x01206D,
+ 0x01206E, 0x01BC01, 0x01BC00, 0x01BC03, 0x01BC02, 0x01BC05, 0x01BC04, 0x01BC07,
+ 0x01BC06, 0x01BC09, 0x01BC08, 0x01BC0B, 0x01BC0A, 0x01BC0D, 0x01BC0C, 0x01BC0F,
+ 0x01BC0E, 0x01BC11, 0x01BC10, 0x01BC13, 0x01BC12, 0x01BC15, 0x01BC14, 0x01BC17,
+ 0x01BC16, 0x01BC19, 0x01BC18, 0x01BC1B, 0x01BC1A, 0x01BC1D, 0x01BC1C, 0x01BC1F,
+ 0x01BC1E, 0x01BC21, 0x01BC20, 0x01BC23, 0x01BC22, 0x01206F, 0x012068, 0x01BC27,
+ 0x01BC26, 0x001581, 0x001582, 0x001583, 0x001599, 0x00159C, 0x001587, 0x00159B,
+ 0x00159A, 0x01BC31, 0x01BC30, 0x01BC33, 0x01BC32, 0x01BC35, 0x01BC34, 0x01BC37,
+ 0x01BC36, 0x01BC39, 0x01BC38, 0x01BC3B, 0x01BC3A, 0x01BC3D, 0x01BC3C, 0x01BC3F,
+ 0x01BC3E, 0x001590, 0x001593, 0x001592, 0x001595, 0x001594, 0x001597, 0x001596,
+ 0x001580, 0x001585, 0x001586, 0x01BC52, 0x01BC53, 0x01BC50, 0x01BC51, 0x01BC57,
+ 0x00158A, 0x001589, 0x01BC69, 0x00158B, 0x01BC68, 0x0015A1, 0x00159D, 0x0015AC,
+ 0x001533, 0x0015B1, 0x00159E, 0x00159F, 0x001536, 0x001531, 0x001532, 0x001530,
+ 0x00150C, 0x01BC64, 0x001537, 0x01BC6A, 0x001598, 0x01BC24, 0x01BC25, 0x00150D,
+ 0x01BC65, 0x01BC28, 0x01BC29, 0x01BC2A, 0x01BC2B, 0x01BC2C, 0x01BC2D, 0x01BC2E,
+ 0x01BC2F, 0x0015D1, 0x0015D2, 0x0015D3, 0x001535, 0x0015D5, 0x0015D6, 0x012228,
+ 0x01222C, 0x0120E0, 0x01225B, 0x0120EE, 0x0120ED, 0x0120EF, 0x0120EC, 0x0120E8,
+ 0x0120E9, 0x01BC81, 0x0120E6, 0x01BC62, 0x01BC63, 0x01BC85, 0x01BC84, 0x01BC83,
+ 0x012013, 0x01BC61, 0x01BC88, 0x01BC60, 0x012254, 0x012012, 0x01BC66, 0x012010,
+ 0x01BC67, 0x01BC92, 0x01BC90, 0x01BC93, 0x01BC91, 0x01BC96, 0x01BC78, 0x01BC97,
+ 0x0120FC, 0x01BC7A, 0x0120E3, 0x01BC98, 0x01BC99, 0x0120FD, 0x01BC95, 0x01BC94,
+ 0x01BC82, 0x01BC80, 0x0120E1, 0x01BC7C, 0x012016, 0x01BC74, 0x012017, 0x01BC86,
+ 0x01BC87, 0x0120E2, 0x01BC79, 0x0120EA, 0x01BC76, 0x01BC77, 0x0120E7, 0x0120F8,
+ 0x0120F9, 0x01BC70, 0x01BC7B, 0x01BC72, 0x01BC73, 0x0120FE, 0x01BC75, 0x0120C0,
+ 0x0120C1, 0x0120C2, 0x0120C3, 0x0120C4, 0x0120C5, 0x0120C6, 0x0120C7, 0x0120C8,
+ 0x0120C9, 0x0120CA, 0x0120CB, 0x01BC42, 0x01BC43, 0x01BC44, 0x01BC45, 0x01BC4E,
+ 0x01BC4F, 0x01BC4C, 0x01BC49, 0x012253, 0x01BC48, 0x01BC4A, 0x01BC4D, 0x01BC4B,
+ 0x0120CF, 0x012252, 0x012251, 0x0120DC, 0x012250, 0x01BC54, 0x01BC55, 0x01BC56,
+ 0x01BC41, 0x01BC58, 0x01BC59, 0x01BC5A, 0x01BC5B, 0x01BC5C, 0x01BC5D, 0x01BC5E,
+ 0x01BC5F, 0x01BC40, 0x01BC71, 0x0120CC, 0x0120CD, 0x0120CE, 0x0120FF, 0x01BC46,
+ 0x01BC47, 0x0120F2, 0x0120F3, 0x0120F1, 0x0120F6, 0x0120F0, 0x0120F7, 0x012256,
+ 0x012255, 0x012257, 0x0120FB, 0x0120F4, 0x0120F5, 0x0120FA, 0x0122ED, 0x012081,
+ 0x012080, 0x012083, 0x012082, 0x012085, 0x012084, 0x012087, 0x012086, 0x012089,
+ 0x012088, 0x01208B, 0x01208A, 0x01208D, 0x01208C, 0x01208F, 0x01208E, 0x0120D0,
+ 0x0120D1, 0x0120D2, 0x0120D3, 0x0120D4, 0x0120D5, 0x0120D6, 0x0120D7, 0x012099,
+ 0x012098, 0x0120DA, 0x0120DB, 0x01209D, 0x01209C, 0x01209F, 0x01209E, 0x0120A1,
+ 0x0120A0, 0x0120A3, 0x0120A2, 0x0120A5, 0x0120A4, 0x0120A7, 0x0120A6, 0x0120A9,
+ 0x0120A8, 0x0120AB, 0x0120AA, 0x0120AD, 0x0120AC, 0x0120AF, 0x0120AE, 0x0120B1,
+ 0x0120B0, 0x0120B3, 0x0120B2, 0x0120B5, 0x0120B4, 0x0120B7, 0x0120B6, 0x0120B9,
+ 0x0120B8, 0x0120BB, 0x0120BA, 0x0120BD, 0x0120BC, 0x0120BF, 0x0120BE, 0x0120D8,
+ 0x0120D9, 0x0120DE, 0x0120DF, 0x0120DD, 0x016F01, 0x016F00, 0x016F03, 0x016F02,
+ 0x016F05, 0x016F04, 0x016F07, 0x016F06, 0x016F09, 0x016F08, 0x016F0B, 0x016F0A,
+ 0x016F0D, 0x016F0C, 0x016F0F, 0x016F0E, 0x016F11, 0x016F10, 0x016F13, 0x016F12,
+ 0x016F15, 0x016F14, 0x016F17, 0x016F16, 0x016F19, 0x016F18, 0x016F1B, 0x016F1A,
+ 0x016F1D, 0x016F1C, 0x016F1F, 0x016F1E, 0x016F21, 0x016F20, 0x016F23, 0x016F22,
+ 0x016F25, 0x016F24, 0x016F27, 0x016F26, 0x016F29, 0x016F28, 0x016F2B, 0x016F2A,
+ 0x016F2D, 0x016F2C, 0x016F2F, 0x016F2E, 0x016F31, 0x016F30, 0x016F33, 0x016F32,
+ 0x016F35, 0x016F34, 0x016F37, 0x016F36, 0x016F39, 0x016F38, 0x016F3B, 0x016F3A,
+ 0x016F3D, 0x016F3C, 0x016F3F, 0x012106, 0x012107, 0x016F43, 0x016F40, 0x012102,
+ 0x01210B, 0x016F44, 0x012103, 0x012109, 0x012105, 0x01210F, 0x016F42, 0x012111,
+ 0x012110, 0x012113, 0x012112, 0x001369, 0x012108, 0x012117, 0x016F50, 0x012119,
+ 0x01211B, 0x012118, 0x012104, 0x01211D, 0x01211F, 0x01211C, 0x01211E, 0x00136A,
+ 0x001282, 0x001281, 0x016F41, 0x001283, 0x001286, 0x001285, 0x001280, 0x001287,
+ 0x00136C, 0x00136D, 0x00129C, 0x01210C, 0x01210D, 0x01210E, 0x00136E, 0x00136F,
+ 0x001212, 0x012133, 0x012132, 0x001213, 0x001211, 0x00121C, 0x012136, 0x001217,
+ 0x001219, 0x001218, 0x00121B, 0x00121A, 0x001216, 0x001215, 0x001214, 0x012240,
+ 0x012241, 0x012243, 0x016F3E, 0x012244, 0x012245, 0x012242, 0x012247, 0x012248,
+ 0x012249, 0x01224A, 0x01224B, 0x01224C, 0x01224D, 0x012246, 0x01224F, 0x001210,
+ 0x001200, 0x001204, 0x001207, 0x001203, 0x00121D, 0x00121E, 0x00121F, 0x012258,
+ 0x012259, 0x01225A, 0x01224E, 0x01225C, 0x01225D, 0x01225E, 0x01225F, 0x012260,
+ 0x012261, 0x012262, 0x012263, 0x012264, 0x012265, 0x012266, 0x012267, 0x012268,
+ 0x012269, 0x01226A, 0x01226B, 0x01226C, 0x01226D, 0x01226E, 0x01226F, 0x012270,
+ 0x012271, 0x012272, 0x012273, 0x012274, 0x012275, 0x012276, 0x012277, 0x012278,
+ 0x012279, 0x01227A, 0x01227B, 0x01227C, 0x01227D, 0x01227E, 0x01227F, 0x001229,
+ 0x001254, 0x001244, 0x001248, 0x001264, 0x001293, 0x001205, 0x001206, 0x001256,
+ 0x001228, 0x00125A, 0x00120B, 0x00125B, 0x001258, 0x00127D, 0x00122E, 0x00124B,
+ 0x0012E0, 0x0012E1, 0x0012E6, 0x0012E7, 0x0012E4, 0x001221, 0x001222, 0x001223,
+ 0x001220, 0x001226, 0x0012EA, 0x0012EB, 0x0012EC, 0x001227, 0x0012E9, 0x0012E5,
+ 0x0121E1, 0x00122B, 0x0012F5, 0x001232, 0x0012F4, 0x001224, 0x00122A, 0x00122F,
+ 0x0012F9, 0x0012F8, 0x0012EE, 0x00123A, 0x0012ED, 0x0012EF, 0x0012FF, 0x0012FE,
+ 0x001320, 0x001291, 0x001296, 0x001295, 0x00132C, 0x001297, 0x001322, 0x001323,
+ 0x001321, 0x001328, 0x001325, 0x001327, 0x00133D, 0x00133E, 0x00133F, 0x0121C1,
+ 0x0121C0, 0x0121C3, 0x0121C2, 0x0121C5, 0x0121C4, 0x0121C7, 0x0121C6, 0x0121C9,
+ 0x0121C8, 0x0121CB, 0x0121CA, 0x0121CD, 0x0121CC, 0x0121CF, 0x0121CE, 0x001338,
+ 0x001339, 0x00133A, 0x00133B, 0x0121D5, 0x0121D4, 0x001335, 0x0121D6, 0x0121D9,
+ 0x0121D8, 0x0121DB, 0x0121DA, 0x0121DD, 0x0121DC, 0x0121DF, 0x0121DE, 0x00D7BE,
+ 0x0121E0, 0x0121E3, 0x0121E2, 0x0121E5, 0x0121E4, 0x0121E7, 0x0121E6, 0x0121E9,
+ 0x0121E8, 0x0121EB, 0x0121EA, 0x0121ED, 0x0121EC, 0x0121EF, 0x0121EE, 0x0121F1,
+ 0x0121F0, 0x0121F3, 0x0121F2, 0x0121F5, 0x0121F4, 0x0121F7, 0x0121F6, 0x0121F9,
+ 0x0121F8, 0x0121FB, 0x0121FA, 0x0121FD, 0x0121FC, 0x0121FF, 0x0121FE, 0x012201,
+ 0x012200, 0x001350, 0x001356, 0x012205, 0x012204, 0x012202, 0x012203, 0x012209,
+ 0x012208, 0x01220B, 0x01220A, 0x001354, 0x001357, 0x012206, 0x012207, 0x012211,
+ 0x012210, 0x012213, 0x012212, 0x012215, 0x012214, 0x012217, 0x012216, 0x012219,
+ 0x012218, 0x01221B, 0x01221A, 0x01221D, 0x01221C, 0x01221F, 0x01221E, 0x001326,
+ 0x00129B, 0x012232, 0x00135A, 0x001359, 0x001294, 0x001355, 0x012231, 0x00129A,
+ 0x001358, 0x001329, 0x00132A, 0x00132B, 0x00132E, 0x00132D, 0x01220F, 0x00132F,
+ 0x001379, 0x001371, 0x001378, 0x00137B, 0x001290, 0x001375, 0x001292, 0x001377,
+ 0x012233, 0x00134C, 0x00D7B8, 0x00D7B9, 0x00D7BA, 0x01220E, 0x00D7BC, 0x012220,
+ 0x012221, 0x00D7BF, 0x00D7BB, 0x012224, 0x012225, 0x012222, 0x012223, 0x012238,
+ 0x012229, 0x01222A, 0x01222B, 0x00D7B6, 0x00D7B7, 0x012226, 0x012227, 0x012230,
+ 0x012234, 0x01222E, 0x01222F, 0x00D7B4, 0x012235, 0x012236, 0x012237, 0x012239,
+ 0x00D7B5, 0x01223A, 0x01223B, 0x01223C, 0x01223D, 0x01223E, 0x01223F, 0x00134E,
+ 0x00D7D1, 0x00D7D3, 0x001373, 0x001372, 0x00D7D2, 0x001374, 0x001376, 0x00137C,
+ 0x01222D, 0x001370, 0x00136B, 0x01220C, 0x01220D, 0x00134D, 0x00137A, 0x00134F,
+ 0x001340, 0x001341, 0x001342, 0x001343, 0x001344, 0x001345, 0x001346, 0x001347,
+ 0x001348, 0x00134B, 0x00134A, 0x00D7D7, 0x001349, 0x00D7D0, 0x00D7BD, 0x012281,
+ 0x012280, 0x0122A8, 0x0122CE, 0x012285, 0x012284, 0x012282, 0x012283, 0x012289,
+ 0x012288, 0x01228B, 0x01228A, 0x01228D, 0x01228C, 0x012286, 0x012287, 0x012291,
+ 0x012290, 0x012293, 0x012292, 0x012295, 0x012294, 0x012297, 0x012296, 0x012299,
+ 0x012298, 0x01229B, 0x01229A, 0x01229D, 0x01229C, 0x01229F, 0x01229E, 0x0122A1,
+ 0x0122A0, 0x0122A3, 0x0122A2, 0x0122A5, 0x0122A4, 0x0122A7, 0x0122A6, 0x0122A9,
+ 0x0122B9, 0x0122AB, 0x0122AA, 0x0122AD, 0x0122AC, 0x0122AF, 0x0122AE, 0x0122B1,
+ 0x0122B0, 0x0122B3, 0x0122B2, 0x0122B5, 0x0122B4, 0x0122B7, 0x0122B6, 0x01228F,
+ 0x0122B8, 0x0122BB, 0x0122BA, 0x0122BD, 0x0122BC, 0x0122BF, 0x0122BE, 0x0122C1,
+ 0x0122C0, 0x0122C3, 0x0122C2, 0x0122C5, 0x0122C4, 0x0122E8, 0x0122C6, 0x0122C9,
+ 0x0122D9, 0x0122CB, 0x0122CA, 0x0122CD, 0x0122CC, 0x0122CF, 0x0122C7, 0x0122D1,
+ 0x01228E, 0x0122D3, 0x0122D2, 0x0122D5, 0x0122D4, 0x0122D7, 0x0122D6, 0x0122D0,
+ 0x0122D8, 0x0122DB, 0x0122DA, 0x0122DD, 0x0122DC, 0x0122DF, 0x0122DE, 0x0122E2,
+ 0x0122E0, 0x0122E3, 0x0122FD, 0x0122E6, 0x0122E4, 0x0122E7, 0x0122E1, 0x0122EA,
+ 0x0122F9, 0x0122EB, 0x0122E5, 0x0122EF, 0x0122EC, 0x0122FE, 0x0122E9, 0x0122F1,
+ 0x0122F0, 0x0122F3, 0x0122F2, 0x0122F5, 0x0122F4, 0x0122F7, 0x0122F6, 0x0122C8,
+ 0x0122F8, 0x0122FB, 0x0122FA, 0x0122FF, 0x0122FC, 0x02F861, 0x02F860, 0x02F863,
+ 0x01230C, 0x012324, 0x01234F, 0x02F867, 0x02F866, 0x02F869, 0x02F868, 0x01230D,
+ 0x02F86A, 0x02F86D, 0x02F86C, 0x02F86F, 0x02F86E, 0x02F871, 0x02F870, 0x02F82E,
+ 0x02F82D, 0x02F875, 0x02F874, 0x02F877, 0x02F876, 0x02F879, 0x02F878, 0x02F87B,
+ 0x02F87A, 0x02F87D, 0x02F87C, 0x02F87F, 0x02F87E, 0x02F890, 0x02F897, 0x01232C,
+ 0x012320, 0x012323, 0x012322, 0x012325, 0x012321, 0x012327, 0x012326, 0x012338,
+ 0x012328, 0x01232B, 0x01232A, 0x01232D, 0x012329, 0x01232F, 0x01232E, 0x012334,
+ 0x012330, 0x012333, 0x012332, 0x012335, 0x012331, 0x012337, 0x012336, 0x01233C,
+ 0x02F891, 0x01233B, 0x01233A, 0x01233D, 0x012339, 0x01233F, 0x01233E, 0x012341,
+ 0x012340, 0x012343, 0x012342, 0x012345, 0x012344, 0x012347, 0x012346, 0x012349,
+ 0x012359, 0x01234B, 0x01234A, 0x01234D, 0x01234C, 0x012364, 0x01234E, 0x012351,
+ 0x012350, 0x012353, 0x012352, 0x012355, 0x012354, 0x012357, 0x012356, 0x0122EE,
+ 0x012358, 0x01235B, 0x01235A, 0x01235D, 0x01235C, 0x01235F, 0x01235E, 0x012361,
+ 0x012360, 0x012363, 0x012362, 0x012365, 0x012375, 0x012367, 0x012366, 0x012369,
+ 0x012368, 0x01236B, 0x01236A, 0x01236D, 0x01236C, 0x01236F, 0x01236E, 0x012371,
+ 0x012370, 0x012373, 0x012372, 0x012348, 0x012374, 0x012377, 0x012376, 0x012379,
+ 0x012378, 0x01237B, 0x01237A, 0x01237D, 0x01237C, 0x01237F, 0x01237E, 0x02F882,
+ 0x02F883, 0x02F880, 0x02F881, 0x02F886, 0x02F887, 0x02F888, 0x02F889, 0x02F88A,
+ 0x02F88B, 0x02F884, 0x02F885, 0x02F89E, 0x02F88F, 0x02F88C, 0x02F88D, 0x02F892,
+ 0x02F893, 0x02F894, 0x02F895, 0x02F896, 0x02F8B3, 0x02F898, 0x02F899, 0x02F94C,
+ 0x02F89B, 0x02F89C, 0x02F89D, 0x02F89F, 0x02F89A, 0x02F901, 0x02F900, 0x02F903,
+ 0x02F902, 0x02F905, 0x02F904, 0x02F907, 0x02F906, 0x02F909, 0x02F908, 0x02F90B,
+ 0x02F90A, 0x02F90D, 0x02F90C, 0x02F90F, 0x02F91F, 0x02F911, 0x02F910, 0x02F913,
+ 0x02F912, 0x02F915, 0x02F914, 0x02F917, 0x02F916, 0x02F919, 0x02F918, 0x02F91B,
+ 0x02F91A, 0x02F91D, 0x02F91C, 0x02F92E, 0x02F91E, 0x02F921, 0x02F920, 0x02F923,
+ 0x02F922, 0x02F90E, 0x02F924, 0x02F927, 0x02F926, 0x02F929, 0x02F928, 0x02F92B,
+ 0x02F92A, 0x02F92D, 0x02F925, 0x02F92F, 0x02F93F, 0x02F931, 0x02F930, 0x02F933,
+ 0x02F932, 0x02F935, 0x02F934, 0x02F937, 0x02F82C, 0x02F939, 0x02F938, 0x02F93B,
+ 0x02F93A, 0x02F93D, 0x02F93C, 0x02F936, 0x02F93E, 0x02F941, 0x02F947, 0x02F940,
+ 0x02F942, 0x02F945, 0x02F94B, 0x02F944, 0x02F946, 0x02F949, 0x02F94F, 0x02F948,
+ 0x02F94A, 0x02F95C, 0x02F96D, 0x02F94D, 0x02F95F, 0x02F951, 0x02F950, 0x02F953,
+ 0x02F952, 0x02F955, 0x02F954, 0x02F957, 0x02F956, 0x02F959, 0x02F958, 0x02F95B,
+ 0x02F95A, 0x02F96C, 0x02F943, 0x02F95D, 0x02F95E, 0x02F94E, 0x02F92C, 0x02F963,
+ 0x02F962, 0x02F960, 0x02F961, 0x02F967, 0x02F966, 0x02F969, 0x02F968, 0x02F96B,
+ 0x02F96A, 0x02F964, 0x02F965, 0x02F96F, 0x02F96E, 0x02F971, 0x02F970, 0x02F853,
+ 0x02F972, 0x02F975, 0x02F974, 0x02F977, 0x02F976, 0x02F979, 0x02F978, 0x02F97B,
+ 0x02F97A, 0x02F97D, 0x02F97C, 0x02F97F, 0x02F97E, 0x02F981, 0x02F980, 0x02F983,
+ 0x02F987, 0x02F985, 0x02F984, 0x02F982, 0x02F986, 0x02F989, 0x02F988, 0x02F98B,
+ 0x02F98F, 0x02F98D, 0x02F98C, 0x02F99E, 0x02F98E, 0x02F991, 0x02F990, 0x02F9AE,
+ 0x02F997, 0x02F995, 0x02F994, 0x02F993, 0x02F996, 0x02F999, 0x02F998, 0x02F99B,
+ 0x02F99F, 0x02F99D, 0x02F99C, 0x02F99A, 0x02F992, 0x02F9A1, 0x02F9A0, 0x02F9A3,
+ 0x02F9A2, 0x02F9A5, 0x02F9A4, 0x02F9A7, 0x02F9A6, 0x02F9A9, 0x02F9A8, 0x02F9AB,
+ 0x02F9AA, 0x02F98A, 0x02F9AC, 0x02F9AF, 0x02F9BF, 0x02F9B1, 0x02F9B0, 0x02F9B3,
+ 0x02F9EC, 0x02F9B5, 0x02F9B4, 0x02F9B7, 0x02F9B6, 0x02F9B9, 0x02F9B8, 0x02F9BB,
+ 0x02F9BA, 0x02F9BD, 0x02F9BC, 0x02F9B2, 0x02F9BE, 0x02F9C1, 0x02F9C0, 0x02F9C3,
+ 0x02F9C2, 0x02F9C5, 0x02F9C4, 0x02F9C7, 0x02F9C6, 0x02F9C9, 0x02F9C8, 0x02F9CB,
+ 0x02F9DB, 0x02F9CD, 0x02F9CC, 0x02F9CF, 0x02F9CE, 0x02F9D1, 0x02F9D0, 0x02F9D3,
+ 0x02F9D2, 0x02F9D5, 0x02F9D4, 0x02F9D7, 0x02F9D6, 0x02F9D9, 0x02F9D8, 0x02F9ED,
+ 0x02F9DA, 0x02F9DD, 0x02F9DC, 0x02F9DF, 0x02F9DE, 0x02F9CA, 0x02F9AD, 0x02F9E3,
+ 0x02F9E2, 0x02F9E0, 0x02F9E1, 0x02F9E7, 0x02F9E6, 0x02F9E9, 0x02F9E8, 0x02F9EB,
+ 0x02F9EA, 0x02F9E4, 0x02F9E5, 0x02F9EF, 0x02F9EE, 0x02F9F1, 0x02F9F0, 0x02F9F3,
+ 0x02F9F2, 0x02F9F5, 0x02F9F4, 0x02F9F7, 0x02F9F6, 0x02F9F9, 0x02F9F8, 0x02F9FB,
+ 0x02F9FA, 0x02F9FD, 0x02F9FC, 0x02F9FF, 0x02F9FE, 0x012069, 0x01206A, 0x01206B,
+ 0x012064, 0x012065, 0x012066, 0x012067, 0x012060, 0x012061, 0x012062, 0x012063,
+ 0x01207C, 0x01207D, 0x01207E, 0x01207F, 0x012078, 0x012079, 0x01207A, 0x01207B,
+ 0x012074, 0x012075, 0x012076, 0x012077, 0x012070, 0x012071, 0x012072, 0x012073,
+ 0x01204C, 0x01204D, 0x01204E, 0x01204F, 0x012048, 0x012049, 0x01204A, 0x01204B,
+ 0x012044, 0x012045, 0x012046, 0x012047, 0x012040, 0x012041, 0x012042, 0x012043,
+ 0x01205C, 0x01205D, 0x01205E, 0x00D7B0, 0x01205F, 0x012058, 0x012059, 0x01205A,
+ 0x01205B, 0x012054, 0x012055, 0x012056, 0x012057, 0x012050, 0x012051, 0x012052,
+ 0x012053, 0x01202C, 0x01202D, 0x01202E, 0x01202F, 0x012028, 0x012029, 0x01202A,
+ 0x01202B, 0x012024, 0x012025, 0x012026, 0x00D7B1, 0x012027, 0x012020, 0x012021,
+ 0x012022, 0x012023, 0x01203C, 0x01203D, 0x01203E, 0x01203F, 0x012038, 0x012039,
+ 0x01203A, 0x01203B, 0x012034, 0x012035, 0x012036, 0x012037, 0x012030, 0x012031,
+ 0x012032, 0x012033, 0x01200C, 0x01200D, 0x01200E, 0x02F862, 0x02F864, 0x012501,
+ 0x012500, 0x012503, 0x012502, 0x02F865, 0x012504, 0x012525, 0x02F86B, 0x012509,
+ 0x012508, 0x01250B, 0x01250A, 0x01250D, 0x01250C, 0x01250F, 0x01250E, 0x012511,
+ 0x012510, 0x012513, 0x012512, 0x012515, 0x012514, 0x012517, 0x012516, 0x012519,
+ 0x012518, 0x01251B, 0x01251A, 0x01251D, 0x012524, 0x01251F, 0x01251E, 0x012521,
+ 0x012520, 0x012523, 0x012522, 0x01253C, 0x012535, 0x012527, 0x01200F, 0x01252B,
+ 0x012526, 0x012008, 0x012529, 0x012009, 0x01200A, 0x01252A, 0x01200B, 0x012531,
+ 0x012530, 0x012533, 0x012532, 0x012537, 0x02F8BB, 0x02F8B5, 0x012536, 0x02F8B4,
+ 0x012538, 0x012004, 0x012005, 0x01253D, 0x02F8B2, 0x01253F, 0x01253E, 0x012006,
+ 0x012007, 0x012000, 0x012001, 0x02F88E, 0x012002, 0x012003, 0x01201C, 0x01201D,
+ 0x01201E, 0x01201F, 0x012018, 0x012019, 0x01201A, 0x01201B, 0x012014, 0x012015,
+ 0x012011, 0x0120EB, 0x0120E4, 0x02F8B1, 0x0120E5, 0x02F8B0, 0x01209A, 0x01209B,
+ 0x02F8B6, 0x012094, 0x02F8B7, 0x012095, 0x012096, 0x012097, 0x012090, 0x012091,
+ 0x012092, 0x012093, 0x01216C, 0x01216D, 0x01216E, 0x01216F, 0x012168, 0x012169,
+ 0x01216A, 0x01216B, 0x012164, 0x012165, 0x012166, 0x012167, 0x012160, 0x012161,
+ 0x012162, 0x012163, 0x01217C, 0x01217D, 0x01217E, 0x01217F, 0x012178, 0x012179,
+ 0x01217A, 0x01217B, 0x012174, 0x012175, 0x012176, 0x012177, 0x02F8B9, 0x012170,
+ 0x012171, 0x012172, 0x012173, 0x01214C, 0x01214D, 0x01214E, 0x01214F, 0x012148,
+ 0x012149, 0x01214A, 0x01214B, 0x012144, 0x012145, 0x012146, 0x012147, 0x012140,
+ 0x012141, 0x012142, 0x012143, 0x01215C, 0x01215D, 0x01215E, 0x01215F, 0x012158,
+ 0x02F8BA, 0x012159, 0x01215A, 0x01215B, 0x012154, 0x012155, 0x012156, 0x012157,
+ 0x012150, 0x012151, 0x012152, 0x012153, 0x01212C, 0x01212D, 0x01212E, 0x01212F,
+ 0x012128, 0x012129, 0x01212A, 0x01212B, 0x012124, 0x012125, 0x012126, 0x012127,
+ 0x012120, 0x012121, 0x012122, 0x012123, 0x01213C, 0x01213D, 0x01213E, 0x01213F,
+ 0x012138, 0x012139, 0x01213A, 0x01213B, 0x012134, 0x012135, 0x012137, 0x012130,
+ 0x012131, 0x01210A, 0x012100, 0x012101, 0x01211A, 0x012114, 0x012115, 0x012116,
+ 0x0121D7, 0x0121D0, 0x0121D1, 0x0121D2, 0x0121D3, 0x0121AC, 0x0121AD, 0x0121AE,
+ 0x0121AF, 0x0121A8, 0x0121A9, 0x0121AA, 0x0121AB, 0x0121A4, 0x0121A5, 0x0121A6,
+ 0x0121A7, 0x0121A0, 0x0121A1, 0x0121A2, 0x0121A3, 0x0121BC, 0x0121BD, 0x0121BE,
+ 0x0121BF, 0x0121B8, 0x0121B9, 0x0121BA, 0x0121BB, 0x0121B4, 0x0121B5, 0x0121B6,
+ 0x0121B7, 0x0121B0, 0x0121B1, 0x0121B2, 0x0121B3, 0x01218C, 0x01218D, 0x01218E,
+ 0x01218F, 0x012188, 0x012189, 0x01218A, 0x01218B, 0x012184, 0x012185, 0x012186,
+ 0x012187, 0x012180, 0x00D7C1, 0x00D7C0, 0x00D7C3, 0x00D7C2, 0x00D7C5, 0x00D7C4,
+ 0x012181, 0x00D7C6, 0x012182, 0x012183, 0x00D7CB, 0x00D7E8, 0x00D7CD, 0x00D7CC,
+ 0x00D7CF, 0x00D7CE, 0x01219C, 0x01219D, 0x01219E, 0x01219F, 0x00D7D5, 0x00D7D4,
+ 0x00D7EF, 0x00D7D6, 0x00D7D9, 0x00D7D8, 0x00D7DB, 0x00D7DA, 0x00D7DD, 0x00D7DC,
+ 0x00D7DF, 0x00D7DE, 0x00D7E1, 0x00D7E0, 0x00D7E3, 0x00D7E2, 0x00D7E5, 0x00D7E4,
+ 0x00D7E9, 0x00D7E6, 0x00D7F8, 0x00D7ED, 0x00D7EB, 0x00D7EA, 0x00D7B2, 0x00D7EE,
+ 0x00D7EC, 0x00D7B3, 0x00D7F1, 0x00D7F0, 0x00D7F3, 0x00D7F2, 0x00D7F5, 0x00D7F4,
+ 0x00D7F7, 0x00D7F6, 0x00D7F9, 0x00D7FA, 0x00D7FB, 0x012198, 0x012199, 0x01219A,
+ 0x01219B, 0x00D7E7, 0x00FA00, 0x00FA03, 0x00FA02, 0x02F8A1, 0x02F858, 0x02F8A2,
+ 0x02F8A3, 0x02F8A0, 0x02F8A5, 0x02F8A6, 0x02F8A7, 0x02F8A8, 0x02F8A9, 0x02F8AA,
+ 0x02F8AB, 0x02F8A4, 0x02F8AD, 0x02F8AE, 0x02F8AF, 0x00FA01, 0x00FA1C, 0x00FA1D,
+ 0x00FA1E, 0x00FA06, 0x02F84D, 0x00FA19, 0x00FA1F, 0x02F8B8, 0x02F8AC, 0x02F84E,
+ 0x02F84C, 0x02F8BC, 0x02F8BD, 0x02F8BE, 0x02F8BF, 0x02F8C0, 0x02F8C1, 0x02F8C2,
+ 0x02F8C3, 0x02F8C4, 0x02F8C5, 0x02F8C6, 0x02F8C7, 0x02F8C8, 0x02F8C9, 0x02F8CA,
+ 0x02F8CB, 0x02F8CC, 0x02F8CD, 0x02F8CE, 0x02F8CF, 0x02F8D0, 0x02F8D1, 0x02F8D2,
+ 0x02F8D3, 0x02F8D4, 0x02F8D5, 0x02F8D6, 0x02F8D7, 0x02F8D8, 0x02F8D9, 0x02F8DA,
+ 0x02F8DB, 0x02F8DC, 0x02F8DD, 0x02F8DE, 0x02F8DF, 0x02F873, 0x02F973, 0x02F85A,
+ 0x02F85B, 0x02F872, 0x02F856, 0x00FA0A, 0x02F85F, 0x00FA0B, 0x00FA04, 0x00FA05,
+ 0x00FA07, 0x02F854, 0x02F855, 0x00FA4B, 0x00FA0C, 0x00FA61, 0x00FA0D, 0x02F8F2,
+ 0x02F8F3, 0x00FA60, 0x00FA09, 0x02F851, 0x02F852, 0x00FA08, 0x00FA0E, 0x02F857,
+ 0x02F850, 0x00FA0F, 0x00FA24, 0x00FA3D, 0x00FA71, 0x00FA25, 0x00FA34, 0x00FC22,
+ 0x00FA3C, 0x00FA26, 0x00FA28, 0x00FA3B, 0x00FA3A, 0x00FA38, 0x00FA75, 0x00FA2B,
+ 0x00FA3E, 0x00FA7B, 0x00FA32, 0x00FA31, 0x00FA73, 0x00FA33, 0x00FA30, 0x00FA36,
+ 0x00FA57, 0x00FA62, 0x00FA77, 0x00FA2F, 0x00FA72, 0x00FA3F, 0x00FA39, 0x00FA35,
+ 0x00FA37, 0x00FA23, 0x012194, 0x012195, 0x012196, 0x012197, 0x012190, 0x012191,
+ 0x012192, 0x012193, 0x00324C, 0x00324D, 0x00324E, 0x00324F, 0x003248, 0x003249,
+ 0x00324A, 0x00324B, 0x00FC10, 0x00FC11, 0x00FC12, 0x00325C, 0x00FC14, 0x00FC15,
+ 0x00FC16, 0x00FC17, 0x00FC1A, 0x00FC19, 0x00325D, 0x00FC1B, 0x00325E, 0x00FC18,
+ 0x00325F, 0x00FC1F, 0x00FC50, 0x00FC57, 0x00FC52, 0x00FC51, 0x00FC54, 0x02F859,
+ 0x00FC56, 0x00FC55, 0x00FCF8, 0x00FCF9, 0x00FCFA, 0x003258, 0x00FCFC, 0x003259,
+ 0x00FCFE, 0x00FCFD, 0x00325A, 0x00325B, 0x003254, 0x003255, 0x00FA49, 0x00FC53,
+ 0x003256, 0x003257, 0x003251, 0x00FA4A, 0x003252, 0x003253, 0x00FCF5, 0x003228,
+ 0x003229, 0x003224, 0x00FC01, 0x00FCE9, 0x00FCE8, 0x00FC02, 0x00FCE4, 0x00FC05,
+ 0x00FC03, 0x00FA47, 0x012506, 0x012507, 0x00FC0B, 0x00FCE3, 0x012505, 0x00FC09,
+ 0x00FC07, 0x00FCEF, 0x00FA46, 0x00FCC8, 0x00FCC9, 0x00FCCA, 0x00FCC4, 0x00FCF1,
+ 0x00FCF2, 0x00FCF7, 0x00FA45, 0x00FCF0, 0x00FCF6, 0x00FCF4, 0x003225, 0x003226,
+ 0x00FCFF, 0x003227, 0x003220, 0x00FCE5, 0x003221, 0x01251C, 0x00FCEB, 0x003222,
+ 0x00FCE7, 0x003223, 0x00FCCF, 0x011C6C, 0x00FA44, 0x00FC3A, 0x00FC1C, 0x00FCE6,
+ 0x00FC1E, 0x011C68, 0x00FC00, 0x00FC08, 0x00FC0A, 0x011C69, 0x00FC04, 0x00FC0F,
+ 0x00FC06, 0x011C6A, 0x00FC33, 0x011C6B, 0x011C64, 0x011C65, 0x00FC1D, 0x00FCCC,
+ 0x00FCCD, 0x00FCCE, 0x011C66, 0x011C67, 0x011C60, 0x011C61, 0x011C62, 0x011C63,
+ 0x011C7C, 0x011C7D, 0x011C7E, 0x011C7F, 0x011C78, 0x011C79, 0x011C7A, 0x011C7B,
+ 0x011C74, 0x011C75, 0x011C76, 0x011C77, 0x011C72, 0x0032BD, 0x0032BE, 0x0032BF,
+ 0x0032B8, 0x0032B9, 0x0032BA, 0x0032BB, 0x0032B4, 0x0032B5, 0x0032B6, 0x0032B7,
+ 0x0032B2, 0x0032B3, 0x011C5C, 0x011C5D, 0x011C5E, 0x00FF23, 0x011C59, 0x011C5A,
+ 0x011C2D, 0x011C2E, 0x00FC3C, 0x016A64, 0x011C27, 0x011C20, 0x011C21, 0x00FC3D,
+ 0x00FC3E, 0x011C22, 0x011C23, 0x016A4C, 0x00FC38, 0x00FC27, 0x00FF36, 0x00FC21,
+ 0x00FF37, 0x00FC23, 0x016A4D, 0x016A4E, 0x016A4F, 0x016A48, 0x00FC39, 0x016A46,
+ 0x011C02, 0x016A29, 0x016A2A, 0x016A2B, 0x016A24, 0x016A25, 0x016A26, 0x016A27,
+ 0x016A20, 0x016A21, 0x00FA48, 0x016A22, 0x016A23, 0x016A38, 0x00FA4C, 0x00FA4D,
+ 0x00FA4E, 0x00FA4F, 0x016A34, 0x016A35, 0x016A36, 0x016A37, 0x016A30, 0x016A31,
+ 0x016A32, 0x016A33, 0x016A0C, 0x016A0D, 0x016A0E, 0x016A0F, 0x016A08, 0x016A09,
+ 0x016A0A, 0x016A0B, 0x016A04, 0x016A05, 0x016A06, 0x00FA63, 0x00FA64, 0x00FA65,
+ 0x00FA66, 0x00FA67, 0x00FA68, 0x00FA69, 0x00FA6A, 0x00FA6B, 0x00FA6C, 0x00FA6D,
+ 0x016A07, 0x016A00, 0x00FA70, 0x016A01, 0x016A02, 0x016A03, 0x00FA74, 0x016A1C,
+ 0x00FA76, 0x016A1D, 0x00FA78, 0x00FA79, 0x00FA7A, 0x016A1E, 0x00FA7C, 0x00FA7D,
+ 0x00FA7E, 0x00FA7F, 0x016A1F, 0x016A18, 0x016A19, 0x016A1A, 0x016A1B, 0x016A14,
+ 0x016A15, 0x016A16, 0x016A17, 0x016A10, 0x016A11, 0x016A12, 0x016A13, 0x016AEC,
+ 0x016AED, 0x016AE8, 0x016AE9, 0x016AEA, 0x016AEB, 0x016AE4, 0x016AE5, 0x016AE6,
+ 0x016AE7, 0x016AE0, 0x016AE1, 0x016AE2, 0x016AE3, 0x011C8C, 0x011C8D, 0x011C8E,
+ 0x011C8F, 0x011C88, 0x011C89, 0x011C8A, 0x011C8B, 0x011C84, 0x011C85, 0x011C86,
+ 0x016AD9, 0x016ADA, 0x016ADB, 0x016AD4, 0x016AD5, 0x016AD6, 0x016AD7, 0x016AD0,
+ 0x016AD1, 0x016AD2, 0x00FC20, 0x00FC25, 0x00FC24, 0x016AD3, 0x00FC26, 0x011D46,
+ 0x011D58, 0x011D59, 0x011D54, 0x011D55, 0x011D56, 0x011D25, 0x011D27, 0x00306D,
+ 0x00306E, 0x00306F, 0x003060, 0x00FC2A, 0x003062, 0x003063, 0x00FC29, 0x00307C,
+ 0x00307B, 0x003050, 0x003051, 0x003052, 0x003053, 0x00FC2B, 0x003028, 0x003029,
+ 0x003024, 0x003025, 0x003026, 0x003027, 0x016B0C, 0x016B09, 0x016B0A, 0x016B0B,
+ 0x016B07, 0x016B00, 0x016B01, 0x016B02, 0x016B03, 0x016B1C, 0x016B1D, 0x016B1E,
+ 0x016B1F, 0x016B18, 0x016B19, 0x016B1A, 0x016B1B, 0x016B14, 0x016B15, 0x016B16,
+ 0x016B17, 0x016B10, 0x016B11, 0x0030EC, 0x0030ED, 0x0030EE, 0x0030EF, 0x0030E8,
+ 0x0030E9, 0x0030EA, 0x0030EB, 0x0030E4, 0x0030E5, 0x0030E6, 0x0030E7, 0x0030E0,
+ 0x0030E1, 0x0030E2, 0x0030E3, 0x0030FF, 0x0030F8, 0x0030F9, 0x0030FA, 0x0030F4,
+ 0x0030F5, 0x0030F6, 0x0030F7, 0x0030F0, 0x0030F1, 0x0030F2, 0x0030F3, 0x0030CC,
+ 0x0030CD, 0x0030CE, 0x0030CF, 0x0030C8, 0x0030C9, 0x0030CA, 0x0030CB, 0x0030C4,
+ 0x0030C5, 0x0030C6, 0x0030C7, 0x0030C0, 0x0030C1, 0x0030C2, 0x0030C3, 0x0030DC,
+ 0x00FAB1, 0x0030B0, 0x0030B1, 0x0030B2, 0x0030B3, 0x00308C, 0x00FAB0, 0x003089,
+ 0x00308A, 0x00308B, 0x003084, 0x003085, 0x003086, 0x003087, 0x016868, 0x01683B,
+ 0x0168F8, 0x0168F9, 0x00FC28, 0x0168FA, 0x0168FB, 0x0168F4, 0x00FC2C, 0x00FC2D,
+ 0x00FC2E, 0x00FC2F, 0x0168F5, 0x0168F6, 0x0168F7, 0x0168F0, 0x0168F1, 0x0168F2,
+ 0x0168F3, 0x0168CC, 0x0168CD, 0x0168CE, 0x0168CF, 0x0168D9, 0x0168DA, 0x0168DB,
+ 0x0168D4, 0x0168D5, 0x0168D6, 0x0168D7, 0x0168D0, 0x0168D1, 0x0168D2, 0x0168D3,
+ 0x0168AC, 0x0168AD, 0x0168AE, 0x0168AF, 0x0168A8, 0x0168A9, 0x0168AA, 0x0168AB,
+ 0x0168A4, 0x0168A5, 0x0168A6, 0x00FAB4, 0x00FABA, 0x0168A7, 0x0168A0, 0x0168A1,
+ 0x0168A2, 0x0168A3, 0x0168BC, 0x00FC59, 0x00FC5A, 0x00FC5B, 0x0168BD, 0x00FABB,
+ 0x0168BE, 0x00FC5F, 0x0168BF, 0x016888, 0x016889, 0x01688A, 0x01688B, 0x016887,
+ 0x01689B, 0x016968, 0x016969, 0x01696A, 0x01696B, 0x016964, 0x016965, 0x016966,
+ 0x016967, 0x016962, 0x016963, 0x01697C, 0x01697D, 0x016978, 0x016979, 0x01697A,
+ 0x01697B, 0x016974, 0x00FAB5, 0x016975, 0x016976, 0x016977, 0x016970, 0x016971,
+ 0x00FAB6, 0x016972, 0x016973, 0x01694C, 0x01694D, 0x01694E, 0x01694F, 0x016948,
+ 0x016949, 0x01694A, 0x01694B, 0x016944, 0x016945, 0x016946, 0x016947, 0x016940,
+ 0x016941, 0x00FAB2, 0x016942, 0x016943, 0x01695C, 0x01695D, 0x01695E, 0x01695F,
+ 0x016958, 0x016959, 0x01695A, 0x01695B, 0x016954, 0x016955, 0x016956, 0x016957,
+ 0x016950, 0x016951, 0x016952, 0x016953, 0x01692C, 0x01692D, 0x01692E, 0x01692F,
+ 0x016928, 0x016929, 0x01692A, 0x01692B, 0x016924, 0x016925, 0x00FA8C, 0x016926,
+ 0x016927, 0x016920, 0x016921, 0x016922, 0x016923, 0x01693C, 0x01693D, 0x01693E,
+ 0x01693F, 0x016938, 0x016939, 0x01693A, 0x01693B, 0x016934, 0x016935, 0x016936,
+ 0x016937, 0x016930, 0x016931, 0x016932, 0x016933, 0x01690C, 0x01690D, 0x01690E,
+ 0x01690F, 0x016908, 0x016909, 0x01690A, 0x01690B, 0x016904, 0x016905, 0x016906,
+ 0x016907, 0x016900, 0x016901, 0x016902, 0x016903, 0x01691C, 0x01691D, 0x01691E,
+ 0x01691F, 0x016918, 0x016919, 0x01691A, 0x01691B, 0x016914, 0x016915, 0x016916,
+ 0x016917, 0x016910, 0x016911, 0x016912, 0x016913, 0x0169EC, 0x0169ED, 0x0169EE,
+ 0x0169EF, 0x0169E8, 0x0169E9, 0x0169EA, 0x0169EB, 0x0169E4, 0x0169E5, 0x0169E6,
+ 0x0169E7, 0x0169E0, 0x0169E1, 0x0169E2, 0x0169E3, 0x0169FC, 0x0169FD, 0x0169FE,
+ 0x0169FF, 0x0169F8, 0x0169F9, 0x0169FA, 0x0169FB, 0x0169F4, 0x0169F5, 0x0169F6,
+ 0x0169F7, 0x0169F0, 0x00FAC0, 0x00FAC1, 0x00FAC6, 0x0169F1, 0x00FFD4, 0x00FFD5,
+ 0x0169F2, 0x0169F3, 0x0169CC, 0x0169CD, 0x00FAC4, 0x00FFDA, 0x0169CE, 0x0169CF,
+ 0x0169C8, 0x00FAC5, 0x00FAC8, 0x0169C9, 0x00FACA, 0x0169CA, 0x0169CB, 0x00FFAC,
+ 0x00FFAD, 0x00FFAE, 0x0169C4, 0x0169C5, 0x0169C6, 0x0169C7, 0x00FAAC, 0x00FACB,
+ 0x00FAD8, 0x0169C0, 0x0169C1, 0x0169C2, 0x0169C3, 0x00FAA9, 0x0169DC, 0x0169DD,
+ 0x0169DE, 0x00FAA4, 0x00FFA7, 0x00FAC9, 0x0169DF, 0x00FAAA, 0x00FACC, 0x00FACD,
+ 0x00FACE, 0x00FACF, 0x0169D8, 0x00FFAB, 0x00FFA2, 0x00FFA1, 0x00FAAE, 0x00FFA0,
+ 0x00FFA6, 0x00FAAD, 0x00FFA9, 0x00FFA8, 0x00FAA8, 0x00FFAA, 0x00FFA4, 0x00FAAF,
+ 0x00FFAF, 0x00FFA5, 0x0169D9, 0x0169DA, 0x0169DB, 0x0169D4, 0x0169D5, 0x0169D6,
+ 0x0169D7, 0x0169D0, 0x0169D1, 0x0169D2, 0x00FFD3, 0x0169D3, 0x0169AC, 0x0169AD,
+ 0x0169AE, 0x0169AF, 0x0169A8, 0x0169A9, 0x0169AA, 0x0169AB, 0x0169A4, 0x00FAC2,
+ 0x0169A5, 0x0169A6, 0x0169A7, 0x0169A0, 0x0169A1, 0x0169A2, 0x0169A3, 0x0169BC,
+ 0x0169BD, 0x0169BE, 0x0169BF, 0x0169B8, 0x0169B9, 0x0169BA, 0x0169BB, 0x0169B4,
+ 0x0169B5, 0x0169B6, 0x0169B7, 0x0169B0, 0x0169B1, 0x0169B2, 0x0169B3, 0x01698C,
+ 0x01698D, 0x01698E, 0x00FAD0, 0x01698F, 0x00FFD2, 0x00FFD6, 0x016988, 0x00FAD5,
+ 0x00FAD6, 0x00FFD7, 0x016989, 0x00FAD9, 0x01698A, 0x01698B, 0x016984, 0x00FAD4,
+ 0x00FFDB, 0x016985, 0x00FA10, 0x016986, 0x00FA12, 0x00FF84, 0x00FA14, 0x00FA15,
+ 0x00FA16, 0x00FA17, 0x00FA18, 0x00FF88, 0x00FA1A, 0x00FF8B, 0x00FF8D, 0x00FA1B,
+ 0x00FF8F, 0x00FF8E, 0x016987, 0x00FA11, 0x016980, 0x00FA13, 0x016981, 0x016982,
+ 0x016983, 0x01699C, 0x01699D, 0x01699E, 0x01699F, 0x016998, 0x016999, 0x01699A,
+ 0x01699B, 0x016994, 0x016995, 0x016996, 0x016997, 0x00FFA3, 0x016990, 0x016991,
+ 0x016992, 0x016993, 0x0118EC, 0x00FFBD, 0x0118ED, 0x0118EE, 0x00FFBE, 0x00FFBC,
+ 0x0118EF, 0x00FAA3, 0x00FFB0, 0x00FFB5, 0x00FFB6, 0x0118E8, 0x00FABC, 0x00FABD,
+ 0x00FABE, 0x00FFB7, 0x00FABF, 0x00FFB9, 0x00FFBA, 0x00FFBB, 0x00FAB8, 0x00FAB9,
+ 0x00FFB4, 0x00FFB8, 0x0118E9, 0x0118EA, 0x0118EB, 0x0118E4, 0x0118E5, 0x0118E6,
+ 0x0118E7, 0x0118E0, 0x0118E1, 0x0118E2, 0x0118E3, 0x0118FF, 0x0118F0, 0x0118F1,
+ 0x0118F2, 0x0118CC, 0x0118CD, 0x0118CE, 0x0118CF, 0x0118C8, 0x0118C9, 0x0118CA,
+ 0x0118CB, 0x0118C4, 0x0118C5, 0x0118C6, 0x0118C7, 0x0118C0, 0x0118C1, 0x0118C2,
+ 0x0118C3, 0x0118DC, 0x0118DD, 0x0118DE, 0x0118DF, 0x0118D8, 0x0118D9, 0x0118DA,
+ 0x0118DB, 0x0118D4, 0x0118D5, 0x0118D6, 0x0118D7, 0x0118D0, 0x0118D1, 0x0118D2,
+ 0x0118D3, 0x0118AC, 0x0118AD, 0x0118AE, 0x0118AF, 0x0118A8, 0x0118A9, 0x0118AA,
+ 0x0118AB, 0x0118A4, 0x0118A5, 0x0118A6, 0x0118A7, 0x0118A0, 0x0118A1, 0x0118A2,
+ 0x0118A3, 0x0118BC, 0x0118BD, 0x0118BE, 0x0118BF, 0x0118B8, 0x0118B9, 0x0118BA,
+ 0x0118BB, 0x0118B4, 0x0118B5, 0x0118B6, 0x0118B7, 0x0118B0, 0x0118B1, 0x0118B2,
+ 0x0118B3, 0x002C6C, 0x002C6D, 0x002C6E, 0x002C6F, 0x002C68, 0x002C69, 0x002C6A,
+ 0x002C6B, 0x002C64, 0x002C65, 0x002C66, 0x002C67, 0x002C60, 0x002C61, 0x002C62,
+ 0x002C63, 0x002C7E, 0x002C7F, 0x002C78, 0x002C79, 0x002C7A, 0x002C7B, 0x002C74,
+ 0x002C75, 0x002C76, 0x002C77, 0x002C70, 0x002C71, 0x002C72, 0x002C73, 0x002C4C,
+ 0x002C4D, 0x002C4E, 0x002C4F, 0x002C48, 0x002C49, 0x002C4A, 0x002C4B, 0x002C44,
+ 0x002C45, 0x002C46, 0x002C47, 0x002C40, 0x002C41, 0x002C42, 0x002C43, 0x002C5C,
+ 0x002C5D, 0x002C5E, 0x00FCD8, 0x00FCDD, 0x00FCDC, 0x002C58, 0x00FCD4, 0x00FCDE,
+ 0x00FCD6, 0x00FCDF, 0x002C59, 0x00FCD9, 0x00FCDA, 0x002C5A, 0x002C5B, 0x002C54,
+ 0x002C55, 0x002C56, 0x002C57, 0x002C50, 0x002C51, 0x002C52, 0x002C53, 0x002C2C,
+ 0x002C2D, 0x002C2E, 0x002C28, 0x002C29, 0x002C2A, 0x002C2B, 0x002C24, 0x002C25,
+ 0x002C26, 0x002C27, 0x002C20, 0x002C21, 0x002C22, 0x002C23, 0x002C3C, 0x00FCC5,
+ 0x002C3D, 0x002C3E, 0x002C3F, 0x002C38, 0x002C39, 0x002C3A, 0x002C3B, 0x002C34,
+ 0x002C35, 0x002C36, 0x002C37, 0x002C30, 0x002C31, 0x002C32, 0x002C33, 0x002C0C,
+ 0x002C0D, 0x002C0E, 0x002C0F, 0x002C08, 0x002C09, 0x002C0A, 0x002C0B, 0x002C04,
+ 0x002C05, 0x002C06, 0x00FC80, 0x00FC81, 0x00FC82, 0x00FCD2, 0x00FC84, 0x00FCD5,
+ 0x00FCD0, 0x00FC87, 0x00FC88, 0x00FC89, 0x00FC8A, 0x00FC8B, 0x00FC8C, 0x002C07,
+ 0x00FCDB, 0x00FC8F, 0x00FCC1, 0x00FC90, 0x00FC91, 0x00FC92, 0x00FCC2, 0x00FC94,
+ 0x002C00, 0x00FC96, 0x00FCD1, 0x00FCC0, 0x00FCD3, 0x00FCC7, 0x00FC93, 0x00FC97,
+ 0x00FCC6, 0x00FC95, 0x00FCA4, 0x00FCA1, 0x00FCA2, 0x00FC83, 0x00FCB9, 0x00FCD7,
+ 0x00FCC3, 0x00FCA7, 0x002C01, 0x00FCBB, 0x002C02, 0x00FCFB, 0x00FCCB, 0x00FCF3,
+ 0x00FCBA, 0x002C03, 0x00FCB0, 0x00FCB1, 0x00FCB2, 0x00FCB3, 0x00FCB4, 0x00FCB5,
+ 0x00FCB6, 0x00FCB7, 0x00FC98, 0x00FC99, 0x00FC9A, 0x00FC9B, 0x00FC9C, 0x00FC9D,
+ 0x00FC9E, 0x00FC9F, 0x002C1C, 0x002C1D, 0x002C1E, 0x002C1F, 0x002C18, 0x002C19,
+ 0x002C1A, 0x002C1B, 0x00FCBC, 0x002C14, 0x002C15, 0x002C16, 0x002C17, 0x00FCBD,
+ 0x00FCBE, 0x00FCBF, 0x002C10, 0x002C11, 0x002C12, 0x00FCA3, 0x002C13, 0x002CEC,
+ 0x002CED, 0x002CEE, 0x002CEB, 0x00FCE1, 0x00FCE2, 0x002CE4, 0x00FCE0, 0x00FCB8,
+ 0x002CE0, 0x002CE1, 0x002CE2, 0x002CE3, 0x002CFD, 0x002CF2, 0x002CF3, 0x002CCC,
+ 0x002CCD, 0x00FCAF, 0x00FCA8, 0x00FCA9, 0x00FCAA, 0x00FCAB, 0x00FCAC, 0x00FCAD,
+ 0x00FCAE, 0x002CCE, 0x002CCF, 0x002CC8, 0x002CC9, 0x002CCA, 0x002CCB, 0x002CC4,
+ 0x002CC5, 0x002CC6, 0x002CC7, 0x002CC0, 0x002CC1, 0x002CC2, 0x002CC3, 0x002CDC,
+ 0x002CDD, 0x002CDE, 0x002CDF, 0x002CD8, 0x002CD9, 0x002CDA, 0x002CDB, 0x002CD4,
+ 0x002CD5, 0x002CD6, 0x002CD7, 0x002CD0, 0x002CD1, 0x002CD2, 0x002CD3, 0x002CAC,
+ 0x002CAD, 0x002CAE, 0x002CAF, 0x002CA8, 0x002CA9, 0x002CAA, 0x002CAB, 0x002CA4,
+ 0x002CA5, 0x002CA6, 0x002CA7, 0x002CA0, 0x002CA1, 0x002CA2, 0x002CA3, 0x002CBC,
+ 0x002CBD, 0x002CBE, 0x002CBF, 0x002CB8, 0x002CB9, 0x002CBA, 0x002CBB, 0x002CB4,
+ 0x002CB6, 0x002CB7, 0x002CB0, 0x002CB1, 0x002CB2, 0x002CB3, 0x002C8C, 0x002C8D,
+ 0x002C8E, 0x002C8F, 0x002C88, 0x002C8B, 0x002C84, 0x011623, 0x002D64, 0x002D65,
+ 0x002D66, 0x002D67, 0x002D60, 0x002D61, 0x002D62, 0x002D63, 0x01160C, 0x01160D,
+ 0x01160E, 0x01160F, 0x011608, 0x011609, 0x01160A, 0x01160B, 0x011604, 0x011605,
+ 0x011606, 0x011607, 0x011600, 0x011601, 0x011602, 0x002D5D, 0x00FD7C, 0x00FD6D,
+ 0x002D5E, 0x002D5F, 0x00FD50, 0x00FD51, 0x00FD52, 0x002D58, 0x00FD54, 0x00FD55,
+ 0x00FD56, 0x00FD57, 0x00FD58, 0x00FD59, 0x00FD5A, 0x00FD5B, 0x00FD5C, 0x00FD5D,
+ 0x00FD5E, 0x00FD5F, 0x00FD78, 0x00FD7D, 0x00FD7E, 0x00FD62, 0x00FD74, 0x00FD75,
+ 0x00FD76, 0x00FD7F, 0x00FD67, 0x00FD79, 0x00FD7A, 0x00FD61, 0x002D59, 0x00FD60,
+ 0x00FD6B, 0x002D5A, 0x00FD65, 0x00FD71, 0x00FD72, 0x00FD73, 0x00FD64, 0x00FD70,
+ 0x00FD66, 0x00FD77, 0x00FD68, 0x00FD7B, 0x00FD6A, 0x00FD63, 0x00FD6C, 0x00FD69,
+ 0x00FD6E, 0x00FD6F, 0x002D5B, 0x002D54, 0x002D55, 0x002D56, 0x002D57, 0x002D50,
+ 0x002D51, 0x002D52, 0x002D53, 0x002D2D, 0x002D24, 0x002D25, 0x002D27, 0x002D20,
+ 0x002D21, 0x002D22, 0x002D23, 0x002D3C, 0x002D3D, 0x002D3E, 0x002D3F, 0x002D38,
+ 0x002D3B, 0x002D34, 0x002D0D, 0x002D0E, 0x002D0F, 0x002D08, 0x002D09, 0x002D0A,
+ 0x002D0B, 0x002D04, 0x002D05, 0x002D06, 0x002D07, 0x002D00, 0x002D01, 0x002D02,
+ 0x002D03, 0x002D1C, 0x002D1D, 0x002D1E, 0x002D1F, 0x002D18, 0x002D14, 0x0116A3,
+ 0x01168C, 0x01168D, 0x01168E, 0x01168F, 0x011688, 0x011689, 0x01168A, 0x01168B,
+ 0x011684, 0x011685, 0x011686, 0x011687, 0x011680, 0x011681, 0x011682, 0x01169E,
+ 0x011696, 0x002DDD, 0x002DDE, 0x002DD8, 0x002DD9, 0x002DDA, 0x002DDB, 0x002DD4,
+ 0x002DD5, 0x002DD6, 0x002DD0, 0x002DD1, 0x002DD2, 0x002DD3, 0x002DAC, 0x002DAD,
+ 0x002DAE, 0x002DA8, 0x002DA9, 0x002DAA, 0x002DAB, 0x002DA4, 0x002DA5, 0x002DA6,
+ 0x002DA0, 0x002DA1, 0x002DA2, 0x002DA3, 0x01E807, 0x002DBC, 0x002DBD, 0x002DBE,
+ 0x002DB8, 0x002DB9, 0x002DBA, 0x002DBB, 0x002DB4, 0x002DB5, 0x002DB6, 0x002DB0,
+ 0x01E817, 0x002DB1, 0x002DB2, 0x002DB3, 0x002D8C, 0x002D8D, 0x002D8E, 0x002D8F,
+ 0x002D88, 0x002D89, 0x002D8A, 0x002D8B, 0x01E83B, 0x002D84, 0x002D85, 0x002D86,
+ 0x002D87, 0x01E830, 0x01E831, 0x002D80, 0x002D81, 0x01E834, 0x002D82, 0x002D83,
+ 0x01E837, 0x002D94, 0x01E832, 0x002D95, 0x002D96, 0x002D90, 0x00FD04, 0x00FD05,
+ 0x00FD06, 0x00FD07, 0x00FD08, 0x00FD09, 0x00FD0A, 0x00FD0F, 0x00FD0C, 0x00FD0D,
+ 0x00FD0E, 0x00FD1F, 0x00FD10, 0x00FD11, 0x00FD12, 0x00FD13, 0x002D91, 0x00FD16,
+ 0x00FD1B, 0x00FD17, 0x002D92, 0x00FD18, 0x002D93, 0x011738, 0x00FD15, 0x00FD14,
+ 0x011739, 0x01173A, 0x01173B, 0x011734, 0x011735, 0x011736, 0x011737, 0x011730,
+ 0x011731, 0x011732, 0x011733, 0x01170C, 0x01170D, 0x01170E, 0x01170F, 0x011708,
+ 0x011709, 0x01170A, 0x00FD30, 0x01170B, 0x011704, 0x011705, 0x00FD35, 0x00FD34,
+ 0x011706, 0x00FD33, 0x011707, 0x011700, 0x011701, 0x011702, 0x011703, 0x00FD3D,
+ 0x011718, 0x011719, 0x011714, 0x011715, 0x011716, 0x011717, 0x011710, 0x011711,
+ 0x011712, 0x011713, 0x011448, 0x011449, 0x01144A, 0x011447, 0x011458, 0x011459,
+ 0x011454, 0x011455, 0x011456, 0x011457, 0x011450, 0x011451, 0x011452, 0x011453,
+ 0x01142C, 0x01142D, 0x01142E, 0x01142F, 0x011428, 0x011429, 0x01142A, 0x01142B,
+ 0x011424, 0x011425, 0x011426, 0x011427, 0x011420, 0x011421, 0x011422, 0x011423,
+ 0x011434, 0x011430, 0x011431, 0x011432, 0x011433, 0x01140C, 0x01140D, 0x01140E,
+ 0x01140F, 0x011408, 0x011409, 0x01140A, 0x01140B, 0x011404, 0x011405, 0x011406,
+ 0x011407, 0x011400, 0x011401, 0x011402, 0x011403, 0x01141C, 0x01141D, 0x01141E,
+ 0x01141F, 0x011418, 0x011419, 0x01B066, 0x01B067, 0x01B060, 0x01B061, 0x01B062,
+ 0x01B063, 0x01B07C, 0x01B07D, 0x01B07E, 0x01B07F, 0x01B078, 0x01B079, 0x01B07A,
+ 0x01B07B, 0x01B074, 0x01B075, 0x01B076, 0x01B077, 0x01B070, 0x01B071, 0x01B072,
+ 0x01B073, 0x01B04C, 0x01B04D, 0x01B04E, 0x01B04F, 0x01B048, 0x01B049, 0x01B04A,
+ 0x01B04B, 0x01B044, 0x01B045, 0x01B046, 0x01B047, 0x01B040, 0x00FDA4, 0x00FDA5,
+ 0x00FDAC, 0x01B041, 0x00FDA8, 0x00FDA9, 0x00FDAA, 0x00FDAB, 0x00FDAE, 0x00FDAD,
+ 0x01B042, 0x00FDAF, 0x01B043, 0x01B05C, 0x01B05D, 0x01B058, 0x01B05A, 0x01B05B,
+ 0x01B054, 0x01B055, 0x01B056, 0x01B057, 0x01B050, 0x01B051, 0x01B02C, 0x00FEC4,
+ 0x01B02D, 0x01B036, 0x00FEC7, 0x00FEC2, 0x01B037, 0x00FDC3, 0x00FEC0, 0x00FEC1,
+ 0x01B030, 0x00FEC5, 0x01B031, 0x01B032, 0x01B033, 0x00FEC6, 0x01B00C, 0x01B00D,
+ 0x01B00E, 0x00FDF9, 0x00FDF1, 0x00FDFB, 0x00FDF7, 0x01B00F, 0x01B008, 0x00FDF5,
+ 0x00FDF6, 0x01B009, 0x01B00A, 0x01B00B, 0x01B004, 0x01B005, 0x00FDF4, 0x01B0E6,
+ 0x00FDF8, 0x01B0E7, 0x00FDF0, 0x01B0E0, 0x00FDF2, 0x01B0E1, 0x01B0E2, 0x01B0E3,
+ 0x01B0FC, 0x01B0FD, 0x01B0FE, 0x01B0FF, 0x01B0F8, 0x01B0F9, 0x01B0FA, 0x01B0FB,
+ 0x00FEDC, 0x01B0F4, 0x01B0F5, 0x01B0F6, 0x01B0F7, 0x01B0F0, 0x01B0F1, 0x01B0F2,
+ 0x01B0F3, 0x00FEC3, 0x01B0CC, 0x01B0CD, 0x01B0CE, 0x01B0CF, 0x01B0C8, 0x01B0C9,
+ 0x01B0CA, 0x01B0CB, 0x01B0C4, 0x01B0C5, 0x01B0C6, 0x01B0C7, 0x00FDA2, 0x01B0C0,
+ 0x01B0C1, 0x01B0C2, 0x01B0C3, 0x01B0DC, 0x01B0DD, 0x01B0DE, 0x01B0DF, 0x01B0D8,
+ 0x01B0D9, 0x00FDA1, 0x01B0DA, 0x01B0DB, 0x01B0D4, 0x01B0D5, 0x00FDA0, 0x01B0D6,
+ 0x01B0D7, 0x01B0D0, 0x01B0D1, 0x01B0D2, 0x01B0D3, 0x01B0AC, 0x01B0AD, 0x01B0AE,
+ 0x01B0AF, 0x01B0A8, 0x01B0A9, 0x01B0AA, 0x01B0AB, 0x01B0A4, 0x01B0A5, 0x01B0A6,
+ 0x01B0A7, 0x01B0A0, 0x01B0A1, 0x01B0A2, 0x01B0A3, 0x01B0BC, 0x01B0BD, 0x01B0BE,
+ 0x01B0BF, 0x01B0B8, 0x01B0B9, 0x01B0BA, 0x01B0BB, 0x01B0B4, 0x01B0B5, 0x01B0B6,
+ 0x01B0B7, 0x01B0B0, 0x01B0B1, 0x01B0B2, 0x01B0B3, 0x01B08C, 0x01B08D, 0x01B08E,
+ 0x01B08F, 0x01B088, 0x01B089, 0x01B08A, 0x01B08B, 0x01B084, 0x01B085, 0x01B086,
+ 0x01B087, 0x01B080, 0x01B081, 0x01B082, 0x01B083, 0x01B09C, 0x01B09D, 0x01B09E,
+ 0x01B09F, 0x01B098, 0x01B099, 0x01B09A, 0x01B09B, 0x01B094, 0x01B095, 0x01B096,
+ 0x01B097, 0x01B090, 0x01B091, 0x01B092, 0x01B093, 0x0115D8, 0x0115D9, 0x0115DA,
+ 0x0115DB, 0x0115AC, 0x0115AD, 0x0115AE, 0x0115A8, 0x0115A9, 0x0115AA, 0x0115AB,
+ 0x0115A4, 0x0115A5, 0x0115A6, 0x0115A7, 0x0115A0, 0x0115A1, 0x0115A2, 0x0115A3,
+ 0x01B10C, 0x01B10D, 0x01B10E, 0x01B10F, 0x01B108, 0x01B109, 0x01B10A, 0x00FDA7,
+ 0x01B10B, 0x01B104, 0x01B105, 0x011585, 0x01159A, 0x01159B, 0x011594, 0x011595,
+ 0x00FDA6, 0x011596, 0x00FD81, 0x00FF2D, 0x00FF2E, 0x011597, 0x00FD80, 0x00FD84,
+ 0x00FD87, 0x00FD86, 0x00FD8B, 0x00FD89, 0x00FD88, 0x00FF2F, 0x00FD85, 0x00FD8E,
+ 0x00FD8D, 0x00FD8F, 0x00FD93, 0x011590, 0x00FD92, 0x011591, 0x00FD96, 0x00FD94,
+ 0x011592, 0x011593, 0x011228, 0x011229, 0x01122A, 0x00FDBC, 0x00FD8C, 0x00FD9C,
+ 0x00FD9B, 0x00FF2C, 0x01122B, 0x011224, 0x00FF2B, 0x011225, 0x011226, 0x011227,
+ 0x011220, 0x011221, 0x00FF21, 0x011222, 0x00FDBD, 0x00FF22, 0x00FF25, 0x00FF24,
+ 0x00FF27, 0x00FF26, 0x00FDB7, 0x00FDBB, 0x00FDB2, 0x00FDB0, 0x00FDB6, 0x00FF28,
+ 0x00FF2A, 0x00FDB5, 0x00FDB8, 0x00FDB9, 0x00FDBA, 0x00FF29, 0x011223, 0x00FDB4,
+ 0x00FDBE, 0x00FDBF, 0x00FEE8, 0x00FEEC, 0x01120C, 0x01120D, 0x00FECC, 0x00FEED,
+ 0x00FEEE, 0x01120E, 0x00FECA, 0x00FEC9, 0x00FF53, 0x00FECB, 0x00FEC8, 0x00FECD,
+ 0x00FECE, 0x00FECF, 0x00FF50, 0x00FF51, 0x00FF52, 0x01120F, 0x011208, 0x011209,
+ 0x01120A, 0x00FF56, 0x01120B, 0x011204, 0x011205, 0x011206, 0x011207, 0x011200,
+ 0x011201, 0x011202, 0x00FEF8, 0x00FEE2, 0x00FDA3, 0x00FEE3, 0x00FEE0, 0x00FEE1,
+ 0x00FEFC, 0x00FEE5, 0x00FEF9, 0x00FEE9, 0x00FEEA, 0x00FEEF, 0x00FEE4, 0x00FEEB,
+ 0x00FEE6, 0x00FEE7, 0x00FF54, 0x00FF55, 0x00FEF2, 0x00FEF3, 0x00FEF0, 0x00FEF1,
+ 0x00FEF7, 0x00FF57, 0x00FF58, 0x00FEFA, 0x00FF5A, 0x00FF59, 0x00FEF4, 0x00FEF5,
+ 0x00FEF6, 0x00FEFB, 0x011203, 0x01121C, 0x01121D, 0x01121E, 0x01121F, 0x011218,
+ 0x011219, 0x01121A, 0x01121B, 0x011214, 0x011215, 0x011216, 0x011217, 0x011210,
+ 0x011211, 0x011213, 0x0112F8, 0x0112F9, 0x0112F4, 0x0112F5, 0x0112F6, 0x0112F7,
+ 0x0112F0, 0x0112F1, 0x0112F2, 0x0112F3, 0x0112CC, 0x0112CD, 0x0112CE, 0x0112CF,
+ 0x0112C8, 0x0112C9, 0x0112CA, 0x0112CB, 0x0112C4, 0x0112C5, 0x0112C6, 0x0112C7,
+ 0x0112C0, 0x0112C1, 0x0112C2, 0x0112C3, 0x0112DC, 0x0112DD, 0x0112DE, 0x0112D8,
+ 0x0112D9, 0x0112DA, 0x0112DB, 0x0112D4, 0x0112D5, 0x0112D6, 0x0112D7, 0x0112D0,
+ 0x0112D1, 0x0112D2, 0x0112D3, 0x0112A8, 0x0112A4, 0x0112A5, 0x0112A6, 0x0112A7,
+ 0x0112A0, 0x0112A1, 0x0112A2, 0x0112A3, 0x0112BC, 0x0112BD, 0x0112BE, 0x0112BF,
+ 0x0112B8, 0x0112B9, 0x0112BA, 0x0112BB, 0x0112B4, 0x0112B5, 0x0112B6, 0x0112B7,
+ 0x0112B0, 0x0112B1, 0x0112B2, 0x0112B3, 0x01128C, 0x01128D, 0x01128F, 0x011288,
+ 0x01128A, 0x01128B, 0x011284, 0x011285, 0x011286, 0x011280, 0x011281, 0x011282,
+ 0x011283, 0x01129C, 0x01129D, 0x01129F, 0x011298, 0x011299, 0x01129A, 0x01129B,
+ 0x011294, 0x011295, 0x011296, 0x011297, 0x011290, 0x011291, 0x011292, 0x011293,
+ 0x011360, 0x011361, 0x01135D, 0x01135E, 0x01135F, 0x011350, 0x01132C, 0x01132D,
+ 0x01132E, 0x01132F, 0x011328, 0x01132A, 0x01132B, 0x011324, 0x011325, 0x011326,
+ 0x011327, 0x011320, 0x011321, 0x011322, 0x011323, 0x01133D, 0x011338, 0x011339,
+ 0x011335, 0x011336, 0x011337, 0x011330, 0x011332, 0x011333, 0x01130C, 0x01130F,
+ 0x011308, 0x011309, 0x01130A, 0x01130B, 0x011305, 0x011306, 0x011307, 0x01131C,
+ 0x01131D, 0x01131E, 0x01131F, 0x011318, 0x011319, 0x01131A, 0x01131B, 0x011314,
+ 0x011315, 0x011316, 0x011317, 0x011310, 0x011313, 0x01106C, 0x01106D, 0x01106E,
+ 0x01106F, 0x011068, 0x011069, 0x01106A, 0x01106B, 0x011064, 0x011065, 0x011066,
+ 0x011067, 0x011060, 0x011061, 0x011062, 0x011063, 0x01105C, 0x01105D, 0x01105E,
+ 0x01105F, 0x011058, 0x011059, 0x01105A, 0x01105B, 0x011054, 0x011055, 0x011056,
+ 0x011057, 0x011052, 0x011053, 0x01102C, 0x01102D, 0x01102E, 0x01102F, 0x011028,
+ 0x011029, 0x01102A, 0x01102B, 0x011024, 0x011025, 0x011026, 0x011027, 0x011020,
+ 0x011021, 0x011022, 0x011023, 0x011034, 0x011035, 0x011036, 0x011037, 0x011030,
+ 0x011031, 0x011032, 0x01100B, 0x011004, 0x011007, 0x011003, 0x01101C, 0x01101D,
+ 0x01101E, 0x01101F, 0x011018, 0x011019, 0x01101A, 0x01101B, 0x011014, 0x011015,
+ 0x011016, 0x011017, 0x011010, 0x011011, 0x011012, 0x011013, 0x0110E8, 0x0110E4,
+ 0x0110E5, 0x0110E6, 0x0110E7, 0x0110E0, 0x0110E1, 0x0110E2, 0x0110E3, 0x0110F8,
+ 0x0110F9, 0x0110F4, 0x0110F5, 0x0110F6, 0x0110F7, 0x0110F0, 0x0110F1, 0x0110F2,
+ 0x0110F3, 0x0110DC, 0x0110DD, 0x0110DE, 0x0110DF, 0x0110D8, 0x0110D9, 0x0110DA,
+ 0x0110DB, 0x0110D4, 0x0110D5, 0x0110D6, 0x0110D7, 0x0110D0, 0x0110D1, 0x0110D2,
+ 0x0110D3, 0x0110AC, 0x0110AD, 0x0110AE, 0x0110AF, 0x0110A8, 0x0110A9, 0x0110AA,
+ 0x0110AB, 0x0110A4, 0x0110A5, 0x0110A6, 0x0110A7, 0x0110A0, 0x0110A1, 0x0110A2,
+ 0x0110A3, 0x01108C, 0x01108D, 0x01108E, 0x01108F, 0x011088, 0x011089, 0x01108A,
+ 0x01108B, 0x011084, 0x011085, 0x011086, 0x011087, 0x011083, 0x01109C, 0x01109D,
+ 0x01109E, 0x01109F, 0x011098, 0x011099, 0x01109A, 0x01109B, 0x011094, 0x011095,
+ 0x011096, 0x011097, 0x011090, 0x011091, 0x011092, 0x011093, 0x01116C, 0x01116D,
+ 0x01116E, 0x01116F, 0x011168, 0x011169, 0x01116A, 0x01116B, 0x011164, 0x011165,
+ 0x011166, 0x011167, 0x011160, 0x011161, 0x011162, 0x011163, 0x011176, 0x011170,
+ 0x011171, 0x011172, 0x00278C, 0x011153, 0x011124, 0x011125, 0x011126, 0x002790,
+ 0x002465, 0x002466, 0x002461, 0x002462, 0x002463, 0x00247C, 0x002471, 0x002472,
+ 0x002473, 0x011103, 0x01111C, 0x01111D, 0x01111E, 0x01111F, 0x011118, 0x011119,
+ 0x01111A, 0x01111B, 0x011114, 0x011115, 0x011116, 0x011117, 0x011110, 0x011111,
+ 0x011112, 0x011113, 0x0111EC, 0x0111ED, 0x0111EE, 0x0111EF, 0x0111E8, 0x0111E9,
+ 0x0111EA, 0x0111EB, 0x0111E4, 0x0111E5, 0x0111E6, 0x0111E7, 0x0111E1, 0x0111E2,
+ 0x0111E3, 0x0111F4, 0x0111F0, 0x0111F1, 0x0111F2, 0x01E8AE, 0x01E8B4, 0x0111F3,
+ 0x0111C4, 0x0111C1, 0x01E8B9, 0x01E8BE, 0x01E8B8, 0x0111C2, 0x01E8A9, 0x01E8BA,
+ 0x01E8AA, 0x0111C3, 0x0111DC, 0x0111D8, 0x01E887, 0x01E880, 0x01E881, 0x0111D9,
+ 0x0111DA, 0x0111D4, 0x0111D5, 0x0111D6, 0x01E884, 0x0111D7, 0x0111D0, 0x01E886,
+ 0x01E885, 0x0111D1, 0x01E890, 0x0111D2, 0x01E889, 0x01E888, 0x01E88D, 0x0111D3,
+ 0x0111AC, 0x0111AD, 0x01E898, 0x0111AE, 0x01E88A, 0x0111AF, 0x0111A8, 0x0111A9,
+ 0x0111AA, 0x0111AB, 0x0111A4, 0x0111A5, 0x01E8C3, 0x0111A6, 0x0111A7, 0x0111A0,
+ 0x0111A1, 0x0111A2, 0x01E88F, 0x0024ED, 0x0024EE, 0x0024EF, 0x0024EA, 0x0024EB,
+ 0x0111B0, 0x0111B1, 0x0111B2, 0x0024FC, 0x0024F1, 0x0024F2, 0x0024F3, 0x011183,
+ 0x01119C, 0x01119D, 0x01119E, 0x01119F, 0x011198, 0x01E88C, 0x01E8CA, 0x01E88E,
+ 0x011199, 0x01119A, 0x01119B, 0x011194, 0x011195, 0x011196, 0x011197, 0x011190,
+ 0x011191, 0x011192, 0x011193, 0x010E6C, 0x010E6D, 0x010E6E, 0x010E6F, 0x010E68,
+ 0x010E69, 0x010E6A, 0x010E6B, 0x010E64, 0x010E65, 0x010E66, 0x010E67, 0x010E60,
+ 0x010E61, 0x010E62, 0x010E63, 0x010E7C, 0x010E7D, 0x010E7E, 0x010E78, 0x010E79,
+ 0x010E7A, 0x010E7B, 0x010E74, 0x010E75, 0x010E76, 0x010E77, 0x010E70, 0x010E71,
+ 0x010E72, 0x010E73, 0x00248C, 0x00248D, 0x00248E, 0x00248F, 0x002488, 0x002489,
+ 0x00248A, 0x00248B, 0x002484, 0x002485, 0x002486, 0x002487, 0x002480, 0x002481,
+ 0x002482, 0x002483, 0x002498, 0x002499, 0x00249A, 0x00249B, 0x002494, 0x002495,
+ 0x002496, 0x002497, 0x002490, 0x002491, 0x002492, 0x002493, 0x010C48, 0x010C44,
+ 0x010C45, 0x010C46, 0x010C47, 0x010C40, 0x010C41, 0x010C42, 0x010C43, 0x010C2C,
+ 0x010C2D, 0x010C2E, 0x010C2F, 0x010C28, 0x010C29, 0x010C2A, 0x010C2B, 0x010C24,
+ 0x010C25, 0x010C26, 0x010C27, 0x010C20, 0x010C21, 0x010C22, 0x010C23, 0x010C3C,
+ 0x010C3D, 0x010C3E, 0x010C3F, 0x010C38, 0x010C39, 0x010C3A, 0x010C3B, 0x010C34,
+ 0x010C35, 0x010C36, 0x010C37, 0x010C30, 0x010C31, 0x010C32, 0x010C33, 0x010C0C,
+ 0x010C0D, 0x010C0E, 0x010C0F, 0x010C08, 0x010C09, 0x010C0A, 0x010C0B, 0x010C04,
+ 0x010C05, 0x010C06, 0x010C07, 0x010C00, 0x010C01, 0x010C02, 0x010C03, 0x010C1C,
+ 0x010C1D, 0x010C1E, 0x010C1F, 0x010C18, 0x010C19, 0x010C1A, 0x010C1B, 0x010C14,
+ 0x010C15, 0x010C16, 0x010C17, 0x010C10, 0x010C11, 0x010C12, 0x010C13, 0x010CEC,
+ 0x010CED, 0x010CEE, 0x010CEF, 0x010CE8, 0x010CE9, 0x010CEA, 0x010CEB, 0x010CE4,
+ 0x010CE5, 0x010CE6, 0x010CE7, 0x010CE0, 0x010CE1, 0x010CE2, 0x010CE3, 0x010CFC,
+ 0x010CFD, 0x010CFE, 0x010CFF, 0x010CFA, 0x010CFB, 0x010CF0, 0x010CF1, 0x010CF2,
+ 0x010CCC, 0x010CCD, 0x010CCE, 0x010CCF, 0x010CC8, 0x010CC9, 0x010CCA, 0x010CCB,
+ 0x010CC4, 0x010CC5, 0x010CC6, 0x010CC7, 0x010CC0, 0x010CC1, 0x010CC2, 0x010CC3,
+ 0x010CDC, 0x010CDD, 0x010CDE, 0x010CDF, 0x010CD8, 0x010CD9, 0x010CDA, 0x010CDB,
+ 0x010CD4, 0x010CD5, 0x010CD6, 0x010CD7, 0x010CD0, 0x010CD1, 0x010CD2, 0x010CD3,
+ 0x010CAC, 0x010CAD, 0x010CAE, 0x010CAF, 0x010CA8, 0x010CA9, 0x010CAA, 0x010CAB,
+ 0x010CA4, 0x010CA5, 0x010CA6, 0x010CA7, 0x010CA0, 0x010CA1, 0x010CA2, 0x010CA3,
+ 0x010CB0, 0x010CB1, 0x010CB2, 0x010C8C, 0x010C8D, 0x010C8E, 0x010C8F, 0x010C88,
+ 0x010C89, 0x010C8A, 0x010C8B, 0x010C84, 0x010C85, 0x010C86, 0x010C87, 0x010C80,
+ 0x010C81, 0x010C82, 0x010C83, 0x010C9C, 0x010C9D, 0x010C9E, 0x010C9F, 0x010C98,
+ 0x010C99, 0x010C9A, 0x010C9B, 0x010C94, 0x010C95, 0x010C96, 0x010C97, 0x010C90,
+ 0x010C91, 0x010C92, 0x010C93, 0x002078, 0x002079, 0x002074, 0x002075, 0x002076,
+ 0x002077, 0x002070, 0x010A6C, 0x010A6D, 0x010A6E, 0x010A6F, 0x010A68, 0x010A69,
+ 0x010A6A, 0x010A6B, 0x010A64, 0x010A65, 0x010A66, 0x010A67, 0x010A60, 0x010A61,
+ 0x010A62, 0x010A63, 0x010A7C, 0x010A7D, 0x010A7E, 0x010A78, 0x010A79, 0x010A7A,
+ 0x010A7B, 0x010A74, 0x010A75, 0x010A76, 0x010A77, 0x010A70, 0x010A71, 0x010A72,
+ 0x010A73, 0x010A44, 0x010A45, 0x010A46, 0x010A47, 0x010A40, 0x010A41, 0x010A42,
+ 0x010A43, 0x002088, 0x002089, 0x002084, 0x002085, 0x002086, 0x002087, 0x002080,
+ 0x002081, 0x002082, 0x002083, 0x010A2C, 0x010A2D, 0x010A2E, 0x010A2F, 0x010A28,
+ 0x010A29, 0x010A2A, 0x010A2B, 0x010A24, 0x010A25, 0x010A26, 0x010A27, 0x010A20,
+ 0x010A21, 0x010A22, 0x00216D, 0x00216E, 0x00216F, 0x002168, 0x002169, 0x00216A,
+ 0x00216B, 0x002164, 0x002165, 0x002166, 0x002167, 0x002160, 0x00217D, 0x00217E,
+ 0x00217F, 0x002178, 0x002179, 0x00217A, 0x00217B, 0x002174, 0x002175, 0x002176,
+ 0x002177, 0x002170, 0x002172, 0x002173, 0x010A1C, 0x010A1E, 0x002149, 0x010A19,
+ 0x010A1A, 0x010A1B, 0x002145, 0x010A17, 0x010A10, 0x010A11, 0x010A12, 0x002159,
+ 0x00215A, 0x00215B, 0x002156, 0x002157, 0x002150, 0x00212D, 0x00212F, 0x002128,
+ 0x00212A, 0x00212B, 0x002124, 0x002126, 0x00213C, 0x002139, 0x010AC9, 0x010ACA,
+ 0x010ADF, 0x010AD8, 0x010ADB, 0x010AD4, 0x010AD5, 0x010AD7, 0x010AD0, 0x010AD2,
+ 0x00211D, 0x002119, 0x00211A, 0x00211B, 0x002115, 0x002110, 0x002111, 0x002112,
+ 0x002113, 0x010A8C, 0x010A8D, 0x010A8E, 0x010A8F, 0x010A88, 0x010A89, 0x010A8A,
+ 0x010A8B, 0x010A84, 0x010A85, 0x010A86, 0x010A87, 0x010A80, 0x010A81, 0x010A82,
+ 0x010A83, 0x010A9C, 0x010A9D, 0x010A9E, 0x010A9F, 0x010A98, 0x010A99, 0x010A9A,
+ 0x010A9B, 0x010A94, 0x010A95, 0x010A96, 0x010A97, 0x010A90, 0x010A91, 0x010A92,
+ 0x010A93, 0x010B6C, 0x010B6D, 0x010B6E, 0x010B6F, 0x010B68, 0x010B69, 0x010B6A,
+ 0x010B6B, 0x010B64, 0x010B65, 0x010B66, 0x010B67, 0x010B60, 0x010B61, 0x010B62,
+ 0x010B63, 0x010B7C, 0x010B7D, 0x010B7E, 0x010B7F, 0x010B78, 0x010B79, 0x010B7A,
+ 0x010B7B, 0x010B70, 0x010B71, 0x010B72, 0x010B4C, 0x010B4D, 0x010B4E, 0x010B4F,
+ 0x010B48, 0x010B49, 0x010B4A, 0x010B4B, 0x010B44, 0x010B45, 0x010B46, 0x010B47,
+ 0x010B40, 0x010B41, 0x010B42, 0x010B43, 0x010B5C, 0x010B5D, 0x010B5E, 0x010B59,
+ 0x010B5A, 0x002187, 0x002180, 0x010B53, 0x010B2C, 0x010B2D, 0x010B2E, 0x010B2F,
+ 0x010B28, 0x010B29, 0x010B2A, 0x010B2B, 0x010B24, 0x010B25, 0x010B26, 0x010B27,
+ 0x010B20, 0x010B21, 0x010B22, 0x001E6D, 0x001E6E, 0x001E6F, 0x001E68, 0x001E69,
+ 0x001E6A, 0x001E6B, 0x001E64, 0x001E67, 0x001E60, 0x001E5D, 0x001E5E, 0x001E5F,
+ 0x001E58, 0x001E59, 0x001E5A, 0x001E5B, 0x001E54, 0x001E55, 0x001E56, 0x001E57,
+ 0x001E50, 0x001E51, 0x001E52, 0x001E53, 0x001E2C, 0x001E2D, 0x001E2E, 0x001E2F,
+ 0x001E28, 0x001E29, 0x001E2A, 0x001E2B, 0x001E24, 0x001E25, 0x001E26, 0x001E27,
+ 0x001E20, 0x001E21, 0x001E22, 0x001E23, 0x001E3C, 0x001E3D, 0x001E3E, 0x001E3F,
+ 0x001E38, 0x001E39, 0x001E3A, 0x001E3B, 0x001E34, 0x001E35, 0x001E36, 0x001E37,
+ 0x001E30, 0x001E31, 0x001E32, 0x001E33, 0x001E0C, 0x001E0D, 0x001E0E, 0x001E0F,
+ 0x001E08, 0x001E09, 0x001E0A, 0x001E0B, 0x001E04, 0x001E05, 0x001E06, 0x001E07,
+ 0x001E00, 0x001E01, 0x001E02, 0x001E03, 0x001E1C, 0x001E19, 0x001E15, 0x001E16,
+ 0x001E17, 0x001E10, 0x001E11, 0x001E12, 0x001E13, 0x001EEC, 0x001EED, 0x001EEE,
+ 0x001EEF, 0x001EE8, 0x001EE9, 0x001EEA, 0x001EEB, 0x001EE4, 0x001EE5, 0x001EE6,
+ 0x001EE7, 0x001EE0, 0x001EE1, 0x001EE2, 0x001EE3, 0x01E8CC, 0x01E8CD, 0x01E8CE,
+ 0x001EFC, 0x001ECD, 0x001ECE, 0x001ECF, 0x001EC8, 0x001EC9, 0x001ECA, 0x001ECB,
+ 0x001EC4, 0x001EC5, 0x001EC6, 0x001EC7, 0x001EC0, 0x001EC3, 0x001EDC, 0x001EA9,
+ 0x001EA0, 0x001E87, 0x001E80, 0x001F6E, 0x001F6F, 0x001F6A, 0x001F6B, 0x001F64,
+ 0x001F67, 0x01080D, 0x01080E, 0x001F7A, 0x001F77, 0x001F70, 0x01081D, 0x01081E,
+ 0x010815, 0x010816, 0x010813, 0x0108ED, 0x0108EF, 0x0108E9, 0x001F29, 0x001F2A,
+ 0x001F2B, 0x001F27, 0x001F20, 0x001F3C, 0x001F3D, 0x001F3E, 0x001F3F, 0x001F38,
+ 0x001F39, 0x001F3A, 0x001F3B, 0x001F34, 0x001F35, 0x001F36, 0x001F37, 0x001F30,
+ 0x001F31, 0x001F32, 0x001F33, 0x001F0C, 0x001F0D, 0x001F0E, 0x001F0F, 0x001F08,
+ 0x001F09, 0x001F0A, 0x001F0B, 0x001F04, 0x001F05, 0x001F06, 0x001F07, 0x001F00,
+ 0x001F01, 0x001F02, 0x001F03, 0x001F1C, 0x0108AD, 0x0108AE, 0x001F15, 0x001F11,
+ 0x001F12, 0x001F13, 0x001FEC, 0x001FE8, 0x001FE9, 0x001FEA, 0x001FEB, 0x001FE4,
+ 0x001FE5, 0x001FE6, 0x001FE7, 0x001FE0, 0x001FE1, 0x001FE2, 0x001FE3, 0x001FFC,
+ 0x01088C, 0x01088D, 0x01088E, 0x010884, 0x00FA88, 0x00FA8E, 0x010887, 0x010880,
+ 0x01089C, 0x00FA9C, 0x01089D, 0x00FA89, 0x00FA98, 0x00FA8B, 0x00FA8A, 0x00FA9E,
+ 0x01089E, 0x00FA8D, 0x001FC8, 0x010894, 0x010897, 0x010890, 0x010893, 0x001FD8,
+ 0x001FD9, 0x001FDA, 0x001FDB, 0x001FD6, 0x001FD7, 0x001FD0, 0x001FD1, 0x001FD2,
+ 0x001FD3, 0x001FAC, 0x001FAD, 0x001FAE, 0x001FAF, 0x001FA8, 0x001FA9, 0x001FAA,
+ 0x001FAB, 0x001FA4, 0x001FA5, 0x001FA6, 0x001FA7, 0x001FA0, 0x001FA1, 0x001FA2,
+ 0x001FA3, 0x001FBC, 0x001FBE, 0x001FB8, 0x001FB9, 0x001FBA, 0x001FBB, 0x001FB4,
+ 0x001FB6, 0x001FB7, 0x001FB0, 0x001FB1, 0x001FB2, 0x001FB3, 0x001F8C, 0x001F8D,
+ 0x001F8E, 0x001F8F, 0x001F88, 0x001F89, 0x001F8A, 0x001F8B, 0x001F84, 0x001F85,
+ 0x001F86, 0x001F87, 0x001F80, 0x001F81, 0x001F82, 0x001F83, 0x001F9C, 0x001C6D,
+ 0x001C6E, 0x001C6F, 0x001C68, 0x001C6B, 0x001C64, 0x010933, 0x01090C, 0x01090D,
+ 0x01090E, 0x01090F, 0x010908, 0x010909, 0x01090A, 0x010903, 0x001C4D, 0x001C4E,
+ 0x001C4F, 0x001C48, 0x010919, 0x01091A, 0x0109E3, 0x0109FC, 0x0109FD, 0x0109FE,
+ 0x0109FF, 0x0109F8, 0x0109F9, 0x0109FA, 0x0109FB, 0x0109F4, 0x0109F5, 0x0109F6,
+ 0x0109F3, 0x0109CC, 0x0109CD, 0x0109CE, 0x0109CF, 0x0109C8, 0x0109C9, 0x0109CA,
+ 0x0109CB, 0x0109C4, 0x0109C5, 0x0109C6, 0x0109C7, 0x0109C0, 0x0109C1, 0x0109C2,
+ 0x001C01, 0x001C02, 0x0109BC, 0x0109BF, 0x001CE9, 0x001CEA, 0x001CEB, 0x0109B4,
+ 0x0109B5, 0x0109B6, 0x0109B7, 0x0109B0, 0x0109B1, 0x0109B2, 0x0109B3, 0x01098C,
+ 0x01098D, 0x01098E, 0x01098F, 0x010988, 0x010989, 0x01098A, 0x01098B, 0x010986,
+ 0x010981, 0x010982, 0x010983, 0x01099C, 0x01099D, 0x01099E, 0x01099F, 0x010998,
+ 0x010999, 0x01099A, 0x01099B, 0x010994, 0x010995, 0x010996, 0x010997, 0x010990,
+ 0x010991, 0x010992, 0x010993, 0x01066C, 0x01066D, 0x01066E, 0x01066F, 0x010668,
+ 0x010669, 0x01066A, 0x01066B, 0x010664, 0x010665, 0x010666, 0x010667, 0x010660,
+ 0x010661, 0x010662, 0x010663, 0x01067C, 0x01067D, 0x01067E, 0x01067F, 0x010678,
+ 0x010679, 0x01067A, 0x01067B, 0x010674, 0x010675, 0x010676, 0x010677, 0x010670,
+ 0x010671, 0x010672, 0x010673, 0x01064C, 0x01064D, 0x01064E, 0x01064F, 0x010648,
+ 0x010649, 0x01064A, 0x01064B, 0x010644, 0x010645, 0x010646, 0x010647, 0x010640,
+ 0x010641, 0x010642, 0x010643, 0x01065C, 0x01065D, 0x01065E, 0x010658, 0x010659,
+ 0x01065A, 0x010653, 0x01062C, 0x01062D, 0x01062E, 0x01062F, 0x010628, 0x010629,
+ 0x01062A, 0x01062B, 0x010624, 0x010625, 0x010626, 0x010627, 0x010620, 0x010621,
+ 0x010622, 0x01063F, 0x010638, 0x010639, 0x01063B, 0x010634, 0x010635, 0x010636,
+ 0x010637, 0x010630, 0x010631, 0x010632, 0x01060F, 0x010603, 0x01061C, 0x01061D,
+ 0x01061E, 0x01061F, 0x010618, 0x010619, 0x01061A, 0x01061B, 0x010614, 0x010615,
+ 0x010616, 0x010617, 0x010610, 0x010611, 0x010612, 0x010613, 0x0106EC, 0x0106ED,
+ 0x0106EE, 0x0106EF, 0x0106E8, 0x0106E9, 0x0106EA, 0x0106EB, 0x0106E4, 0x0106E5,
+ 0x0106E6, 0x0106E7, 0x0106E0, 0x0106E1, 0x0106E2, 0x0106E3, 0x0106FC, 0x0106FD,
+ 0x0106FE, 0x0106F3, 0x0106CC, 0x0106CD, 0x0106CE, 0x0106CF, 0x0106C8, 0x0106C9,
+ 0x0106CA, 0x0106CB, 0x0106C4, 0x0106C5, 0x0106C6, 0x0106C7, 0x0106C0, 0x0106C1,
+ 0x0106C2, 0x0106A3, 0x0106BC, 0x0106BD, 0x0106BE, 0x0106BF, 0x0106B8, 0x0106B9,
+ 0x0106BA, 0x0106BB, 0x0106B4, 0x0106B5, 0x0106B6, 0x0106B7, 0x0106B0, 0x0106B1,
+ 0x0106B2, 0x0106B3, 0x01068C, 0x01068D, 0x01068E, 0x01068F, 0x010688, 0x010689,
+ 0x01068A, 0x01068B, 0x010684, 0x010685, 0x010686, 0x010687, 0x010680, 0x010681,
+ 0x010682, 0x010683, 0x01069C, 0x01069D, 0x01069E, 0x01069F, 0x010698, 0x010699,
+ 0x01069A, 0x01069B, 0x010694, 0x010695, 0x010696, 0x010697, 0x010690, 0x010691,
+ 0x010692, 0x010693, 0x010764, 0x010765, 0x010766, 0x010767, 0x010760, 0x010761,
+ 0x010762, 0x010763, 0x01074C, 0x01074D, 0x01074E, 0x01074F, 0x010748, 0x010749,
+ 0x01074A, 0x01074B, 0x010744, 0x010745, 0x010746, 0x010747, 0x010740, 0x010741,
+ 0x010742, 0x001D8D, 0x001D8E, 0x001D8F, 0x001D88, 0x001D89, 0x001D8A, 0x001D8B,
+ 0x001D84, 0x001D87, 0x001D80, 0x010753, 0x01072C, 0x01072D, 0x01072E, 0x01072A,
+ 0x010723, 0x010734, 0x010735, 0x010736, 0x010730, 0x010731, 0x010732, 0x010733,
+ 0x01070C, 0x01070D, 0x01070E, 0x01070F, 0x010708, 0x010709, 0x01070A, 0x01070B,
+ 0x010704, 0x010705, 0x010706, 0x010707, 0x010700, 0x010701, 0x010702, 0x010713,
+ 0x001A54, 0x001A50, 0x001A51, 0x001A52, 0x001A53, 0x001A2C, 0x001A2D, 0x001A2E,
+ 0x001A2F, 0x001A28, 0x001A29, 0x001A2A, 0x001A2B, 0x001A24, 0x001A25, 0x001A26,
+ 0x001A27, 0x001A20, 0x001A21, 0x001A22, 0x001A23, 0x001A3C, 0x001A3D, 0x001A3E,
+ 0x001A3F, 0x001A38, 0x001A39, 0x001A3A, 0x001A3B, 0x001A34, 0x001A35, 0x001A36,
+ 0x001A37, 0x001A30, 0x001A31, 0x001A32, 0x001A33, 0x001A0C, 0x001A0D, 0x001A0E,
+ 0x001A0F, 0x001A08, 0x001A09, 0x001A0A, 0x001A0B, 0x001A04, 0x001A05, 0x001A06,
+ 0x001A07, 0x001A00, 0x001A01, 0x001A02, 0x001A03, 0x001A14, 0x001A15, 0x001A16,
+ 0x001A10, 0x001A11, 0x001A12, 0x001A13, 0x01046C, 0x01046D, 0x01046E, 0x01046F,
+ 0x010468, 0x010469, 0x01046A, 0x01046B, 0x010464, 0x010465, 0x010466, 0x010467,
+ 0x010460, 0x010461, 0x010462, 0x010463, 0x01047C, 0x01047E, 0x01047F, 0x010478,
+ 0x01044D, 0x01044E, 0x01044F, 0x010448, 0x010449, 0x01044A, 0x01044B, 0x010444,
+ 0x010445, 0x010446, 0x010447, 0x010440, 0x010441, 0x010442, 0x010443, 0x01045C,
+ 0x01045D, 0x01045E, 0x010459, 0x01045A, 0x010453, 0x01042C, 0x01042D, 0x01042E,
+ 0x010429, 0x01042A, 0x010423, 0x01043C, 0x01043D, 0x01043E, 0x01043F, 0x010438,
+ 0x010439, 0x01043A, 0x01043B, 0x010434, 0x010435, 0x010436, 0x010437, 0x010430,
+ 0x010431, 0x010432, 0x010433, 0x01040C, 0x01040D, 0x01040E, 0x01040F, 0x010408,
+ 0x010409, 0x01040A, 0x01040B, 0x010404, 0x010405, 0x010406, 0x010407, 0x010400,
+ 0x010401, 0x010402, 0x010403, 0x01041C, 0x01041D, 0x01041E, 0x01041B, 0x010417,
+ 0x010410, 0x010411, 0x010412, 0x010413, 0x0104EC, 0x0104ED, 0x0104EE, 0x0104E9,
+ 0x0104EA, 0x001B2D, 0x001B2E, 0x001B2F, 0x001B28, 0x0104F3, 0x0104CC, 0x0104CD,
+ 0x0104CE, 0x0104CF, 0x0104C8, 0x0104C9, 0x0104CA, 0x0104CB, 0x0104C4, 0x0104C5,
+ 0x0104C6, 0x001B05, 0x001B07, 0x0104D1, 0x001B1D, 0x001B1F, 0x0104BC, 0x0104BD,
+ 0x0104B9, 0x0104B5, 0x0104B6, 0x01048C, 0x01048D, 0x01048F, 0x010489, 0x01048B,
+ 0x010486, 0x010487, 0x010481, 0x001BDD, 0x001BDE, 0x001BDF, 0x001BD8, 0x001BD9,
+ 0x001BDA, 0x001BD4, 0x01EE0E, 0x01EE0F, 0x01EE08, 0x01EE09, 0x01EE0A, 0x01EE0B,
+ 0x01EE05, 0x01EE07, 0x01EE00, 0x01EE01, 0x010557, 0x010550, 0x010551, 0x001B9D,
+ 0x001B9E, 0x001B9F, 0x001B98, 0x001B99, 0x001B9A, 0x001B9B, 0x001B94, 0x010533,
+ 0x01050C, 0x01050D, 0x01050E, 0x01050F, 0x010508, 0x010509, 0x01050A, 0x00185E,
+ 0x00185F, 0x001858, 0x001859, 0x001824, 0x00183E, 0x00183F, 0x001838, 0x001839,
+ 0x01EE92, 0x01EE93, 0x001818, 0x001819, 0x001814, 0x001815, 0x001816, 0x001817,
+ 0x001810, 0x001811, 0x001812, 0x001813, 0x0018EC, 0x0018ED, 0x0018EE, 0x0018EF,
+ 0x0018E8, 0x0018E9, 0x0018EA, 0x0018EB, 0x0018E4, 0x0018E5, 0x0018E6, 0x0018E7,
+ 0x0018E0, 0x0018E1, 0x0018E2, 0x0018E3, 0x0018F4, 0x0018F5, 0x0018F0, 0x0018F1,
+ 0x0018F2, 0x0018F3, 0x0018CC, 0x0018CD, 0x0018CE, 0x0018CF, 0x0018C8, 0x0018C9,
+ 0x0018CA, 0x0018CB, 0x0018C4, 0x0018C5, 0x0018C6, 0x0018C7, 0x0018C0, 0x0018C1,
+ 0x0018C2, 0x0018C3, 0x0018DC, 0x0018DD, 0x0018DE, 0x0018DF, 0x0018D8, 0x0018D9,
+ 0x0018DA, 0x0018DB, 0x0018D4, 0x0018D5, 0x0018D6, 0x0018D7, 0x0018D0, 0x0018D1,
+ 0x0018D2, 0x0018D3, 0x0018A8, 0x0018AA, 0x0018A4, 0x0018A5, 0x0018A6, 0x0018A7,
+ 0x0018A0, 0x0018A1, 0x0018A2, 0x0018A3, 0x0018BC, 0x0018BD, 0x0018BE, 0x0018BF,
+ 0x0018B8, 0x01D608, 0x0018B9, 0x0018BA, 0x0018BB, 0x01D60C, 0x01D60D, 0x01D60E,
+ 0x0018B4, 0x0018B5, 0x0018B6, 0x0018B7, 0x0018B0, 0x0018B1, 0x0018B2, 0x0018B3,
+ 0x00188C, 0x00188D, 0x00188E, 0x00188F, 0x001888, 0x001889, 0x00188A, 0x00188B,
+ 0x001884, 0x01D620, 0x01D621, 0x01D622, 0x01D623, 0x01D624, 0x01D625, 0x01D626,
+ 0x01D627, 0x01D628, 0x01D629, 0x01D62A, 0x01D62B, 0x01D62C, 0x01D62D, 0x01D62E,
+ 0x01D62F, 0x01D630, 0x01D631, 0x01D632, 0x001887, 0x01D634, 0x01D635, 0x01D636,
+ 0x01D637, 0x01D638, 0x01D639, 0x01D63A, 0x01D63B, 0x01D63C, 0x01D63D, 0x01D63E,
+ 0x01D63F, 0x01D640, 0x01D641, 0x01D642, 0x01D643, 0x01D644, 0x01D645, 0x01D646,
+ 0x01D647, 0x01D648, 0x01D649, 0x01D64A, 0x01D64B, 0x01D64C, 0x01D64D, 0x01D64E,
+ 0x01D64F, 0x01D650, 0x01D651, 0x01D652, 0x01D653, 0x001880, 0x01D655, 0x01D656,
+ 0x01D657, 0x01D658, 0x01D659, 0x01D65A, 0x001881, 0x01D65C, 0x01D65D, 0x01D65E,
+ 0x01D65F, 0x001882, 0x001883, 0x00189C, 0x00189D, 0x00189E, 0x00189F, 0x001898,
+ 0x001899, 0x00189A, 0x00189B, 0x001894, 0x001895, 0x001896, 0x001897, 0x001890,
+ 0x001891, 0x001892, 0x001893, 0x01D672, 0x01D673, 0x00196C, 0x00196D, 0x001968,
+ 0x001969, 0x00196A, 0x00196B, 0x001964, 0x001965, 0x001966, 0x001967, 0x001960,
+ 0x001961, 0x001962, 0x001963, 0x001974, 0x001970, 0x001971, 0x001972, 0x001973,
+ 0x00194C, 0x00194D, 0x00194E, 0x00194F, 0x001948, 0x001949, 0x00194A, 0x00194B,
+ 0x001946, 0x001947, 0x00195C, 0x001951, 0x0102E3, 0x0102F8, 0x0102F9, 0x0102FA,
+ 0x0102FB, 0x0102F4, 0x0102F5, 0x0102F6, 0x0102F7, 0x0102F0, 0x0102F1, 0x0102F2,
+ 0x0102F3, 0x0102CC, 0x0102CD, 0x0102CE, 0x0102CF, 0x0102C8, 0x0102C9, 0x0102CA,
+ 0x0102CB, 0x0102C4, 0x0102C5, 0x0102C6, 0x0102C7, 0x0102C0, 0x0102C1, 0x0102C2,
+ 0x00190D, 0x00190E, 0x00190F, 0x001908, 0x001909, 0x00190A, 0x00190B, 0x001904,
+ 0x001905, 0x001906, 0x001907, 0x001900, 0x001902, 0x001903, 0x00191C, 0x0102AE,
+ 0x0102A3, 0x0102BC, 0x0102BD, 0x0102BE, 0x0102BF, 0x0102B8, 0x0102B9, 0x0102BA,
+ 0x0102BB, 0x0102B4, 0x0102B5, 0x0102B6, 0x0102B7, 0x0102B0, 0x0102B1, 0x0102B2,
+ 0x0102B3, 0x01028C, 0x01028D, 0x01028E, 0x01028F, 0x010288, 0x010289, 0x01028A,
+ 0x01028B, 0x010284, 0x010285, 0x010286, 0x010287, 0x010280, 0x010281, 0x010282,
+ 0x010283, 0x01029C, 0x0019C8, 0x010299, 0x01029A, 0x010293, 0x01036C, 0x01036D,
+ 0x01036E, 0x01036A, 0x010363, 0x0019A8, 0x0019A9, 0x0019AA, 0x0019AB, 0x0019A4,
+ 0x0019A7, 0x0019A0, 0x00FC40, 0x0019BD, 0x0019BE, 0x0019BF, 0x0019B8, 0x00FC45,
+ 0x0019B4, 0x00199D, 0x001999, 0x00199A, 0x00199B, 0x001994, 0x001995, 0x001996,
+ 0x00FC4E, 0x001997, 0x001990, 0x01033C, 0x01033D, 0x00165D, 0x00165E, 0x00165F,
+ 0x001658, 0x001659, 0x00165A, 0x00165B, 0x001654, 0x001655, 0x001656, 0x001657,
+ 0x001650, 0x001651, 0x001652, 0x001653, 0x00162C, 0x00162D, 0x00162E, 0x00162F,
+ 0x00FC66, 0x001628, 0x001629, 0x00162A, 0x00162B, 0x001624, 0x001625, 0x001626,
+ 0x001627, 0x001620, 0x001621, 0x001622, 0x001623, 0x00163C, 0x001635, 0x001636,
+ 0x001637, 0x001630, 0x00160D, 0x00160E, 0x00160F, 0x001608, 0x001609, 0x00160A,
+ 0x00160B, 0x001604, 0x001607, 0x001600, 0x001601, 0x0103A3, 0x0103BC, 0x0103BA,
+ 0x0103B3, 0x01038C, 0x01038D, 0x01038E, 0x010388, 0x010389, 0x01038A, 0x0016CF,
+ 0x0016C8, 0x0016DD, 0x0016DE, 0x0016DF, 0x0016D8, 0x0016D9, 0x0016DA, 0x0016DB,
+ 0x0016D4, 0x0016D5, 0x0016D6, 0x0016D7, 0x0016D0, 0x0016D1, 0x0016D2, 0x0016D3,
+ 0x0016AC, 0x0016AD, 0x0016AE, 0x0016AF, 0x0016A8, 0x0016A9, 0x0016AA, 0x0016AB,
+ 0x0016A4, 0x0016A5, 0x0016A6, 0x0016A7, 0x0016A0, 0x0016A1, 0x0016A2, 0x0016A3,
+ 0x0016BC, 0x0016BF, 0x0016B8, 0x00168F, 0x001688, 0x010057, 0x010053, 0x01002C,
+ 0x01002D, 0x01002E, 0x01002A, 0x001690, 0x01003C, 0x00176F, 0x001764, 0x010033,
+ 0x01000D, 0x01000E, 0x01000F, 0x010008, 0x010009, 0x01000A, 0x01000B, 0x010004,
+ 0x010005, 0x010006, 0x010000, 0x010001, 0x010002, 0x010013, 0x0100EC, 0x0100ED,
+ 0x0100EE, 0x0100EF, 0x0100E8, 0x0100E9, 0x0100EA, 0x0100EB, 0x0100E4, 0x0100E5,
+ 0x0100E6, 0x0100E1, 0x0100E2, 0x00172D, 0x00172E, 0x00172F, 0x001728, 0x001724,
+ 0x0100F3, 0x0100CC, 0x0100CD, 0x0100CE, 0x0100CF, 0x0100C8, 0x0100C9, 0x0100CA,
+ 0x0100CB, 0x0100C4, 0x0100C5, 0x0100C6, 0x0100C1, 0x0100C2, 0x0100DC, 0x0100D3,
+ 0x0100AC, 0x0100AD, 0x0100AE, 0x0100AF, 0x0100A8, 0x0100A9, 0x0100AA, 0x0100AB,
+ 0x0100A4, 0x0100A5, 0x0100A6, 0x0100A1, 0x0100A2, 0x0100A3, 0x0100BC, 0x0100BD,
+ 0x0100BE, 0x0100B9, 0x0100BA, 0x0100B3, 0x01008C, 0x01008D, 0x01008E, 0x010089,
+ 0x01008A, 0x010083, 0x01009C, 0x01009D, 0x01009E, 0x01009F, 0x010098, 0x010099,
+ 0x01009A, 0x01009B, 0x010094, 0x010095, 0x010096, 0x010097, 0x010090, 0x010091,
+ 0x010092, 0x01016C, 0x01016D, 0x01016E, 0x01016F, 0x010168, 0x010169, 0x01016A,
+ 0x01016B, 0x010164, 0x010165, 0x010166, 0x010167, 0x010160, 0x010161, 0x010162,
+ 0x0017AD, 0x0017AE, 0x0017AF, 0x0017A8, 0x0017AA, 0x0017AB, 0x0017A4, 0x010173,
+ 0x01014C, 0x01014D, 0x01014E, 0x01014F, 0x010148, 0x010149, 0x01014A, 0x01014B,
+ 0x010144, 0x010145, 0x010146, 0x00146D, 0x00146E, 0x00146F, 0x001468, 0x001469,
+ 0x00146A, 0x00146B, 0x001464, 0x001465, 0x001466, 0x001467, 0x001460, 0x001475,
+ 0x001476, 0x001477, 0x00F95A, 0x001471, 0x001472, 0x001473, 0x00144C, 0x00145D,
+ 0x00F959, 0x01D401, 0x01D400, 0x01D403, 0x01D402, 0x01D405, 0x01D404, 0x01D407,
+ 0x01D406, 0x01D409, 0x01D408, 0x01D40B, 0x01D40A, 0x01D40D, 0x01D40C, 0x01D40F,
+ 0x01D40E, 0x01D411, 0x01D410, 0x01D413, 0x01D412, 0x01D415, 0x01D414, 0x01D417,
+ 0x01D416, 0x01D419, 0x01D418, 0x01D41B, 0x01D41A, 0x01D41D, 0x01D41C, 0x01D41F,
+ 0x01D41E, 0x01D421, 0x01D420, 0x01D423, 0x01D422, 0x01D425, 0x01D424, 0x01D427,
+ 0x01D426, 0x01D429, 0x01D428, 0x01D42B, 0x01D42A, 0x01D42D, 0x01D42C, 0x01D42F,
+ 0x01D42E, 0x01D431, 0x01D430, 0x01D433, 0x01D432, 0x01D435, 0x01D434, 0x01D437,
+ 0x01D436, 0x01D439, 0x01D438, 0x01D43B, 0x01D43A, 0x01D43D, 0x01D43C, 0x01D43F,
+ 0x01D43E, 0x01D441, 0x01D440, 0x01D443, 0x01D442, 0x01D445, 0x01D444, 0x01D447,
+ 0x01D446, 0x01D449, 0x01D448, 0x01D44B, 0x01D44A, 0x01D44D, 0x01D44C, 0x01D44F,
+ 0x01D44E, 0x01D451, 0x01D450, 0x01D453, 0x01D452, 0x01D6D8, 0x01D454, 0x01D457,
+ 0x01D456, 0x01D459, 0x01D458, 0x01D45B, 0x01D45A, 0x01D45D, 0x01D45C, 0x01D45F,
+ 0x01D45E, 0x01D461, 0x01D460, 0x01D463, 0x01D462, 0x01D465, 0x01D464, 0x01D467,
+ 0x01D466, 0x01D469, 0x01D468, 0x01D46B, 0x01D46A, 0x01D46D, 0x01D46C, 0x01D46F,
+ 0x01D46E, 0x01D471, 0x01D470, 0x01D473, 0x01D472, 0x01D475, 0x01D474, 0x01D477,
+ 0x01D476, 0x01D479, 0x01D478, 0x01D47B, 0x01D47A, 0x01D47D, 0x01D47C, 0x01D47F,
+ 0x01D47E, 0x00145E, 0x00145F, 0x001458, 0x001459, 0x00145A, 0x00145B, 0x001454,
+ 0x001455, 0x001456, 0x001457, 0x001450, 0x001451, 0x001452, 0x001453, 0x00142C,
+ 0x00142D, 0x00142E, 0x00142F, 0x001428, 0x001429, 0x00142A, 0x00142B, 0x001424,
+ 0x001425, 0x001426, 0x001427, 0x001420, 0x001421, 0x001422, 0x001423, 0x00143C,
+ 0x00143D, 0x00143E, 0x00143F, 0x001438, 0x001439, 0x00143A, 0x00143B, 0x001434,
+ 0x001435, 0x001436, 0x001437, 0x001430, 0x001431, 0x001432, 0x001433, 0x00140C,
+ 0x00140D, 0x00140E, 0x00140F, 0x001408, 0x001409, 0x00140A, 0x00140B, 0x001404,
+ 0x001405, 0x001406, 0x001407, 0x001401, 0x001402, 0x001403, 0x00141C, 0x00141D,
+ 0x00141E, 0x00141F, 0x001418, 0x001419, 0x00141A, 0x00141B, 0x001414, 0x001415,
+ 0x001416, 0x001417, 0x00FF18, 0x001410, 0x001411, 0x001412, 0x001413, 0x0014EC,
+ 0x0014ED, 0x0014EE, 0x0014EF, 0x0014E8, 0x0014E9, 0x0014EA, 0x0014EB, 0x0014E4,
+ 0x0014E5, 0x0014E6, 0x0014E7, 0x0014E0, 0x0014E1, 0x0014E2, 0x0014E3, 0x0014FC,
+ 0x0014FD, 0x01D4E1, 0x01D4E0, 0x01D4E3, 0x01D4E2, 0x01D4E5, 0x01D4E4, 0x01D4E7,
+ 0x01D4E6, 0x01D4E9, 0x01D4E8, 0x01D4EB, 0x01D4EA, 0x01D4ED, 0x01D4EC, 0x01D4EF,
+ 0x01D4EE, 0x01D4F1, 0x01D4F0, 0x0014FE, 0x0014FF, 0x01D4F5, 0x01D4F4, 0x01D4F7,
+ 0x01D4F6, 0x01D4F9, 0x01D4F8, 0x01D4FB, 0x01D4FA, 0x01D4FD, 0x01D4FC, 0x01D4FF,
+ 0x01D4FE, 0x0014F8, 0x0014F9, 0x0014FA, 0x0014F5, 0x0014F6, 0x00FBDC, 0x00FBDD,
+ 0x0014F7, 0x0014F0, 0x0014F1, 0x00FBD9, 0x0014F2, 0x0014F3, 0x0014CC, 0x00FBDE,
+ 0x00FBDF, 0x0014CD, 0x0014CE, 0x0014CF, 0x01D612, 0x0014C8, 0x0014C9, 0x00FBE4,
+ 0x00FBE5, 0x00FBE6, 0x00FBE8, 0x0014CA, 0x0014CB, 0x00FBEF, 0x00FBFC, 0x00FBFD,
+ 0x0014C4, 0x00FBEB, 0x00FBF7, 0x00FBF0, 0x00FBF1, 0x00FBF2, 0x0014C5, 0x00FBF4,
+ 0x0014C6, 0x00FBF6, 0x0014C7, 0x00FBF9, 0x00FBFA, 0x00FBFF, 0x00FBF8, 0x00FBF5,
+ 0x00FBFE, 0x0014C0, 0x0014C1, 0x0014C2, 0x0014C3, 0x01D611, 0x0014DC, 0x0014DD,
+ 0x0014DE, 0x0014DF, 0x0014D8, 0x0014D9, 0x0014DA, 0x0014DB, 0x0014D4, 0x01D610,
+ 0x0014D5, 0x0014D6, 0x00FF90, 0x0014D7, 0x0014D0, 0x0014D1, 0x0014D2, 0x00FF95,
+ 0x00FF96, 0x01D6E8, 0x01D6EC, 0x00FBD8, 0x0014D3, 0x01D74C, 0x01D74D, 0x01D74E,
+ 0x01D6ED, 0x0014AC, 0x0014A6, 0x00FBE7, 0x0014BD, 0x00FBE1, 0x0014BE, 0x0014BF,
+ 0x0014B8, 0x0014B9, 0x0014BA, 0x0014BB, 0x0014B4, 0x0014B5, 0x0014B6, 0x0014B7,
+ 0x0014B0, 0x0014B1, 0x01D6E4, };
+
+/* indexes */
+const uint16_t NU_DUCET_VALUES_I[] = {
+ 0x0781, 0x07BC, 0x0209, 0x075B, 0x07FE, 0x0802, 0x0760, 0x0765, 0x032D, 0x032C,
+ 0x032F, 0x0335, 0x0866, 0x0830, 0x03E7, 0x03E9, 0x0767, 0x0A68, 0x081A, 0x07FF,
+ 0x07F6, 0x07FB, 0x07F9, 0x07FD, 0x07C3, 0x07D9, 0x0749, 0x0763, 0x0767, 0x076C,
+ 0x0801, 0x080D, 0x0851, 0x0828, 0x0554, 0x0669, 0x076B, 0x06D2, 0x07EA, 0x0803,
+ 0x05BC, 0x0A7D, 0x07E2, 0x0856, 0x0300, 0x0897, 0x01DF, 0x05E9, 0x084C, 0x072F,
+ 0x0485, 0x04AB, 0x0510, 0x053D, 0x078C, 0x0792, 0x07C0, 0x07C6, 0x0578, 0x09C6,
+ 0x0688, 0x069C, 0x07F1, 0x076F, 0x023F, 0x023E, 0x0245, 0x024F, 0x024D, 0x024B,
+ 0x025D, 0x02C2, 0x061A, 0x065F, 0x0288, 0x0776, 0x0694, 0x05DD, 0x0600, 0x063C,
+ 0x02E8, 0x0493, 0x06B2, 0x0319, 0x04C1, 0x04CA, 0x04C7, 0x0313, 0x04D0, 0x05FB,
+ 0x05FA, 0x05FD, 0x03E5, 0x06A7, 0x06F5, 0x06AB, 0x089A, 0x0A44, 0x0767, 0x076C,
+ 0x0867, 0x089A, 0x0278, 0x07C2, 0x07D8, 0x07ED, 0x07AA, 0x07F8, 0x07FC, 0x07F2,
+ 0x04BF, 0x04BE, 0x0886, 0x0778, 0x01C9, 0x056A, 0x03BD, 0x083C, 0x0A62, 0x01A2,
+ 0x0198, 0x02D0, 0x067F, 0x02AE, 0x03CC, 0x036D, 0x0862, 0x0859, 0x082A, 0x07C5,
+ 0x0656, 0x0676, 0x0270, 0x0276, 0x086B, 0x027A, 0x04FA, 0x0269, 0x07F3, 0x02CC,
+ 0x026A, 0x0814, 0x06F6, 0x05A7, 0x04E9, 0x04A1, 0x02FA, 0x04E8, 0x04F4, 0x03CB,
+ 0x0766, 0x04F1, 0x061D, 0x06B4, 0x0622, 0x061F, 0x0761, 0x04EB, 0x0694, 0x061C,
+ 0x067F, 0x023D, 0x03FD, 0x0414, 0x07EE, 0x078D, 0x0760, 0x0765, 0x07BF, 0x076D,
+ 0x0783, 0x078F, 0x0832, 0x07C5, 0x085E, 0x083D, 0x0863, 0x022A, 0x0424, 0x044C,
+ 0x01F5, 0x061A, 0x0215, 0x021F, 0x0551, 0x0234, 0x082A, 0x0867, 0x086B, 0x065F,
+ 0x082F, 0x083B, 0x02F0, 0x032B, 0x07FE, 0x0802, 0x05DE, 0x061B, 0x0660, 0x0680,
+ 0x0832, 0x083D, 0x0292, 0x047F, 0x0769, 0x076E, 0x0816, 0x07F0, 0x0552, 0x0800,
+ 0x01DB, 0x05AD, 0x081B, 0x07F7, 0x0539, 0x07E7, 0x044D, 0x01BD, 0x0511, 0x056B,
+ 0x01C3, 0x01C1, 0x01F2, 0x080C, 0x02A9, 0x05CD, 0x02C7, 0x055D, 0x0827, 0x0816,
+ 0x036E, 0x038A, 0x03E4, 0x03E3, 0x040F, 0x0425, 0x03B3, 0x0885, 0x049D, 0x04E7,
+ 0x0534, 0x054E, 0x0819, 0x082F, 0x0850, 0x0861, 0x059A, 0x07ED, 0x06B3, 0x06A6,
+ 0x01F0, 0x0695, 0x081B, 0x0861, 0x06D3, 0x068D, 0x0253, 0x027E, 0x0240, 0x026B,
+ 0x0252, 0x027D, 0x02BE, 0x02C8, 0x02BF, 0x02C9, 0x02C1, 0x02CB, 0x02C0, 0x02CA,
+ 0x02DF, 0x02F1, 0x02E2, 0x02F4, 0x031F, 0x033B, 0x0312, 0x032E, 0x031B, 0x0337,
+ 0x031E, 0x033A, 0x0318, 0x0334, 0x0381, 0x038D, 0x0380, 0x038C, 0x0383, 0x038F,
+ 0x0384, 0x0390, 0x03A8, 0x03B4, 0x03AD, 0x03B9, 0x03D3, 0x03EB, 0x03B2, 0x03EE,
+ 0x03CE, 0x03E6, 0x03D4, 0x03ED, 0x03FC, 0x03EC, 0x03DF, 0x03F8, 0x040B, 0x0410,
+ 0x041F, 0x0428, 0x044E, 0x055C, 0x0450, 0x043D, 0x044F, 0x043F, 0x0456, 0x043E,
+ 0x0451, 0x0445, 0x049E, 0x0440, 0x04A3, 0x0490, 0x04A0, 0x0495, 0x0719, 0x0492,
+ 0x056A, 0x04BB, 0x04D4, 0x04FE, 0x04C0, 0x04EA, 0x04C9, 0x04F3, 0x04E4, 0x050E,
+ 0x055E, 0x056C, 0x0561, 0x056F, 0x055F, 0x056D, 0x059B, 0x05AE, 0x059D, 0x05B0,
+ 0x05A1, 0x05B4, 0x059E, 0x05B1, 0x05D1, 0x05E1, 0x05CE, 0x05DF, 0x05EB, 0x05EC,
+ 0x0606, 0x0628, 0x0609, 0x062B, 0x05FC, 0x061E, 0x0389, 0x049C, 0x0605, 0x0627,
+ 0x0608, 0x062A, 0x0679, 0x0683, 0x06A9, 0x06B6, 0x06D4, 0x06B7, 0x06D7, 0x06CA,
+ 0x047E, 0x06CD, 0x05A8, 0x06CC, 0x02B8, 0x02B0, 0x02B9, 0x02BA, 0x0714, 0x0715,
+ 0x02D8, 0x051F, 0x0306, 0x02D7, 0x030B, 0x0308, 0x06D1, 0x030A, 0x0353, 0x0350,
+ 0x037A, 0x0356, 0x039E, 0x0379, 0x03BF, 0x03A4, 0x0404, 0x0408, 0x0430, 0x0431,
+ 0x0476, 0x0463, 0x04B0, 0x064F, 0x052B, 0x04B1, 0x04DA, 0x0504, 0x03A5, 0x03A6,
+ 0x0545, 0x0546, 0x0711, 0x057B, 0x05C6, 0x0710, 0x05F0, 0x05C9, 0x05F1, 0x05F2,
+ 0x0630, 0x05F4, 0x0654, 0x060E, 0x06C3, 0x066F, 0x06DE, 0x06C2, 0x06ED, 0x06DD,
+ 0x06F0, 0x06F1, 0x0709, 0x06F3, 0x0712, 0x0713, 0x06FB, 0x05DA, 0x0728, 0x0727,
+ 0x072A, 0x0729, 0x02FD, 0x02FF, 0x045A, 0x02EC, 0x0448, 0x0459, 0x04A9, 0x04AA,
+ 0x0275, 0x049B, 0x03E8, 0x024A, 0x04F0, 0x03D0, 0x0620, 0x04C6, 0x0626, 0x05FE,
+ 0x0623, 0x0604, 0x0625, 0x0601, 0x0624, 0x0603, 0x034F, 0x0602, 0x024E, 0x0279,
+ 0x0251, 0x027C, 0x025F, 0x028A, 0x039A, 0x039B, 0x0382, 0x038E, 0x041E, 0x0427,
+ 0x04D2, 0x04FC, 0x04D3, 0x04FD, 0x06EC, 0x06EE, 0x02FE, 0x040C, 0x02EB, 0x02FC,
+ 0x037F, 0x038B, 0x0861, 0x03C0, 0x0491, 0x049F, 0x024C, 0x0277, 0x025E, 0x0289,
+ 0x04D1, 0x04FB, 0x07AA, 0x07C2, 0x07BF, 0x078F, 0x0783, 0x07C5, 0x07FC, 0x07F0,
+ 0x07F4, 0x081B, 0x07AA, 0x07C2, 0x07D8, 0x07FA, 0x0850, 0x0863, 0x085E, 0x0779,
+ 0x0749, 0x089A, 0x0861, 0x0763, 0x07ED, 0x076C, 0x078D, 0x0819, 0x0760, 0x0767,
+ 0x07ED, 0x076E, 0x082F, 0x0827, 0x083B, 0x082F, 0x0861, 0x0850, 0x0869, 0x0865,
+ 0x0816, 0x0885, 0x07C2, 0x0779, 0x0861, 0x07ED, 0x0819, 0x0827, 0x0765, 0x0760,
+ 0x076E, 0x0769, 0x078F, 0x0783, 0x07C5, 0x07BF, 0x07F0, 0x07E7, 0x07FA, 0x07F4,
+ 0x0802, 0x07FE, 0x081B, 0x0816, 0x07C5, 0x082A, 0x083D, 0x0832, 0x0863, 0x085E,
+ 0x086B, 0x0867, 0x07E7, 0x089A, 0x0763, 0x0749, 0x076C, 0x0767, 0x078D, 0x0779,
+ 0x07C2, 0x07AA, 0x07ED, 0x07D8, 0x07F8, 0x07F2, 0x0800, 0x07FC, 0x0819, 0x080C,
+ 0x082F, 0x0827, 0x083B, 0x082F, 0x0861, 0x0850, 0x0869, 0x0865, 0x07ED, 0x0885,
+ 0x07C2, 0x0779, 0x0861, 0x07ED, 0x0819, 0x0827, 0x0785, 0x0787, 0x0779, 0x07C2,
+ 0x01B1, 0x019D, 0x01E4, 0x01CF, 0x020E, 0x01FA, 0x0224, 0x021A, 0x0239, 0x022F,
+ 0x01B1, 0x019D, 0x01E4, 0x01CF, 0x020E, 0x01FA, 0x0224, 0x021A, 0x07F2, 0x07F8,
+ 0x076C, 0x0800, 0x080C, 0x0819, 0x0827, 0x082F, 0x07FE, 0x0802, 0x0850, 0x0861,
+ 0x082A, 0x07C5, 0x0832, 0x083D, 0x07FC, 0x083B, 0x0224, 0x021A, 0x0827, 0x082F,
+ 0x0760, 0x0765, 0x0769, 0x076E, 0x0783, 0x078F, 0x07BF, 0x07C5, 0x07E7, 0x07F0,
+ 0x05B7, 0x05A4, 0x0280, 0x0255, 0x0281, 0x0256, 0x033F, 0x0323, 0x0340, 0x0324,
+ 0x03F0, 0x03D7, 0x03F1, 0x03D8, 0x0502, 0x04D8, 0x0503, 0x04D9, 0x04F9, 0x04CF,
+ 0x06BA, 0x06AE, 0x0471, 0x04B7, 0x05F5, 0x0413, 0x02EA, 0x0550, 0x0295, 0x02D3,
+ 0x06C8, 0x06C7, 0x03B5, 0x03A9, 0x06E5, 0x0718, 0x0717, 0x02B1, 0x0645, 0x0675,
+ 0x034B, 0x034A, 0x0417, 0x0416, 0x055B, 0x055A, 0x0581, 0x0580, 0x04F8, 0x04CE,
+ 0x029A, 0x029C, 0x02A0, 0x02B7, 0x051E, 0x02D9, 0x0305, 0x0307, 0x0359, 0x0352,
+ 0x035A, 0x0355, 0x035B, 0x035F, 0x0360, 0x041A, 0x04B2, 0x030C, 0x0532, 0x0531,
+ 0x06E2, 0x06E1, 0x027B, 0x0250, 0x0311, 0x031C, 0x04F2, 0x04C8, 0x03CD, 0x0338,
+ 0x03CF, 0x03D1, 0x0652, 0x0489, 0x04AF, 0x04B6, 0x04AC, 0x052A, 0x06C9, 0x052E,
+ 0x04F7, 0x04CD, 0x0585, 0x0587, 0x02D2, 0x0464, 0x05EE, 0x05C1, 0x103C, 0x0DB8,
+ 0x0D7D, 0x0C6F, 0x1037, 0x0E0C, 0x1014, 0x1027, 0x0A7A, 0x0A79, 0x103E, 0x103F,
+ 0x0A54, 0x0A5D, 0x0A61, 0x0A67, 0x1040, 0x1021, 0x0CD1, 0x0D9B, 0x0CD6, 0x0CD3,
+ 0x1024, 0x0CD8, 0x1030, 0x0EB6, 0x0D9C, 0x0DB5, 0x0CD5, 0x102E, 0x1015, 0x0EB5,
+ 0x0A1A, 0x0A19, 0x0A5A, 0x0A58, 0x0A6B, 0x0764, 0x0A6E, 0x0A6D, 0x0A76, 0x0A75,
+ 0x0A72, 0x0A71, 0x0A55, 0x0A5F, 0x0A7C, 0x0A7B, 0x1039, 0x1034, 0x1033, 0x1038,
+ 0x0A83, 0x0A20, 0x0A6C, 0x1035, 0x0A08, 0x0A07, 0x0A22, 0x103D, 0x0768, 0x0A1F,
+ 0x0A1C, 0x0A1B, 0x09DC, 0x09E2, 0x09E9, 0x09F6, 0x0A09, 0x0A0B, 0x0473, 0x0A2D,
+ 0x0403, 0x0407, 0x03FE, 0x064E, 0x046B, 0x046F, 0x06C1, 0x06C0, 0x0A7E, 0x0A21,
+ 0x0A47, 0x0A84, 0x0A81, 0x0A82, 0x0A23, 0x0A43, 0x0989, 0x09AA, 0x0A4B, 0x0A50,
+ 0x098E, 0x0978, 0x09F7, 0x0A41, 0x02A3, 0x0396, 0x0399, 0x03A3, 0x02DE, 0x030F,
+ 0x0363, 0x037E, 0x03A7, 0x03CA, 0x0467, 0x041C, 0x078E, 0x048F, 0x040A, 0x04BD,
+ 0x0589, 0x039D, 0x03C2, 0x07AB, 0x074A, 0x058A, 0x07D4, 0x0515, 0x054C, 0x0583,
+ 0x0362, 0x064A, 0x043C, 0x0478, 0x058D, 0x058F, 0x0DAA, 0x0DB0, 0x0E41, 0x0DAB,
+ 0x0DA7, 0x0E06, 0x0E07, 0x0DAF, 0x0D99, 0x0DAE, 0x3242, 0x3243, 0x3245, 0x3250,
+ 0x3246, 0x3247, 0x2FAE, 0x3244, 0x324A, 0x324B, 0x3249, 0x324D, 0x324E, 0x324F,
+ 0x324C, 0x3251, 0x3252, 0x3253, 0x3254, 0x3260, 0x3256, 0x3257, 0x3258, 0x3259,
+ 0x325A, 0x325B, 0x2F27, 0x325D, 0x325E, 0x325F, 0x325C, 0x3261, 0x0CCC, 0x0D50,
+ 0x2FB0, 0x3286, 0x0F99, 0x0F9A, 0x0DAC, 0x3248, 0x0D88, 0x0D8B, 0x3265, 0x0DB7,
+ 0x0DAD, 0x0E08, 0x0E0B, 0x2FAF, 0x3272, 0x3273, 0x3275, 0x3280, 0x3276, 0x3277,
+ 0x3274, 0x3279, 0x327A, 0x327B, 0x3278, 0x327D, 0x0D4A, 0x327F, 0x327C, 0x3281,
+ 0x0D7B, 0x0D7C, 0x102B, 0x3287, 0x1032, 0x103B, 0x2FA8, 0x0D7E, 0x2FB1, 0x2FAA,
+ 0x0D45, 0x0D78, 0x2F90, 0x0E0D, 0x0D7A, 0x0FD9, 0x0E0E, 0x0EF5, 0x0E0A, 0x0E8B,
+ 0x0E8C, 0x0E8D, 0x0FDA, 0x0F64, 0x0F10, 0x0F13, 0x0C70, 0x1013, 0x0F65, 0x0F98,
+ 0x0F44, 0x0DB6, 0x327E, 0x3270, 0x0F14, 0x2FA5, 0x3266, 0x3267, 0x2FA7, 0x2FA4,
+ 0x326A, 0x326B, 0x326C, 0x326D, 0x326F, 0x2FA3, 0x3271, 0x2FA2, 0x101E, 0x2FA9,
+ 0x101D, 0x2FAB, 0x2FB6, 0x2FA6, 0x2FB8, 0x2FB9, 0x0988, 0x0933, 0x0931, 0x092E,
+ 0x2FBE, 0x2FBF, 0x2FAC, 0x2FAD, 0x2F4A, 0x2FC0, 0x2F4E, 0x095D, 0x2F47, 0x2F46,
+ 0x0932, 0x2F4F, 0x2F5A, 0x2F5B, 0x2F4D, 0x2F4B, 0x2F50, 0x2F51, 0x2F60, 0x2F61,
+ 0x2F53, 0x2F52, 0x2F55, 0x2F54, 0x2F5C, 0x2F5D, 0x2F59, 0x2F58, 0x2F44, 0x2F45,
+ 0x2F5E, 0x2F5F, 0x2F56, 0x2F57, 0x2F42, 0x2F43, 0x2F66, 0x2F62, 0x2F65, 0x2F64,
+ 0x2F67, 0x2F63, 0x2F48, 0x2F49, 0x0936, 0x2F6A, 0x2F6D, 0x2F6C, 0x2FB7, 0x095E,
+ 0x2F71, 0x2F70, 0x2F76, 0x2F72, 0x2F75, 0x2F74, 0x2F77, 0x2F73, 0x2F79, 0x2F78,
+ 0x2F7E, 0x2F7A, 0x2F7D, 0x2F7C, 0x2F7F, 0x2F7B, 0x2F81, 0x2F80, 0x3082, 0x3083,
+ 0x30A4, 0x30A5, 0x2F85, 0x30A3, 0x30A8, 0x30A9, 0x30A2, 0x308A, 0x2F86, 0x2F8C,
+ 0x2F87, 0x2F9F, 0x0937, 0x0991, 0x2F82, 0x2F83, 0x2F84, 0x2FC1, 0x2F97, 0x2F96,
+ 0x2F88, 0x2F89, 0x2F9B, 0x2F9A, 0x2F9D, 0x2F9C, 0x30BE, 0x2F9E, 0x2FA1, 0x2FA0,
+ 0x30C0, 0x30C1, 0x092F, 0x2FBA, 0x2F8B, 0x2FB3, 0x0992, 0x2F8A, 0x2FB4, 0x2F8D,
+ 0x2FB5, 0x30BC, 0x30BA, 0x2FB2, 0x2F68, 0x2F69, 0x30B2, 0x30B3, 0x30B4, 0x30B5,
+ 0x30B6, 0x30B7, 0x2F91, 0x30BB, 0x2FBB, 0x2F8E, 0x30B8, 0x30BD, 0x30BF, 0x2FBD,
+ 0x2F8F, 0x30B9, 0x2FEA, 0x2FEB, 0x2FEC, 0x2FED, 0x3046, 0x3047, 0x2FE6, 0x2FE7,
+ 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, 0x3051, 0x2FEE, 0x2FEF,
+ 0x303A, 0x303B, 0x3054, 0x3055, 0x2FD6, 0x2FD7, 0x2FDC, 0x2FDD, 0x2FDA, 0x2FDB,
+ 0x2FE0, 0x2FE1, 0x2FF0, 0x2FF1, 0x3042, 0x3043, 0x3044, 0x3045, 0x3066, 0x3067,
+ 0x3048, 0x3049, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070, 0x3071,
+ 0x3052, 0x3053, 0x3074, 0x3075, 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B,
+ 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, 0x3062, 0x3063, 0x3084, 0x3085,
+ 0x3086, 0x3087, 0x3088, 0x3089, 0x3015, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F,
+ 0x3090, 0x3091, 0x3092, 0x3093, 0x3094, 0x3095, 0x3096, 0x3097, 0x3098, 0x3099,
+ 0x309A, 0x309B, 0x309C, 0x309D, 0x309E, 0x309F, 0x30A0, 0x30A1, 0x3012, 0x3013,
+ 0x3014, 0x3065, 0x3006, 0x3037, 0x3019, 0x3064, 0x303D, 0x300C, 0x3018, 0x300D,
+ 0x3036, 0x3040, 0x303C, 0x3041, 0x3072, 0x3073, 0x3068, 0x3069, 0x3076, 0x3077,
+ 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080, 0x3081,
+ 0x0946, 0x0945, 0x09C9, 0x09C8, 0x093E, 0x093D, 0x09EF, 0x09EE, 0x09AF, 0x09AE,
+ 0x0966, 0x0965, 0x0974, 0x0973, 0x0A69, 0x0A6A, 0x2EED, 0x0B95, 0x0A89, 0x0A8A,
+ 0x099B, 0x099C, 0x09A8, 0x09A9, 0x09C2, 0x0A15, 0x09D6, 0x09D7, 0x09C3, 0x0A16,
+ 0x09BA, 0x09BB, 0x0959, 0x09A4, 0x09E6, 0x09E5, 0x095A, 0x09A5, 0x0B90, 0x0BA5,
+ 0x0B94, 0x0B92, 0x0BA3, 0x0B9D, 0x0B96, 0x0B99, 0x0BA1, 0x0B9F, 0x0B93, 0x0BAD,
+ 0x0BA9, 0x0BA7, 0x0B9B, 0x0BAB, 0x0BB1, 0x0BAF, 0x0BB5, 0x0BB3, 0x0BBD, 0x0BBB,
+ 0x0BC1, 0x0BBF, 0x0BC8, 0x0B97, 0x2ECC, 0x0BC7, 0x0BBC, 0x09DA, 0x0BC5, 0x0BC6,
+ 0x0BD6, 0x0BD4, 0x0BDA, 0x0BB0, 0x0BDE, 0x0BDC, 0x0BD8, 0x0BE0, 0x0BC3, 0x0BBE,
+ 0x0BC0, 0x0BC9, 0x0BCB, 0x0BCD, 0x0BD0, 0x0BD2, 0x0BC4, 0x2EDD, 0x0BC2, 0x0BCE,
+ 0x0A32, 0x0A31, 0x0B9C, 0x0B8F, 0x0C2C, 0x0C26, 0x091C, 0x0BD1, 0x0C23, 0x3025,
+ 0x3026, 0x3027, 0x3024, 0x0BAE, 0x302A, 0x302B, 0x302C, 0x302D, 0x302E, 0x302F,
+ 0x3030, 0x3031, 0x0BB4, 0x2ED4, 0x0BB2, 0x0B9A, 0x0A35, 0x0997, 0x0BD7, 0x0BD9,
+ 0x0BD3, 0x0BD5, 0x0BDF, 0x0B98, 0x0BDB, 0x0BDD, 0x303E, 0x0C61, 0x2EC3, 0x2EC4,
+ 0x0C1E, 0x0C21, 0x2EC7, 0x2EC8, 0x0968, 0x0967, 0x09A7, 0x09A6, 0x09B1, 0x09B0,
+ 0x09E1, 0x09E0, 0x2EC9, 0x2ECA, 0x099E, 0x099D, 0x2ED5, 0x2ED6, 0x2ED3, 0x2ED0,
+ 0x2ED8, 0x2ED9, 0x2ECD, 0x2ECB, 0x2EDC, 0x2ECE, 0x2EDE, 0x2EDF, 0x2ED1, 0x2ED2,
+ 0x2EEE, 0x2EEF, 0x2EF0, 0x2EF1, 0x2EE6, 0x2EE7, 0x2EE4, 0x2EE5, 0x2EFA, 0x2EFB,
+ 0x2EEC, 0x2EEB, 0x2EE9, 0x2ECF, 0x2F00, 0x2EEA, 0x2EF2, 0x2EF3, 0x2EF4, 0x2EF5,
+ 0x2EFC, 0x2F01, 0x2EF8, 0x2EF9, 0x0C00, 0x2F0B, 0x2EFD, 0x2EE3, 0x2EF6, 0x2EF7,
+ 0x2EFE, 0x2EFF, 0x2F04, 0x2F03, 0x0BA6, 0x2F05, 0x2F08, 0x2F02, 0x2F09, 0x0BFA,
+ 0x0C03, 0x0BF9, 0x2F0C, 0x2F0D, 0x2F06, 0x2F07, 0x2F1D, 0x2F11, 0x2F14, 0x2F15,
+ 0x2F12, 0x2F13, 0x2F18, 0x2F19, 0x0C0B, 0x0BAA, 0x0B91, 0x0BAC, 0x0BF3, 0x0BF6,
+ 0x0C09, 0x0C05, 0x0BFE, 0x0BA0, 0x0BA2, 0x0BA4, 0x0C11, 0x0B9E, 0x0C0E, 0x0C14,
+ 0x0BEC, 0x0BEF, 0x0C15, 0x0C1C, 0x0C12, 0x0C20, 0x0BB6, 0x0C19, 0x0BE1, 0x0BE8,
+ 0x0C17, 0x0BA8, 0x0BCA, 0x0BCC, 0x0BFB, 0x0BFD, 0x2EE2, 0x2EE8, 0x2F1A, 0x2F1B,
+ 0x2F1C, 0x2F1F, 0x2F16, 0x2F17, 0x2F20, 0x2F21, 0x108C, 0x3202, 0x108E, 0x108F,
+ 0x0D9D, 0x1090, 0x3208, 0x3209, 0x3226, 0x3227, 0x322F, 0x0F04, 0x30D7, 0x0DBC,
+ 0x0DA3, 0x0E43, 0x0D40, 0x30D3, 0x322B, 0x3230, 0x322E, 0x0E61, 0x322A, 0x30D2,
+ 0x10A8, 0x3231, 0x0DB3, 0x322C, 0x321E, 0x10A7, 0x10A9, 0x10AA, 0x0D76, 0x30DF,
+ 0x1099, 0x109B, 0x323E, 0x30D6, 0x3224, 0x3225, 0x109E, 0x0D77, 0x316D, 0x31F0,
+ 0x31EE, 0x0D8D, 0x30D5, 0x30CD, 0x30DD, 0x3236, 0x3240, 0x3241, 0x3237, 0x2F2E,
+ 0x09D2, 0x0A5E, 0x2F2D, 0x09CE, 0x0979, 0x09CB, 0x2F30, 0x2F31, 0x2F2C, 0x09D0,
+ 0x09BC, 0x2F22, 0x097D, 0x2F25, 0x10A5, 0x09FF, 0x2F2F, 0x1096, 0x2F0A, 0x321F,
+ 0x2F24, 0x2F29, 0x2F0E, 0x2F0F, 0x2F10, 0x2F2A, 0x109F, 0x3153, 0x102A, 0x0A60,
+ 0x323C, 0x108D, 0x2F40, 0x2F28, 0x097E, 0x097A, 0x096F, 0x2F3B, 0x2F1E, 0x2F3A,
+ 0x2F41, 0x09FA, 0x2F26, 0x2F2B, 0x0A0E, 0x0970, 0x09D1, 0x2F3E, 0x2F38, 0x2F23,
+ 0x0A10, 0x09D3, 0x0A30, 0x0A0D, 0x0939, 0x0A0F, 0x0A53, 0x0A51, 0x0935, 0x0934,
+ 0x2F34, 0x2F35, 0x2F36, 0x2F37, 0x09DB, 0x2F3C, 0x2F3F, 0x2F33, 0x0A57, 0x0A56,
+ 0x2F32, 0x0938, 0x2F3D, 0x2F39, 0x0980, 0x097F, 0x1029, 0x102F, 0x09DF, 0x09DE,
+ 0x3154, 0x3159, 0x3177, 0x317B, 0x0E29, 0x0E0F, 0x092B, 0x103A, 0x0948, 0x0947,
+ 0x0998, 0x0A14, 0x099A, 0x0999, 0x1036, 0x0961, 0x0995, 0x0A02, 0x0A03, 0x0A13,
+ 0x0A2A, 0x0A29, 0x09F0, 0x0A36, 0x09E8, 0x09E7, 0x09BF, 0x09BE, 0x0A88, 0x0A87,
+ 0x0996, 0x09C4, 0x09A0, 0x0956, 0x0A12, 0x0A11, 0x09C5, 0x0A00, 0x09D9, 0x09D8,
+ 0x0A3A, 0x0A39, 0x0D83, 0x0E45, 0x0A3E, 0x0A3D, 0x0A40, 0x0A3F, 0x0D79, 0x0DE0,
+ 0x0928, 0x098F, 0x091E, 0x3167, 0x093C, 0x094D, 0x316B, 0x09BD, 0x09C0, 0x09B4,
+ 0x09B5, 0x0CD4, 0x0A37, 0x0A8B, 0x091F, 0x094F, 0x0920, 0x091D, 0x0957, 0x094B,
+ 0x0924, 0x0922, 0x0926, 0x0925, 0x0923, 0x0921, 0x0962, 0x0960, 0x0958, 0x0955,
+ 0x0A8C, 0x101F, 0x102C, 0x1026, 0x0993, 0x09A3, 0x09A2, 0x09C1, 0x1025, 0x1023,
+ 0x0954, 0x0994, 0x1028, 0x0A38, 0x32B0, 0x32A6, 0x09FD, 0x09F8, 0x32AA, 0x32AE,
+ 0x32AD, 0x0A2E, 0x32AF, 0x32B1, 0x0A01, 0x32AC, 0x09FE, 0x09F9, 0x102D, 0x09F1,
+ 0x1020, 0x1022, 0x1069, 0x106A, 0x1065, 0x1068, 0x106D, 0x106F, 0x106C, 0x108B,
+ 0x106B, 0x1081, 0x31C3, 0x1076, 0x31D8, 0x31D9, 0x107F, 0x106E, 0x1084, 0x1082,
+ 0x3255, 0x1085, 0x1083, 0x1080, 0x1089, 0x1088, 0x1079, 0x1066, 0x1077, 0x31DA,
+ 0x31D4, 0x31D5, 0x1087, 0x1067, 0x31D6, 0x31D7, 0x31DC, 0x31DD, 0x31D3, 0x31DB,
+ 0x31E0, 0x31DF, 0x31E1, 0x31D2, 0x1075, 0x31C2, 0x1072, 0x1074, 0x1071, 0x107D,
+ 0x31C4, 0x31C5, 0x31E6, 0x31ED, 0x107A, 0x107B, 0x31F6, 0x31E7, 0x31FC, 0x31FD,
+ 0x1070, 0x31EB, 0x1078, 0x107C, 0x31EA, 0x31EF, 0x31C8, 0x31C9, 0x31F7, 0x10A0,
+ 0x1092, 0x1097, 0x31DE, 0x31CD, 0x31EC, 0x31F1, 0x1098, 0x01DF, 0x01C9, 0x01A2,
+ 0x021F, 0x109A, 0x0CD2, 0x0234, 0x1091, 0x1093, 0x10A1, 0x10A2, 0x10A3, 0x10A4,
+ 0x109C, 0x109D, 0x321B, 0x1095, 0x3214, 0x3215, 0x1094, 0x1031, 0x3155, 0x321D,
+ 0x3212, 0x3213, 0x3216, 0x3205, 0x3203, 0x3217, 0x3218, 0x3219, 0x0198, 0x0209,
+ 0x022A, 0x0215, 0x107E, 0x1073, 0x3204, 0x10A6, 0x323A, 0x323B, 0x01F5, 0x323D,
+ 0x10AB, 0x10AC, 0x3220, 0x32A7, 0x321C, 0x3221, 0x32AB, 0x321A, 0x3200, 0x3201,
+ 0x097C, 0x0950, 0x0942, 0x0930, 0x094E, 0x096C, 0x0983, 0x0984, 0x09AB, 0x0952,
+ 0x09C7, 0x09F5, 0x108A, 0x098A, 0x09FC, 0x0A42, 0x094A, 0x094C, 0x0941, 0x092D,
+ 0x096B, 0x0A80, 0x0981, 0x0982, 0x097B, 0x1086, 0x09F4, 0x0951, 0x09B3, 0x09B9,
+ 0x09CD, 0x09D5, 0x0A48, 0x09E4, 0x09EB, 0x09FB, 0x09DD, 0x0A0C, 0x0A24, 0x0A2F,
+ 0x086A, 0x0A0A, 0x07E5, 0x0A52, 0x0740, 0x0990, 0x07A3, 0x07CF, 0x09B2, 0x0927,
+ 0x0929, 0x092C, 0x091B, 0x0949, 0x0953, 0x095F, 0x0987, 0x093A, 0x098D, 0x099F,
+ 0x0977, 0x09B8, 0x09CA, 0x09D4, 0x0817, 0x0823, 0x0833, 0x082D, 0x083A, 0x083E,
+ 0x085F, 0x0864, 0x0868, 0x086D, 0x07D3, 0x084B, 0x080A, 0x0847, 0x087E, 0x07EF,
+ 0x0762, 0x07C1, 0x085B, 0x085C, 0x085D, 0x0860, 0x0818, 0x07EC, 0x0822, 0x0821,
+ 0x078B, 0x078A, 0x0786, 0x0784, 0x0820, 0x081F, 0x089D, 0x089C, 0x08E2, 0x08E1,
+ 0x08EC, 0x08EB, 0x08EE, 0x08ED, 0x08F4, 0x08F3, 0x0902, 0x0901, 0x0908, 0x0907,
+ 0x0910, 0x090F, 0x07EB, 0x0826, 0x082E, 0x07E8, 0x07C4, 0x0A7F, 0x0A4D, 0x08A1,
+ 0x08A0, 0x0831, 0x081E, 0x081D, 0x082C, 0x0837, 0x0835, 0x0839, 0x32F5, 0x32D0,
+ 0x32C6, 0x32C7, 0x32F7, 0x32F4, 0x32CA, 0x32CB, 0x32CC, 0x32CD, 0x3282, 0x3283,
+ 0x32A8, 0x32A9, 0x3344, 0x3345, 0x3288, 0x3289, 0x3342, 0x3343, 0x334D, 0x334C,
+ 0x328E, 0x3347, 0x3290, 0x3346, 0x32CE, 0x32CF, 0x0C47, 0x0C46, 0x0C48, 0x3348,
+ 0x0D55, 0x3349, 0x334A, 0x334B, 0x0ECD, 0x0F8F, 0x1016, 0x0EA7, 0x0C50, 0x105E,
+ 0x32A2, 0x32A3, 0x32A4, 0x32A5, 0x32FF, 0x3330, 0x3268, 0x3269, 0x0FDB, 0x32FB,
+ 0x0C4C, 0x105F, 0x32C0, 0x0F66, 0x32F8, 0x32F9, 0x32B2, 0x32B3, 0x32B4, 0x32B5,
+ 0x32B6, 0x32B7, 0x32F6, 0x32B9, 0x32BA, 0x32BB, 0x32BC, 0x32BD, 0x32BE, 0x32BF,
+ 0x32C1, 0x32B8, 0x334F, 0x3350, 0x3351, 0x0C4B, 0x3331, 0x0C45, 0x3355, 0x3356,
+ 0x329A, 0x332C, 0x0CD7, 0x0ECF, 0x329E, 0x329F, 0x32FC, 0x3301, 0x3292, 0x3293,
+ 0x3294, 0x3295, 0x3296, 0x3297, 0x3298, 0x3299, 0x3285, 0x329B, 0x329C, 0x329D,
+ 0x3352, 0x3284, 0x32A0, 0x32A1, 0x0F45, 0x0DB9, 0x0CD9, 0x3327, 0x3361, 0x3362,
+ 0x0C99, 0x328F, 0x3360, 0x3365, 0x328C, 0x328B, 0x335F, 0x328A, 0x3291, 0x3366,
+ 0x3370, 0x3372, 0x336F, 0x3371, 0x32FA, 0x3376, 0x32FD, 0x3375, 0x3326, 0x0C49,
+ 0x32E5, 0x0C56, 0x0C4A, 0x32FE, 0x0C4F, 0x332D, 0x2636, 0x25B6, 0x25B7, 0x0C4E,
+ 0x0C57, 0x2635, 0x0C52, 0x25B1, 0x25A9, 0x25A7, 0x25A2, 0x0C58, 0x25A3, 0x25A8,
+ 0x0C4D, 0x25A1, 0x0C54, 0x25B0, 0x25B3, 0x25B2, 0x25BC, 0x25BD, 0x4495, 0x4492,
+ 0x25B9, 0x25B8, 0x0C51, 0x25BA, 0x44A9, 0x0215, 0x25C0, 0x449D, 0x25DB, 0x25E1,
+ 0x25A0, 0x25DA, 0x0C53, 0x44AB, 0x44AA, 0x44AF, 0x44D1, 0x0C55, 0x2634, 0x449C,
+ 0x25DC, 0x2703, 0x25A5, 0x263B, 0x4499, 0x44BD, 0x25D4, 0x25D3, 0x0C5A, 0x25D9,
+ 0x25D6, 0x25D7, 0x0CDA, 0x0CDB, 0x0F02, 0x0FD7, 0x1060, 0x1045, 0x25C3, 0x25DD,
+ 0x25ED, 0x25EE, 0x25E2, 0x0EFC, 0x0DBA, 0x0E8E, 0x25EC, 0x2620, 0x138B, 0x44C7,
+ 0x1063, 0x105D, 0x4498, 0x260A, 0x260B, 0x021F, 0x2626, 0x105C, 0x25FB, 0x2704,
+ 0x44B4, 0x0C59, 0x1042, 0x25F4, 0x261C, 0x261D, 0x2624, 0x2625, 0x2622, 0x2623,
+ 0x2627, 0x25FA, 0x2610, 0x2616, 0x0E62, 0x2615, 0x260D, 0x260C, 0x2617, 0x0D2A,
+ 0x25C2, 0x25EB, 0x2614, 0x25F2, 0x2619, 0x25C1, 0x2612, 0x2611, 0x1041, 0x1062,
+ 0x0DBB, 0x1046, 0x25DE, 0x104B, 0x25C7, 0x25C8, 0x4580, 0x25DF, 0x1384, 0x263A,
+ 0x12BE, 0x12BF, 0x25E0, 0x25F1, 0x44CE, 0x44B5, 0x44D0, 0x44CF, 0x12B6, 0x12B7,
+ 0x12C1, 0x12C9, 0x12C3, 0x12C2, 0x12C0, 0x12CE, 0x12C5, 0x12CF, 0x25EA, 0x446D,
+ 0x4430, 0x1548, 0x12C4, 0x12BD, 0x12C7, 0x12BB, 0x44FE, 0x0C9A, 0x2B27, 0x4481,
+ 0x0D94, 0x0EAE, 0x12F5, 0x12F6, 0x0C98, 0x0C9C, 0x32E3, 0x262F, 0x32E4, 0x32E9,
+ 0x0E42, 0x2B23, 0x12F0, 0x12EF, 0x441A, 0x2B21, 0x32E2, 0x32E8, 0x1D57, 0x2B22,
+ 0x262E, 0x12F1, 0x4450, 0x12F2, 0x4451, 0x2B24, 0x2637, 0x2B1D, 0x2B18, 0x441D,
+ 0x44C0, 0x44C1, 0x4489, 0x43A2, 0x4500, 0x44F6, 0x12C6, 0x3300, 0x4501, 0x4511,
+ 0x12DA, 0x12DD, 0x12E7, 0x12ED, 0x446A, 0x2B1F, 0x2B1E, 0x44FF, 0x44E4, 0x2B28,
+ 0x12C8, 0x44E5, 0x44D7, 0x44E0, 0x44D6, 0x44E1, 0x44DE, 0x44DB, 0x44DA, 0x44DD,
+ 0x44DC, 0x44DF, 0x022A, 0x0215, 0x022A, 0x021F, 0x0234, 0x0234, 0x0215, 0x021F,
+ 0x2699, 0x2696, 0x260E, 0x260F, 0x01C9, 0x01DF, 0x269F, 0x26A0, 0x269A, 0x2609,
+ 0x2607, 0x4502, 0x269E, 0x269D, 0x269B, 0x12D8, 0x44F5, 0x12D2, 0x12DB, 0x12D3,
+ 0x12E9, 0x12FA, 0x1307, 0x1302, 0x1308, 0x1309, 0x1303, 0x1306, 0x1305, 0x1304,
+ 0x1319, 0x131B, 0x26B2, 0x1318, 0x26B4, 0x26B3, 0x26B6, 0x26B5, 0x26B8, 0x26B7,
+ 0x26BA, 0x26B9, 0x130E, 0x26BB, 0x1313, 0x130F, 0x1315, 0x1314, 0x1317, 0x1316,
+ 0x1310, 0x1311, 0x1312, 0x131A, 0x131F, 0x1321, 0x2601, 0x25FE, 0x130B, 0x131D,
+ 0x2679, 0x2661, 0x2689, 0x2662, 0x01A2, 0x0198, 0x130D, 0x01C9, 0x31A4, 0x31A5,
+ 0x021F, 0x0215, 0x132F, 0x1334, 0x1327, 0x2618, 0x131C, 0x1333, 0x1336, 0x1335,
+ 0x1331, 0x1324, 0x31A9, 0x1325, 0x1326, 0x1337, 0x130A, 0x130C, 0x0198, 0x01A2,
+ 0x01DF, 0x0037, 0x01F5, 0x01C9, 0x0209, 0x31A8, 0x3182, 0x3183, 0x1323, 0x1338,
+ 0x31A2, 0x31A3, 0x3189, 0x0038, 0x003B, 0x003C, 0x318E, 0x131E, 0x318F, 0x0039,
+ 0x1320, 0x132E, 0x3192, 0x3193, 0x3194, 0x31B4, 0x31B2, 0x31B3, 0x3198, 0x3199,
+ 0x1328, 0x132C, 0x1322, 0x31B8, 0x132D, 0x31B9, 0x3190, 0x3191, 0x0A25, 0x0A26,
+ 0x0943, 0x0944, 0x09AC, 0x1329, 0x09B6, 0x09B7, 0x09CC, 0x09CF, 0x31B5, 0x09CF,
+ 0x09CC, 0x09CF, 0x003A, 0x09CC, 0x1330, 0x1332, 0x132A, 0x132B, 0x31B6, 0x31B7,
+ 0x31C0, 0x0234, 0x31BA, 0x31BB, 0x133E, 0x31C1, 0x1343, 0x133F, 0x31BE, 0x31BF,
+ 0x0A34, 0x133C, 0x0A33, 0x31BD, 0x0A45, 0x31BC, 0x2707, 0x1340, 0x133D, 0x3163,
+ 0x3164, 0x1341, 0x134C, 0x134A, 0x134F, 0x134E, 0x1351, 0x1350, 0x1354, 0x1352,
+ 0x1356, 0x1355, 0x3152, 0x3158, 0x3162, 0x3195, 0x3168, 0x3169, 0x317E, 0x317F,
+ 0x3180, 0x135F, 0x318B, 0x3176, 0x1364, 0x1363, 0x1366, 0x1365, 0x1369, 0x1367,
+ 0x317C, 0x3181, 0x136A, 0x317D, 0x1368, 0x1347, 0x317A, 0x1346, 0x095B, 0x3165,
+ 0x26D8, 0x270A, 0x3186, 0x3187, 0x26D2, 0x09F3, 0x318A, 0x095C, 0x09CC, 0x318D,
+ 0x0A2B, 0x09CF, 0x0A2C, 0x318C, 0x0976, 0x0975, 0x2706, 0x1381, 0x26DA, 0x0A3C,
+ 0x26D9, 0x25AC, 0x0972, 0x0971, 0x26E8, 0x0A27, 0x26BD, 0x093F, 0x134B, 0x4471,
+ 0x1353, 0x134D, 0x26BF, 0x136B, 0x0A46, 0x1362, 0x2702, 0x1380, 0x2708, 0x26C3,
+ 0x13CB, 0x26C4, 0x01A2, 0x0198, 0x01DF, 0x01C9, 0x0209, 0x01F5, 0x021F, 0x3166,
+ 0x0234, 0x022A, 0x3170, 0x4467, 0x316C, 0x316A, 0x26BE, 0x2633, 0x316E, 0x316F,
+ 0x3171, 0x44BB, 0x26D5, 0x26D4, 0x26CF, 0x26D0, 0x26D1, 0x44B6, 0x26DB, 0x26DC,
+ 0x4466, 0x26D7, 0x136D, 0x26D6, 0x136F, 0x136E, 0x1371, 0x1370, 0x1373, 0x1372,
+ 0x1377, 0x1375, 0x1378, 0x05B9, 0x071B, 0x0569, 0x30D9, 0x44F7, 0x26EB, 0x30D4,
+ 0x26B1, 0x01C9, 0x44B3, 0x26EC, 0x25F6, 0x2681, 0x0577, 0x01DF, 0x0474, 0x44B2,
+ 0x137B, 0x2700, 0x137A, 0x063B, 0x05D8, 0x2613, 0x0619, 0x26FF, 0x050D, 0x1391,
+ 0x0475, 0x03C3, 0x1395, 0x1394, 0x1397, 0x1396, 0x003F, 0x1398, 0x139F, 0x1399,
+ 0x05A6, 0x0040, 0x139C, 0x139B, 0x05E7, 0x035C, 0x30DC, 0x25FD, 0x137F, 0x028C,
+ 0x02DD, 0x30DB, 0x0262, 0x0261, 0x30C4, 0x30C5, 0x070B, 0x1383, 0x03FF, 0x30D8,
+ 0x0290, 0x071A, 0x0209, 0x052C, 0x26E2, 0x06EA, 0x26E5, 0x06F9, 0x13BC, 0x136C,
+ 0x065E, 0x26E1, 0x1393, 0x26E6, 0x0439, 0x0668, 0x30E0, 0x30E1, 0x26FD, 0x14BA,
+ 0x13BE, 0x4457, 0x022A, 0x441C, 0x26F4, 0x06FA, 0x30DA, 0x052D, 0x26F3, 0x01F5,
+ 0x0A5B, 0x0400, 0x01DF, 0x01C9, 0x0650, 0x0706, 0x021F, 0x0215, 0x0234, 0x022A,
+ 0x06F7, 0x048D, 0x06FD, 0x054B, 0x003E, 0x0042, 0x0704, 0x06FE, 0x0705, 0x0703,
+ 0x0041, 0x446C, 0x1379, 0x139E, 0x0366, 0x003D, 0x0707, 0x06E9, 0x02FB, 0x2705,
+ 0x037D, 0x0708, 0x13CE, 0x137E, 0x13B3, 0x0394, 0x13B2, 0x01DF, 0x13AE, 0x13CC,
+ 0x13B7, 0x13CD, 0x13AD, 0x025C, 0x03C1, 0x13B0, 0x02D6, 0x13AC, 0x13B1, 0x26BC,
+ 0x13B4, 0x26FE, 0x13B5, 0x13AF, 0x43AF, 0x328D, 0x1559, 0x1541, 0x13BF, 0x153B,
+ 0x139A, 0x13A2, 0x13A3, 0x43A4, 0x43A5, 0x43B0, 0x13BB, 0x3263, 0x4513, 0x4547,
+ 0x0209, 0x43B1, 0x4395, 0x452F, 0x13B8, 0x43A9, 0x13B9, 0x43A3, 0x0375, 0x43B6,
+ 0x43F6, 0x43B4, 0x43B2, 0x43B3, 0x43B7, 0x43BA, 0x43B8, 0x43FA, 0x43B9, 0x43BC,
+ 0x43BD, 0x43BB, 0x13C9, 0x13AB, 0x43A8, 0x43AA, 0x43CD, 0x43A6, 0x04E3, 0x43A7,
+ 0x13A4, 0x13A5, 0x43FE, 0x049A, 0x43AE, 0x13A9, 0x13C5, 0x13C8, 0x13C6, 0x13C7,
+ 0x31B0, 0x4397, 0x31B1, 0x326E, 0x13C4, 0x4393, 0x4394, 0x4398, 0x4392, 0x0376,
+ 0x13B6, 0x0287, 0x43DF, 0x43FC, 0x13BD, 0x13BA, 0x13CA, 0x13C3, 0x43DB, 0x2709,
+ 0x4396, 0x04A8, 0x0963, 0x4409, 0x13C0, 0x13C1, 0x13C2, 0x270B, 0x13D0, 0x13CF,
+ 0x43D6, 0x270C, 0x26EE, 0x3264, 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x31AF, 0x13D5,
+ 0x31AC, 0x31AE, 0x43DA, 0x31A7, 0x31A6, 0x31AA, 0x3262, 0x31AB, 0x43CA, 0x43CB,
+ 0x43C6, 0x43CC, 0x31AD, 0x43C7, 0x43FB, 0x43FD, 0x13EB, 0x1464, 0x456D, 0x138C,
+ 0x43F7, 0x2017, 0x152A, 0x137D, 0x1526, 0x1388, 0x441F, 0x1524, 0x4428, 0x4416,
+ 0x1386, 0x4417, 0x441B, 0x44A2, 0x4421, 0x137C, 0x13E9, 0x442B, 0x4431, 0x4420,
+ 0x442D, 0x4425, 0x4429, 0x4415, 0x13EC, 0x4426, 0x452C, 0x1382, 0x4424, 0x442E,
+ 0x13EA, 0x4423, 0x441E, 0x4427, 0x442F, 0x4522, 0x4548, 0x13F5, 0x444D, 0x4521,
+ 0x4448, 0x13F9, 0x4414, 0x4444, 0x1392, 0x13FA, 0x4537, 0x1387, 0x13D6, 0x1523,
+ 0x211D, 0x022A, 0x4443, 0x4445, 0x0234, 0x4449, 0x4413, 0x01C9, 0x4418, 0x4419,
+ 0x442A, 0x4412, 0x1C95, 0x021F, 0x4442, 0x4447, 0x1D6E, 0x442C, 0x4472, 0x4550,
+ 0x4478, 0x1C98, 0x152D, 0x4479, 0x447A, 0x447B, 0x447D, 0x0215, 0x1525, 0x1C75,
+ 0x447C, 0x1529, 0x01F5, 0x0049, 0x1C80, 0x0198, 0x01A2, 0x1C79, 0x1C8E, 0x0209,
+ 0x4490, 0x4491, 0x1C9C, 0x1C9B, 0x4551, 0x1C7A, 0x1C9D, 0x1C9E, 0x1CA1, 0x1CA2,
+ 0x4475, 0x1C89, 0x4477, 0x4474, 0x1CA3, 0x4476, 0x004B, 0x004A, 0x1C7C, 0x01DF,
+ 0x1C8F, 0x4473, 0x448E, 0x1416, 0x1412, 0x1413, 0x1410, 0x4487, 0x4485, 0x4484,
+ 0x4446, 0x4486, 0x448A, 0x4488, 0x448B, 0x1539, 0x444C, 0x448C, 0x1408, 0x1409,
+ 0x448D, 0x1538, 0x4493, 0x140E, 0x1417, 0x4494, 0x140F, 0x4496, 0x153D, 0x1553,
+ 0x1415, 0x1546, 0x1547, 0x1407, 0x140C, 0x1551, 0x154D, 0x140D, 0x44A3, 0x154C,
+ 0x44A5, 0x44A4, 0x153F, 0x13FD, 0x1561, 0x44A8, 0x1560, 0x1537, 0x44B0, 0x1536,
+ 0x44B1, 0x44AE, 0x1555, 0x155C, 0x1562, 0x1563, 0x153E, 0x140B, 0x44B7, 0x153A,
+ 0x44B9, 0x44B8, 0x1545, 0x44BA, 0x140A, 0x44BC, 0x1544, 0x1414, 0x154A, 0x154B,
+ 0x1550, 0x13FB, 0x13FC, 0x13FF, 0x13FE, 0x44C6, 0x1400, 0x1401, 0x44CB, 0x44CA,
+ 0x44CD, 0x44CC, 0x1542, 0x1430, 0x141C, 0x1419, 0x1403, 0x1543, 0x153C, 0x1540,
+ 0x1431, 0x1421, 0x01DF, 0x0198, 0x1405, 0x021F, 0x1300, 0x1406, 0x01A2, 0x01C9,
+ 0x141A, 0x0215, 0x142B, 0x141B, 0x01A2, 0x12AB, 0x1418, 0x1428, 0x1427, 0x142D,
+ 0x1566, 0x1557, 0x1556, 0x142A, 0x1429, 0x142F, 0x12FF, 0x1554, 0x44F3, 0x44F2,
+ 0x1300, 0x44F4, 0x155A, 0x155B, 0x44F9, 0x44F8, 0x44FB, 0x44FA, 0x44FD, 0x44FC,
+ 0x1447, 0x1567, 0x144B, 0x144D, 0x1301, 0x142C, 0x4505, 0x4504, 0x4507, 0x4506,
+ 0x4509, 0x4508, 0x450B, 0x01C9, 0x450D, 0x450C, 0x450F, 0x450E, 0x1D5B, 0x4510,
+ 0x01A2, 0x01DF, 0x4515, 0x4514, 0x1D6C, 0x1D5A, 0x1D61, 0x1D60, 0x1D68, 0x021F,
+ 0x0209, 0x1D6F, 0x1D67, 0x1D66, 0x1D6D, 0x0234, 0x4523, 0x1D69, 0x4525, 0x4524,
+ 0x4527, 0x4526, 0x4529, 0x4528, 0x452B, 0x452A, 0x452D, 0x0198, 0x0215, 0x452E,
+ 0x4531, 0x4530, 0x1D4D, 0x1D73, 0x022A, 0x1D4B, 0x1D4F, 0x144C, 0x1D48, 0x1D46,
+ 0x1D51, 0x1D45, 0x1D4E, 0x1D47, 0x1D4A, 0x1D5E, 0x1D71, 0x1D50, 0x1D5F, 0x1D4C,
+ 0x1D5C, 0x1D5D, 0x1D52, 0x4546, 0x141D, 0x1420, 0x454B, 0x454A, 0x454D, 0x454C,
+ 0x141E, 0x454E, 0x2B19, 0x141F, 0x146A, 0x4517, 0x2B11, 0x2B12, 0x2B1B, 0x2B1A,
+ 0x4422, 0x1432, 0x4549, 0x144A, 0x1446, 0x01C9, 0x1468, 0x021F, 0x1422, 0x1469,
+ 0x0215, 0x142E, 0x022A, 0x0234, 0x01DF, 0x01C9, 0x1D70, 0x2B0D, 0x1D72, 0x2B0F,
+ 0x2B0E, 0x2B1C, 0x2B14, 0x2B10, 0x2B13, 0x2B15, 0x2B16, 0x4572, 0x4575, 0x4574,
+ 0x4577, 0x4576, 0x4579, 0x4578, 0x457B, 0x457A, 0x457D, 0x457C, 0x1478, 0x1472,
+ 0x2B26, 0x2B25, 0x2B17, 0x146C, 0x146D, 0x2B29, 0x4587, 0x4586, 0x1FFD, 0x146B,
+ 0x458B, 0x458A, 0x458D, 0x458C, 0x1FFE, 0x458E, 0x4591, 0x2001, 0x147F, 0x2003,
+ 0x149C, 0x147E, 0x2008, 0x1480, 0x200A, 0x2009, 0x200C, 0x200B, 0x1481, 0x147C,
+ 0x2010, 0x200F, 0x2012, 0x2011, 0x14A9, 0x1474, 0x149A, 0x2015, 0x2018, 0x1470,
+ 0x201A, 0x2019, 0x1471, 0x201B, 0x14A2, 0x146E, 0x2020, 0x201F, 0x1484, 0x1485,
+ 0x147B, 0x14A5, 0x2026, 0x2025, 0x1486, 0x1483, 0x1479, 0x147A, 0x1487, 0x202B,
+ 0x1482, 0x149E, 0x45D1, 0x45C7, 0x45C8, 0x45C9, 0x45C5, 0x45AE, 0x459E, 0x459F,
+ 0x01DF, 0x01A2, 0x45A1, 0x0209, 0x1423, 0x45AF, 0x45B0, 0x45B1, 0x1499, 0x149B,
+ 0x1411, 0x0050, 0x004E, 0x4783, 0x004F, 0x14A8, 0x146F, 0x0051, 0x004D, 0x0198,
+ 0x01DF, 0x004C, 0x149D, 0x0052, 0x1475, 0x0215, 0x005B, 0x1426, 0x1496, 0x1497,
+ 0x149F, 0x1498, 0x14A3, 0x1493, 0x1D87, 0x1D7F, 0x1DA7, 0x1D91, 0x1491, 0x1DBF,
+ 0x1D99, 0x14A0, 0x14A1, 0x1DBA, 0x1D8C, 0x1D80, 0x1DA1, 0x1D93, 0x1DA8, 0x1DA4,
+ 0x45CD, 0x14AA, 0x14A7, 0x14A4, 0x1425, 0x1424, 0x14D8, 0x14B0, 0x0234, 0x022A,
+ 0x14B6, 0x14AE, 0x1DBD, 0x1DB0, 0x4874, 0x14AF, 0x14DD, 0x14DE, 0x14AD, 0x14D7,
+ 0x14B2, 0x14AC, 0x14B8, 0x14B7, 0x14D9, 0x14B9, 0x14BC, 0x14BB, 0x30C7, 0x14BD,
+ 0x14B1, 0x14B4, 0x14BF, 0x14BE, 0x14C1, 0x14C0, 0x14C3, 0x14C2, 0x30C3, 0x14CD,
+ 0x14D6, 0x14C6, 0x14C9, 0x14CB, 0x14C7, 0x14DA, 0x14C8, 0x30DE, 0x1B37, 0x14B5,
+ 0x14B3, 0x1B43, 0x14C5, 0x14CF, 0x14C4, 0x1B61, 0x14D5, 0x14CA, 0x1B79, 0x14D4,
+ 0x14D3, 0x1B5B, 0x14CE, 0x14DB, 0x30C2, 0x14DC, 0x14DF, 0x1DD2, 0x1B4F, 0x1B8B,
+ 0x1B91, 0x45CE, 0x45D0, 0x022A, 0x0234, 0x1B73, 0x1B85, 0x45CA, 0x30C9, 0x45C6,
+ 0x45B9, 0x1DA3, 0x45B3, 0x45CB, 0x45CC, 0x45B2, 0x45CF, 0x45BF, 0x4724, 0x4665,
+ 0x1514, 0x1BA1, 0x47CD, 0x1513, 0x0215, 0x1DB8, 0x1DCE, 0x1DD1, 0x46C4, 0x1DA0,
+ 0x0209, 0x47C0, 0x01C9, 0x01F5, 0x0215, 0x0198, 0x4807, 0x01A2, 0x01A2, 0x0198,
+ 0x14CC, 0x01C9, 0x0234, 0x01F5, 0x021F, 0x01DF, 0x14D2, 0x022A, 0x0198, 0x1D98,
+ 0x1B67, 0x1B6D, 0x1515, 0x01C9, 0x45B4, 0x45B5, 0x1D92, 0x1DB3, 0x0198, 0x1DAF,
+ 0x45E3, 0x4848, 0x01DF, 0x4819, 0x1B7F, 0x4801, 0x30C6, 0x481E, 0x01C9, 0x0234,
+ 0x487B, 0x022A, 0x30C8, 0x021F, 0x30D0, 0x18EF, 0x30D1, 0x30FC, 0x1B9B, 0x1B9C,
+ 0x45B8, 0x1901, 0x30CA, 0x30CB, 0x30CC, 0x18F5, 0x1B98, 0x30CF, 0x18FB, 0x0E89,
+ 0x30F2, 0x30E3, 0x0F95, 0x0F96, 0x0FAA, 0x0EFD, 0x30F8, 0x30F9, 0x0EA8, 0x0EA4,
+ 0x30CE, 0x1017, 0x192B, 0x1931, 0x0EA6, 0x0F11, 0x1A8F, 0x1A95, 0x0F8B, 0x1913,
+ 0x1B9D, 0x1B9E, 0x0F03, 0x1AB3, 0x0F43, 0x0D4F, 0x4772, 0x190D, 0x0F41, 0x0F42,
+ 0x0F40, 0x1AB9, 0x0F0F, 0x0F90, 0x1018, 0x0F97, 0x30F7, 0x1919, 0x1B55, 0x30F5,
+ 0x30F4, 0x30FD, 0x1B9A, 0x1B49, 0x0EF4, 0x30F3, 0x30F6, 0x1907, 0x0FAF, 0x3116,
+ 0x0FC8, 0x0215, 0x0FB8, 0x3117, 0x2135, 0x47F0, 0x4730, 0x0FB5, 0x30E7, 0x0FC2,
+ 0x30E8, 0x0FB0, 0x0E58, 0x3121, 0x311D, 0x3103, 0x311B, 0x30E6, 0x311C, 0x0FD8,
+ 0x0ECE, 0x0EAF, 0x14FA, 0x46FF, 0x0EB0, 0x0EF3, 0x48BE, 0x0ECC, 0x0EFB, 0x0EED,
+ 0x4701, 0x4610, 0x0EA9, 0x30E5, 0x0E63, 0x0FC5, 0x30E2, 0x0FC1, 0x30FE, 0x1008,
+ 0x30E4, 0x3120, 0x0E78, 0x212B, 0x0EF6, 0x476A, 0x2129, 0x311A, 0x30E9, 0x30FF,
+ 0x0EF2, 0x2137, 0x3100, 0x0F9B, 0x475F, 0x30FB, 0x30FA, 0x3101, 0x1B3D, 0x3102,
+ 0x14F5, 0x0D8C, 0x0F67, 0x0F46, 0x1127, 0x1126, 0x112A, 0x0D67, 0x469F, 0x0C64,
+ 0x310A, 0x310B, 0x3110, 0x0F15, 0x310E, 0x310F, 0x0D98, 0x3111, 0x0FDC, 0x0C65,
+ 0x0FBB, 0x0D1E, 0x0CC2, 0x0C9D, 0x1012, 0x0C5B, 0x0C5E, 0x0D7F, 0x0C6B, 0x0D06,
+ 0x0C71, 0x0C9B, 0x480D, 0x0CDC, 0x0CA7, 0x3123, 0x3122, 0x4677, 0x0D56, 0x0C68,
+ 0x0CDF, 0x0C6E, 0x30EC, 0x30ED, 0x0D91, 0x100F, 0x0F12, 0x0D2B, 0x1010, 0x30F1,
+ 0x0F0A, 0x3133, 0x3134, 0x3135, 0x0D95, 0x1011, 0x3138, 0x1A74, 0x1A75, 0x4882,
+ 0x1A55, 0x20FB, 0x0E8F, 0x0ED0, 0x0EB9, 0x0FE3, 0x3107, 0x212D, 0x3104, 0x3105,
+ 0x0F09, 0x4814, 0x468C, 0x4818, 0x477F, 0x311E, 0x3109, 0x46D5, 0x311F, 0x215B,
+ 0x2159, 0x47B3, 0x2167, 0x2157, 0x474B, 0x4632, 0x460F, 0x4669, 0x4635, 0x47B0,
+ 0x471B, 0x45EE, 0x4685, 0x46A5, 0x46F0, 0x4753, 0x46B6, 0x4704, 0x4866, 0x47BB,
+ 0x4615, 0x48BC, 0x4681, 0x4698, 0x3108, 0x47CF, 0x483E, 0x14F4, 0x0D8E, 0x3106,
+ 0x476E, 0x4762, 0x45E5, 0x214F, 0x46AB, 0x4666, 0x46AE, 0x4737, 0x2163, 0x4678,
+ 0x4889, 0x4767, 0x4677, 0x48AA, 0x467D, 0x46E9, 0x464D, 0x310C, 0x488B, 0x310D,
+ 0x151A, 0x200E, 0x457E, 0x470F, 0x47AA, 0x4581, 0x457F, 0x145D, 0x4520, 0x2115,
+ 0x2014, 0x022C, 0x0236, 0x019A, 0x2013, 0x2109, 0x01DF, 0x4886, 0x210F, 0x0221,
+ 0x0198, 0x01A2, 0x2117, 0x445B, 0x210B, 0x445C, 0x021F, 0x1435, 0x1433, 0x4460,
+ 0x1439, 0x210D, 0x1517, 0x4461, 0x1434, 0x1C90, 0x143E, 0x445A, 0x1C9F, 0x0234,
+ 0x01A4, 0x01CB, 0x448F, 0x151E, 0x1465, 0x152F, 0x2141, 0x1437, 0x4872, 0x1438,
+ 0x152B, 0x1518, 0x1C96, 0x4834, 0x1BB7, 0x211B, 0x445E, 0x1462, 0x01F5, 0x152C,
+ 0x1532, 0x4732, 0x1530, 0x1461, 0x4470, 0x1516, 0x20ED, 0x1C91, 0x0CA5, 0x143D,
+ 0x20F1, 0x20F3, 0x2165, 0x215F, 0x1C8A, 0x14FB, 0x1C8C, 0x20EF, 0x4750, 0x2161,
+ 0x20FD, 0x20EB, 0x20E9, 0x20FF, 0x46E2, 0x2107, 0x01C9, 0x01A2, 0x2119, 0x01DF,
+ 0x20F9, 0x0198, 0x2121, 0x2123, 0x20F5, 0x2127, 0x0234, 0x214D, 0x022A, 0x0209,
+ 0x021F, 0x0EB7, 0x0D24, 0x0C5C, 0x0217, 0x0D23, 0x0FBC, 0x2105, 0x01DF, 0x0FC9,
+ 0x0FE4, 0x0D19, 0x0CC7, 0x0215, 0x215D, 0x2153, 0x2151, 0x0D25, 0x1BBE, 0x151C,
+ 0x1C94, 0x1C8B, 0x47E7, 0x4456, 0x445D, 0x151D, 0x1BD1, 0x1BD0, 0x191F, 0x4693,
+ 0x1019, 0x473F, 0x1BD2, 0x18A7, 0x0EF7, 0x445F, 0x18B3, 0x0EF8, 0x1967, 0x18B9,
+ 0x1BBA, 0x1BBB, 0x0FAB, 0x0FD2, 0x0C78, 0x1C93, 0x0FAC, 0x1937, 0x1997, 0x0FCF,
+ 0x0FD1, 0x0EFA, 0x0D49, 0x0FC4, 0x0C29, 0x18AD, 0x0EB1, 0x01E1, 0x0CCD, 0x022A,
+ 0x1C73, 0x1C72, 0x0D9A, 0x01F7, 0x020B, 0x0DB4, 0x01F5, 0x0FC6, 0x487C, 0x18D1,
+ 0x0FB1, 0x0209, 0x0215, 0x021F, 0x022A, 0x0234, 0x0E09, 0x0E44, 0x0E8A, 0x47A2,
+ 0x1CA0, 0x0FB6, 0x1007, 0x1BB4, 0x1BB6, 0x0EF9, 0x485C, 0x01A2, 0x1C9A, 0x0198,
+ 0x0FCD, 0x0FD0, 0x1BBF, 0x101B, 0x1BB9, 0x1949, 0x46C5, 0x1BB8, 0x1BB5, 0x1BA6,
+ 0x1009, 0x100E, 0x1925, 0x0FB7, 0x2BF8, 0x0EEE, 0x1A72, 0x1A73, 0x0FD4, 0x2BF3,
+ 0x2BFB, 0x01C9, 0x0F0D, 0x0FD3, 0x143A, 0x143C, 0x1A76, 0x1404, 0x1402, 0x01A2,
+ 0x0198, 0x01A2, 0x01F5, 0x0209, 0x01F5, 0x0209, 0x1002, 0x01DF, 0x0215, 0x021F,
+ 0x4817, 0x19AD, 0x2C32, 0x2C2C, 0x2C27, 0x0BB9, 0x01DF, 0x0BB7, 0x193D, 0x19B2,
+ 0x2C2D, 0x01DF, 0x2C31, 0x2C2E, 0x1943, 0x47E5, 0x488E, 0x46E4, 0x4857, 0x0F2D,
+ 0x45E9, 0x47A1, 0x4871, 0x48AE, 0x46B4, 0x45E1, 0x48A8, 0x4892, 0x0F07, 0x479D,
+ 0x2C24, 0x0D1F, 0x2BF1, 0x0D26, 0x0D1A, 0x476F, 0x0D27, 0x0D1D, 0x2BEA, 0x0C24,
+ 0x0EAD, 0x0D1B, 0x0EAC, 0x0BEA, 0x0C07, 0x0C1B, 0x0BE6, 0x0EAA, 0x2BA3, 0x2BCA,
+ 0x2BA1, 0x0EB4, 0x2BBE, 0x2BA4, 0x2BA5, 0x2BA6, 0x0EB3, 0x2BBF, 0x2BC0, 0x2BC3,
+ 0x2BC4, 0x2BCB, 0x0EAB, 0x2AA7, 0x2C0B, 0x0F77, 0x0D28, 0x0D4B, 0x47F6, 0x2BC7,
+ 0x1DB9, 0x0D20, 0x2BE0, 0x2BE1, 0x0D29, 0x0F5B, 0x2AAB, 0x2BE5, 0x2BE6, 0x2BE7,
+ 0x0EB2, 0x0D4C, 0x0D53, 0x0D46, 0x0D47, 0x0D44, 0x2BEB, 0x0D41, 0x0D42, 0x0D4E,
+ 0x2691, 0x0D54, 0x1C71, 0x1C84, 0x0D4D, 0x1C74, 0x1C77, 0x1C76, 0x1C7E, 0x2676,
+ 0x2675, 0x267C, 0x1C7D, 0x1C78, 0x1C83, 0x1C7F, 0x2BFF, 0x2BFE, 0x1C81, 0x1CA4,
+ 0x1C92, 0x1C82, 0x226E, 0x2C0C, 0x1C97, 0x1C99, 0x226F, 0x2C0F, 0x46F8, 0x469A,
+ 0x26AF, 0x2C26, 0x2694, 0x2692, 0x2C0E, 0x2248, 0x2C06, 0x26A9, 0x2693, 0x2BFD,
+ 0x2C07, 0x2C02, 0x2C01, 0x1C7B, 0x2C03, 0x2C04, 0x2C0A, 0x2C09, 0x26AA, 0x26A2,
+ 0x26A3, 0x26A4, 0x26A1, 0x26A6, 0x26A5, 0x26B0, 0x2BA2, 0x26A7, 0x26A8, 0x26AC,
+ 0x2B9F, 0x0BF2, 0x2B87, 0x26AB, 0x1230, 0x264C, 0x1FFF, 0x2007, 0x201E, 0x2000,
+ 0x2002, 0x2672, 0x0469, 0x1234, 0x46EF, 0x2004, 0x475E, 0x11F0, 0x11EF, 0x268F,
+ 0x2670, 0x2690, 0x0398, 0x046D, 0x2688, 0x046A, 0x266F, 0x0522, 0x2016, 0x048B,
+ 0x0514, 0x2029, 0x2BE2, 0x034D, 0x051D, 0x268A, 0x264E, 0x2678, 0x0349, 0x264F,
+ 0x2653, 0x267D, 0x2669, 0x2671, 0x267B, 0x201C, 0x0299, 0x267A, 0x2006, 0x264D,
+ 0x029E, 0x202A, 0x0374, 0x265D, 0x0348, 0x266A, 0x2660, 0x266B, 0x265C, 0x04B8,
+ 0x2665, 0x2666, 0x2667, 0x2668, 0x2663, 0x2652, 0x266C, 0x2664, 0x2021, 0x2BE8,
+ 0x4672, 0x0649, 0x46F9, 0x0C13, 0x0643, 0x0C1A, 0x2005, 0x0FBA, 0x46B9, 0x0642,
+ 0x0C1F, 0x0C2D, 0x0CCE, 0x0D1C, 0x0F00, 0x2685, 0x0D48, 0x0FB4, 0x477E, 0x4791,
+ 0x0D22, 0x0EEF, 0x0F01, 0x06A2, 0x0FB2, 0x0FAE, 0x268C, 0x01A2, 0x2684, 0x268D,
+ 0x2023, 0x472A, 0x201D, 0x0FB9, 0x0D43, 0x0F91, 0x0BE7, 0x0C18, 0x2C21, 0x0F94,
+ 0x0C0D, 0x0C10, 0x0C25, 0x0C28, 0x0C2E, 0x2024, 0x0F93, 0x0C08, 0x0BE3, 0x0C27,
+ 0x0234, 0x4480, 0x2B77, 0x2B7A, 0x2B79, 0x0C2B, 0x2B78, 0x2B9A, 0x2BD2, 0x2022,
+ 0x2B7D, 0x069F, 0x2B80, 0x0FB3, 0x0C2A, 0x0BE2, 0x2B9B, 0x2B9D, 0x2B8A, 0x2B90,
+ 0x2B8D, 0x2B8B, 0x0BF7, 0x0C22, 0x2B93, 0x2B94, 0x2B96, 0x2B98, 0x2B95, 0x2B86,
+ 0x2B99, 0x2B92, 0x200D, 0x0CC6, 0x0C66, 0x2B85, 0x0CC5, 0x0C1D, 0x0C67, 0x2249,
+ 0x0CCA, 0x2B7F, 0x0CC3, 0x2639, 0x0CCB, 0x1231, 0x1247, 0x2B7B, 0x1233, 0x2B81,
+ 0x1235, 0x2BCC, 0x122F, 0x124A, 0x1249, 0x1248, 0x124B, 0x124C, 0x124D, 0x0CC8,
+ 0x2BD8, 0x2B83, 0x0CC9, 0x2BFC, 0x2B84, 0x0CD0, 0x2B89, 0x0CCF, 0x2BE4, 0x0CC4,
+ 0x0C16, 0x0FAD, 0x2AD6, 0x0D21, 0x2B9E, 0x04BC, 0x2638, 0x1FBC, 0x1FBD, 0x1FBE,
+ 0x1FC6, 0x1FC0, 0x4829, 0x0D93, 0x4768, 0x481C, 0x0D8A, 0x0EF1, 0x1FBF, 0x461B,
+ 0x0D52, 0x1FC2, 0x2B88, 0x474E, 0x265E, 0x0EF0, 0x0D51, 0x0D8F, 0x0D97, 0x0D96,
+ 0x022A, 0x0F05, 0x0EFF, 0x4835, 0x4867, 0x1FC3, 0x1FC4, 0x1FC5, 0x1D9C, 0x0F06,
+ 0x0F8E, 0x0F8D, 0x265F, 0x4699, 0x1DE9, 0x2BCF, 0x101A, 0x2BDB, 0x0F92, 0x4606,
+ 0x2BDF, 0x2AA3, 0x4842, 0x2BE3, 0x461C, 0x48A4, 0x486F, 0x1D8E, 0x45E0, 0x465D,
+ 0x475B, 0x48B0, 0x4883, 0x1DD3, 0x467F, 0x4790, 0x4726, 0x4968, 0x1DC4, 0x2B8F,
+ 0x1125, 0x480E, 0x1232, 0x470F, 0x11D2, 0x0F3C, 0x47EA, 0x0F3E, 0x0F3D, 0x4714,
+ 0x0F3F, 0x0F60, 0x4628, 0x0F62, 0x0F61, 0x0F85, 0x0F63, 0x0F87, 0x0F86, 0x0F89,
+ 0x481B, 0x484B, 0x11CE, 0x4859, 0x4850, 0x11CD, 0x46F5, 0x11CF, 0x48BE, 0x462E,
+ 0x45FB, 0x4780, 0x022A, 0x0234, 0x0DA1, 0x4756, 0x45DD, 0x000F, 0x000B, 0x0016,
+ 0x0013, 0x0C80, 0x0C7F, 0x0C82, 0x2680, 0x0C89, 0x0C88, 0x0CB6, 0x0CB5, 0x0CB8,
+ 0x0CB7, 0x0CBA, 0x0CB9, 0x0CF8, 0x0CF7, 0x0CFC, 0x0CF9, 0x0CFE, 0x0CFD, 0x0D0F,
+ 0x0D0E, 0x0D11, 0x0D10, 0x0D13, 0x0D12, 0x0E9C, 0x0E9B, 0x0EC5, 0x0EC4, 0x1D62,
+ 0x0964, 0x0A49, 0x1D64, 0x1D6B, 0x0A86, 0x0969, 0x1D65, 0x0A78, 0x0A74, 0x11D1,
+ 0x0A70, 0x0A85, 0x0A4E, 0x0A5C, 0x0A77, 0x0A4F, 0x0A63, 0x0A65, 0x0A6F, 0x0A04,
+ 0x096A, 0x0A73, 0x0A06, 0x0A64, 0x0A66, 0x096D, 0x096E, 0x09AD, 0x0A4A, 0x0A1E,
+ 0x09CC, 0x0A1D, 0x0986, 0x0985, 0x45DB, 0x473B, 0x098B, 0x14F6, 0x1128, 0x098C,
+ 0x14F0, 0x14F7, 0x11F1, 0x1D43, 0x01F5, 0x4641, 0x0209, 0x1549, 0x11D0, 0x1129,
+ 0x4755, 0x11EE, 0x1D6A, 0x11ED, 0x4712, 0x1D53, 0x11EC, 0x2B20, 0x0F0E, 0x14E9,
+ 0x10F2, 0x10F1, 0x2131, 0x2133, 0x46FB, 0x470A, 0x4754, 0x4633, 0x2145, 0x4778,
+ 0x2101, 0x2103, 0x4702, 0x472A, 0x14EC, 0x478D, 0x14EA, 0x43AB, 0x4623, 0x14ED,
+ 0x14EE, 0x14F1, 0x43D1, 0x14E8, 0x14F2, 0x14F3, 0x14EF, 0x2143, 0x2125, 0x488D,
+ 0x4764, 0x213D, 0x4738, 0x1FC1, 0x2139, 0x01A2, 0x212F, 0x111C, 0x111F, 0x4399,
+ 0x1121, 0x1120, 0x1123, 0x1122, 0x477B, 0x112B, 0x112E, 0x4831, 0x1130, 0x214B,
+ 0x1132, 0x1131, 0x1135, 0x1134, 0x1137, 0x1136, 0x1139, 0x2149, 0x113B, 0x113A,
+ 0x2155, 0x1552, 0x48B2, 0x113D, 0x47AC, 0x1501, 0x14FC, 0x469D, 0x4793, 0x48A6,
+ 0x46EA, 0x0234, 0x022A, 0x1D56, 0x4880, 0x4743, 0x1502, 0x150E, 0x46F4, 0x14FD,
+ 0x14FE, 0x114B, 0x01F5, 0x0209, 0x114E, 0x4616, 0x1150, 0x114F, 0x1152, 0x460E,
+ 0x48B4, 0x1153, 0x115B, 0x1D58, 0x115D, 0x115C, 0x4811, 0x485B, 0x4617, 0x4830,
+ 0x14FF, 0x14EB, 0x150F, 0x485F, 0x1511, 0x1510, 0x1D7D, 0x48B1, 0x46BE, 0x1DC0,
+ 0x01C9, 0x01A2, 0x01DF, 0x116F, 0x0215, 0x1512, 0x0198, 0x021F, 0x1D55, 0x14F8,
+ 0x1500, 0x1DAD, 0x14F9, 0x0209, 0x1DD5, 0x01F5, 0x213F, 0x213B, 0x1180, 0x117F,
+ 0x2113, 0x2027, 0x2147, 0x0046, 0x46C8, 0x1D63, 0x2028, 0x489C, 0x2111, 0x211F,
+ 0x45FC, 0x4888, 0x46ED, 0x20F7, 0x4769, 0x47CB, 0x297A, 0x2979, 0x1194, 0x1193,
+ 0x1196, 0x1195, 0x1198, 0x1197, 0x119A, 0x1199, 0x119D, 0x119C, 0x119F, 0x119E,
+ 0x11A1, 0x11A0, 0x11A3, 0x11A2, 0x2975, 0x11A4, 0x11A6, 0x11A5, 0x11A8, 0x11A7,
+ 0x2976, 0x2974, 0x11AA, 0x11A9, 0x11AC, 0x11AB, 0x11AE, 0x11AD, 0x2981, 0x11AF,
+ 0x2983, 0x11B0, 0x11B2, 0x11B1, 0x11B4, 0x11B3, 0x297D, 0x297C, 0x11B6, 0x297E,
+ 0x11B8, 0x11B7, 0x11BA, 0x11B9, 0x2978, 0x11BB, 0x11BE, 0x11BD, 0x11C0, 0x11BF,
+ 0x11C2, 0x11C1, 0x297F, 0x11C3, 0x11C5, 0x11C4, 0x11C7, 0x11C6, 0x11C9, 0x11C8,
+ 0x11CB, 0x11CA, 0x2991, 0x2967, 0x11D6, 0x11D5, 0x2966, 0x2964, 0x298C, 0x2965,
+ 0x2992, 0x2993, 0x2968, 0x2969, 0x296A, 0x296D, 0x296E, 0x296F, 0x11E4, 0x11E3,
+ 0x11E6, 0x11E5, 0x296C, 0x2973, 0x11EA, 0x11E9, 0x2982, 0x2980, 0x11F5, 0x11F4,
+ 0x11F7, 0x11F6, 0x298E, 0x2985, 0x2986, 0x29B5, 0x29B4, 0x2997, 0x298A, 0x298B,
+ 0x29B8, 0x298F, 0x2984, 0x2987, 0x2970, 0x2971, 0x2972, 0x2989, 0x29A5, 0x29A1,
+ 0x29A0, 0x29BF, 0x29B7, 0x29A7, 0x2999, 0x299A, 0x299D, 0x299E, 0x29B6, 0x298D,
+ 0x299C, 0x29A2, 0x29A3, 0x2988, 0x29C4, 0x29C5, 0x29E7, 0x1D44, 0x29C7, 0x29C9,
+ 0x29CA, 0x021F, 0x01F5, 0x01C9, 0x29B0, 0x1D54, 0x1D49, 0x29B1, 0x1D59, 0x47C3,
+ 0x29F5, 0x29D8, 0x29F7, 0x29F6, 0x29F9, 0x29F8, 0x29DA, 0x29FA, 0x29FD, 0x29DE,
+ 0x29FF, 0x29FE, 0x2A01, 0x2A00, 0x1D75, 0x2A02, 0x2A05, 0x2A04, 0x29D6, 0x2A06,
+ 0x2A09, 0x2A08, 0x2A0B, 0x2A0A, 0x1D74, 0x2A0C, 0x2A0F, 0x29DF, 0x4863, 0x2990,
+ 0x474D, 0x463A, 0x4771, 0x0C5D, 0x29D4, 0x29DB, 0x0E1F, 0x0DEB, 0x0CBB, 0x0C69,
+ 0x0C6D, 0x0C6C, 0x0C8B, 0x0C7D, 0x0C72, 0x0E11, 0x0CA1, 0x0C9F, 0x2A25, 0x2A24,
+ 0x29A6, 0x2A26, 0x29A4, 0x2A28, 0x01A2, 0x29AB, 0x01DF, 0x01C9, 0x0209, 0x29AF,
+ 0x29A9, 0x0D3A, 0x0234, 0x29AA, 0x0DFE, 0x29AD, 0x29CB, 0x0E18, 0x29C2, 0x29B9,
+ 0x29BA, 0x29BB, 0x29BC, 0x29BD, 0x29BE, 0x000C, 0x29C0, 0x29C1, 0x29B2, 0x29C3,
+ 0x0E2B, 0x0DA5, 0x0E9D, 0x0E98, 0x0DBE, 0x0DC9, 0x0DD8, 0x0EC0, 0x0EBB, 0x0D5C,
+ 0x0E17, 0x29D5, 0x224A, 0x000E, 0x29A8, 0x0DE2, 0x0DF1, 0x0D70, 0x29AC, 0x29B3,
+ 0x0004, 0x0003, 0x29D7, 0x0008, 0x0D69, 0x0D86, 0x0010, 0x0012, 0x0D85, 0x29AE,
+ 0x0006, 0x000A, 0x2A2C, 0x2A2A, 0x2A30, 0x2A2E, 0x2A34, 0x2A32, 0x2A38, 0x2A36,
+ 0x2A3C, 0x2A3A, 0x2A40, 0x2A3E, 0x2A44, 0x2A42, 0x2A48, 0x2A46, 0x2A4C, 0x2A4A,
+ 0x2A50, 0x2A4E, 0x0D62, 0x0D31, 0x0E7D, 0x2A56, 0x2A5C, 0x2A5A, 0x2A60, 0x2A5E,
+ 0x0002, 0x2A62, 0x2A68, 0x2A66, 0x2A6C, 0x2A6A, 0x2A2B, 0x2A29, 0x0D58, 0x0D5B,
+ 0x0001, 0x2A31, 0x2A37, 0x2A35, 0x2A3B, 0x2A39, 0x0E39, 0x2A3D, 0x2A43, 0x0E32,
+ 0x2A47, 0x2A45, 0x2A4B, 0x2A49, 0x0DCF, 0x2A4D, 0x2A53, 0x2A51, 0x2A57, 0x2A55,
+ 0x2A5B, 0x2A59, 0x2A5F, 0x2A5D, 0x2A63, 0x2A61, 0x2A67, 0x2A65, 0x2A6B, 0x2A69,
+ 0x46E6, 0x29C8, 0x469C, 0x4774, 0x29D2, 0x466E, 0x29CC, 0x29CD, 0x4761, 0x29D1,
+ 0x29D0, 0x4719, 0x01A2, 0x0198, 0x01DF, 0x01C9, 0x0209, 0x01F5, 0x021F, 0x0215,
+ 0x0234, 0x022A, 0x4745, 0x0F5E, 0x0C63, 0x0C62, 0x224B, 0x46B3, 0x4782, 0x0C5F,
+ 0x22C0, 0x22C1, 0x29E0, 0x46DE, 0x0C60, 0x29C6, 0x22DA, 0x29E1, 0x0C6A, 0x0C7A,
+ 0x0D0A, 0x22DB, 0x29CE, 0x29CF, 0x473A, 0x29DC, 0x22C5, 0x22D4, 0x29D9, 0x22D6,
+ 0x29D3, 0x29E2, 0x22D3, 0x0D0D, 0x22D5, 0x22D8, 0x29DD, 0x46A8, 0x29E3, 0x0CFF,
+ 0x22D7, 0x0CB2, 0x0D08, 0x0CAF, 0x0CDE, 0x226A, 0x226B, 0x0CDD, 0x0CE1, 0x22C2,
+ 0x22C6, 0x22C7, 0x0CA9, 0x0CF1, 0x22CA, 0x2264, 0x22C4, 0x22CB, 0x2244, 0x221D,
+ 0x2BF5, 0x4802, 0x2AAC, 0x2BED, 0x492D, 0x2C11, 0x4865, 0x48E0, 0x48EA, 0x0015,
+ 0x2238, 0x2269, 0x2228, 0x0014, 0x0D32, 0x21FC, 0x21FF, 0x21FE, 0x0018, 0x21FD,
+ 0x2203, 0x2200, 0x0D14, 0x0017, 0x0D2D, 0x0CEE, 0x2206, 0x2201, 0x2202, 0x2207,
+ 0x222C, 0x2235, 0x2234, 0x2239, 0x221E, 0x2209, 0x220A, 0x223B, 0x2205, 0x047C,
+ 0x04E2, 0x0446, 0x2204, 0x2218, 0x220B, 0x01A3, 0x0199, 0x01E0, 0x01CA, 0x020A,
+ 0x01F6, 0x0220, 0x0216, 0x0235, 0x223A, 0x221F, 0x2236, 0x2237, 0x2CB5, 0x2CBA,
+ 0x2CBF, 0x2C96, 0x2CA8, 0x2D35, 0x2D2F, 0x2D29, 0x2D5C, 0x2C67, 0x2C9D, 0x2C82,
+ 0x2C6D, 0x2CAF, 0x2C7C, 0x2CCE, 0x2C74, 0x2C7E, 0x2230, 0x0553, 0x053C, 0x05B8,
+ 0x0575, 0x063A, 0x05E6, 0x2C69, 0x2C77, 0x06BD, 0x0698, 0x2C6F, 0x06DA, 0x2CA2,
+ 0x2C84, 0x2C8B, 0x2C90, 0x2BEF, 0x02A7, 0x225C, 0x225F, 0x4658, 0x46D7, 0x225D,
+ 0x2260, 0x025B, 0x02C4, 0x465C, 0x4890, 0x2267, 0x2261, 0x477A, 0x47BD, 0x2263,
+ 0x0386, 0x0365, 0x4731, 0x45E2, 0x473D, 0x2BF9, 0x46D1, 0x4861, 0x484F, 0x4779,
+ 0x47B8, 0x47FD, 0x4707, 0x2C28, 0x4873, 0x483A, 0x0329, 0x4722, 0x473E, 0x46FD,
+ 0x453A, 0x0D92, 0x02E6, 0x4710, 0x225E, 0x4536, 0x2278, 0x4540, 0x453D, 0x453B,
+ 0x4534, 0x4535, 0x4541, 0x453F, 0x0499, 0x453C, 0x03B1, 0x4785, 0x4720, 0x03DB,
+ 0x480F, 0x0422, 0x040D, 0x471C, 0x453E, 0x483E, 0x454F, 0x2CC9, 0x2CC4, 0x2CD6,
+ 0x2CD1, 0x2CDF, 0x4781, 0x2CE6, 0x2CE2, 0x2CEC, 0x4562, 0x4571, 0x2CF4, 0x4568,
+ 0x2D04, 0x4553, 0x456E, 0x2D1F, 0x4566, 0x2D25, 0x2D22, 0x456F, 0x2D2B, 0x2D3C,
+ 0x4565, 0x2D44, 0x2D40, 0x2D4C, 0x2D48, 0x2D5F, 0x2D52, 0x2265, 0x4564, 0x0D82,
+ 0x456C, 0x4567, 0x4569, 0x4563, 0x4555, 0x0DA6, 0x0D6D, 0x22B0, 0x0D6C, 0x2266,
+ 0x22B7, 0x4554, 0x2977, 0x4558, 0x0D81, 0x2A81, 0x4552, 0x2A87, 0x2A84, 0x4559,
+ 0x0DA0, 0x4844, 0x458F, 0x01DF, 0x48C5, 0x0D9F, 0x01C9, 0x1DD0, 0x456A, 0x456B,
+ 0x4570, 0x4590, 0x0EBF, 0x2B33, 0x2B30, 0x2B39, 0x2B36, 0x2B3F, 0x2B3C, 0x0B4C,
+ 0x2A9D, 0x2B45, 0x2B42, 0x2B4B, 0x2B48, 0x2B51, 0x2B4E, 0x0E97, 0x46E5, 0x46EB,
+ 0x0B4F, 0x0B55, 0x2AB3, 0x0E91, 0x2A91, 0x2AA6, 0x23B2, 0x4799, 0x2AA0, 0x46A3,
+ 0x2B6C, 0x471C, 0x0ED2, 0x23B3, 0x4764, 0x46AD, 0x4622, 0x46A7, 0x2A73, 0x46C3,
+ 0x45D9, 0x2245, 0x46E8, 0x47BC, 0x462B, 0x2A76, 0x23B0, 0x2246, 0x45EC, 0x481A,
+ 0x0198, 0x01A2, 0x2247, 0x0EC6, 0x4841, 0x478B, 0x48C8, 0x0EDC, 0x0F17, 0x4607,
+ 0x0EE4, 0x461E, 0x23AA, 0x0F24, 0x0F35, 0x2392, 0x23AE, 0x36F5, 0x3724, 0x23A8,
+ 0x36F9, 0x23AD, 0x3725, 0x3709, 0x3729, 0x372A, 0x372D, 0x370D, 0x370E, 0x370F,
+ 0x3710, 0x3702, 0x3701, 0x23A5, 0x3703, 0x3707, 0x3705, 0x23A9, 0x23A6, 0x370C,
+ 0x23B1, 0x23A4, 0x370B, 0x370A, 0x3706, 0x3708, 0x23AB, 0x3721, 0x23B4, 0x23B5,
+ 0x23BC, 0x23AF, 0x23B8, 0x3720, 0x3727, 0x23BB, 0x23AC, 0x23BD, 0x23BE, 0x23BF,
+ 0x23C0, 0x3726, 0x23C2, 0x23C3, 0x2384, 0x2385, 0x2383, 0x2387, 0x237D, 0x2378,
+ 0x2348, 0x2389, 0x2386, 0x22CF, 0x237F, 0x237E, 0x3722, 0x238B, 0x2388, 0x372F,
+ 0x23A2, 0x2394, 0x237A, 0x23A3, 0x239B, 0x23A1, 0x2379, 0x2398, 0x239D, 0x238F,
+ 0x239F, 0x239C, 0x23A0, 0x238A, 0x239E, 0x373D, 0x2393, 0x3745, 0x373E, 0x237B,
+ 0x373C, 0x3741, 0x2374, 0x3742, 0x3747, 0x3731, 0x238E, 0x2C2F, 0x238C, 0x238D,
+ 0x3730, 0x3711, 0x2377, 0x3713, 0x3714, 0x3717, 0x22BD, 0x3740, 0x3712, 0x3719,
+ 0x371B, 0x3746, 0x3744, 0x2376, 0x3716, 0x3715, 0x371F, 0x2C29, 0x372E, 0x23B7,
+ 0x2BE9, 0x2C2B, 0x3739, 0x22D1, 0x23B6, 0x3728, 0x236C, 0x3718, 0x23BA, 0x23C1,
+ 0x372C, 0x2BEE, 0x2372, 0x2373, 0x22CE, 0x374B, 0x23A7, 0x374A, 0x3751, 0x22CD,
+ 0x374C, 0x3755, 0x3752, 0x3759, 0x2BF6, 0x374F, 0x374E, 0x23B9, 0x3750, 0x2C2A,
+ 0x22BC, 0x375D, 0x22BE, 0x22BF, 0x2390, 0x2365, 0x2240, 0x22C3, 0x2363, 0x2C22,
+ 0x2391, 0x2366, 0x2BF4, 0x236F, 0x2369, 0x236B, 0x22CC, 0x236D, 0x376A, 0x22D2,
+ 0x236E, 0x3771, 0x2BEC, 0x22D0, 0x2380, 0x2382, 0x22D9, 0x2371, 0x237C, 0x2381,
+ 0x2367, 0x2368, 0x377A, 0x377B, 0x377C, 0x3781, 0x377E, 0x377F, 0x3780, 0x3785,
+ 0x3782, 0x2405, 0x23C6, 0x23C7, 0x23C9, 0x3789, 0x248D, 0x23CA, 0x378A, 0x378D,
+ 0x23D4, 0x3733, 0x3735, 0x3791, 0x3734, 0x3736, 0x3737, 0x3738, 0x373B, 0x3748,
+ 0x3732, 0x248C, 0x373A, 0x379B, 0x379A, 0x23D7, 0x379C, 0x379F, 0x379E, 0x37A1,
+ 0x37A0, 0x37A3, 0x37A2, 0x37A5, 0x37A4, 0x37A7, 0x3749, 0x37A9, 0x37A8, 0x23F7,
+ 0x37AA, 0x37AD, 0x24A9, 0x23F5, 0x23F6, 0x37B1, 0x24B1, 0x24AF, 0x24B8, 0x24B2,
+ 0x24B4, 0x24B5, 0x24AE, 0x23DC, 0x24B7, 0x37BB, 0x37BA, 0x23E1, 0x37BC, 0x37BF,
+ 0x37BE, 0x37C1, 0x37C0, 0x37C3, 0x37C2, 0x23DE, 0x37C4, 0x2407, 0x2420, 0x240A,
+ 0x23E3, 0x2406, 0x0209, 0x23D5, 0x23D6, 0x0096, 0x0097, 0x23D9, 0x00AB, 0x23DB,
+ 0x0092, 0x23DD, 0x0099, 0x23DF, 0x23D8, 0x23DA, 0x0098, 0x008B, 0x23FE, 0x008D,
+ 0x008C, 0x008A, 0x23E0, 0x0091, 0x0090, 0x0095, 0x01DF, 0x01F5, 0x021F, 0x008E,
+ 0x008F, 0x0094, 0x0093, 0x01C9, 0x009A, 0x0215, 0x009C, 0x009B, 0x0234, 0x022A,
+ 0x01A2, 0x00A3, 0x23FF, 0x00A5, 0x00A4, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x23E2,
+ 0x24AA, 0x2489, 0x2482, 0x2481, 0x2480, 0x2485, 0x2483, 0x00AC, 0x00A2, 0x2486,
+ 0x24AD, 0x00A7, 0x00A6, 0x00A9, 0x00A8, 0x01C9, 0x00AE, 0x00AF, 0x01A2, 0x00B3,
+ 0x01C9, 0x248B, 0x01C9, 0x2A54, 0x2404, 0x2409, 0x0209, 0x240B, 0x23D0, 0x2412,
+ 0x2408, 0x00BB, 0x00BA, 0x00C1, 0x00BC, 0x00BF, 0x00BE, 0x00BD, 0x00C0, 0x01A2,
+ 0x2354, 0x2431, 0x01A2, 0x01A2, 0x2358, 0x01C9, 0x24AC, 0x00AA, 0x240C, 0x00C5,
+ 0x0209, 0x24AB, 0x23F8, 0x2424, 0x2402, 0x2484, 0x23FC, 0x23FD, 0x2488, 0x248A,
+ 0x2401, 0x2403, 0x24D8, 0x00D4, 0x009D, 0x00D2, 0x00AD, 0x00D7, 0x00D3, 0x00D5,
+ 0x00D6, 0x24BE, 0x24BC, 0x00D9, 0x24BA, 0x2498, 0x24C1, 0x24BB, 0x00D8, 0x24C3,
+ 0x24C0, 0x2490, 0x24BF, 0x2492, 0x2491, 0x2496, 0x2493, 0x00DA, 0x2497, 0x24C8,
+ 0x0198, 0x2499, 0x24C7, 0x24DC, 0x2495, 0x2494, 0x24EA, 0x24E6, 0x24E7, 0x24EB,
+ 0x24EE, 0x24CB, 0x2355, 0x24A7, 0x24C6, 0x24CC, 0x11B5, 0x2353, 0x24CA, 0x2241,
+ 0x2356, 0x2410, 0x24EC, 0x24CD, 0x24E0, 0x24E9, 0x24ED, 0x24B0, 0x24E2, 0x24BD,
+ 0x24EF, 0x24A1, 0x24C9, 0x24B3, 0x24E4, 0x240E, 0x24C2, 0x24D5, 0x1CC5, 0x1CC4,
+ 0x1CC7, 0x1CC6, 0x1CC9, 0x1CC8, 0x1CCB, 0x1CCA, 0x1CCD, 0x1CCC, 0x1CCF, 0x1CCE,
+ 0x2242, 0x1CD0, 0x1CD2, 0x1CD1, 0x2243, 0x1CD3, 0x1CD4, 0x223C, 0x223D, 0x223E,
+ 0x223F, 0x2258, 0x2259, 0x114C, 0x225A, 0x225B, 0x2254, 0x2437, 0x2438, 0x2A3F,
+ 0x1CD6, 0x1CD5, 0x1CD8, 0x1CD7, 0x1CDA, 0x2425, 0x1CDC, 0x1CDB, 0x1CDE, 0x1D02,
+ 0x1CE0, 0x1CDF, 0x1D05, 0x1CE1, 0x1D06, 0x242B, 0x1CE6, 0x1CE5, 0x2255, 0x2439,
+ 0x2429, 0x2428, 0x2256, 0x2257, 0x2250, 0x242D, 0x242F, 0x2251, 0x2430, 0x2252,
+ 0x2253, 0x2339, 0x1CE8, 0x1BC1, 0x1CEA, 0x1CE9, 0x1CEC, 0x1CEE, 0x2413, 0x1CEB,
+ 0x240D, 0x1CE7, 0x1CF2, 0x240F, 0x242E, 0x1CF3, 0x1CED, 0x1CF1, 0x1CF8, 0x1CF7,
+ 0x1CFE, 0x3514, 0x1CFF, 0x2411, 0x34FB, 0x3501, 0x1CEF, 0x1CF0, 0x1D03, 0x1D04,
+ 0x1D01, 0x1CF4, 0x1CF5, 0x1CF6, 0x1BC0, 0x234A, 0x2432, 0x11BC, 0x3507, 0x34FE,
+ 0x3516, 0x3500, 0x3510, 0x3512, 0x2436, 0x2434, 0x1CFC, 0x34FF, 0x3523, 0x2433,
+ 0x1CF9, 0x242C, 0x1D08, 0x1CFB, 0x351D, 0x3529, 0x2357, 0x1CFA, 0x351B, 0x2435,
+ 0x2426, 0x351C, 0x351F, 0x2427, 0x242A, 0x1D00, 0x1E11, 0x1E14, 0x1E13, 0x1E12,
+ 0x1E15, 0x1E10, 0x1E17, 0x1E16, 0x1E29, 0x1E28, 0x1E1B, 0x1E1A, 0x1E2D, 0x1E19,
+ 0x1E2F, 0x1E2E, 0x1E21, 0x3505, 0x1E23, 0x1E1E, 0x1E1D, 0x1E24, 0x1E1F, 0x1E22,
+ 0x1E20, 0x1E2C, 0x1E2B, 0x1E2A, 0x1E18, 0x1E25, 0x1E26, 0x1E27, 0x224C, 0x1E34,
+ 0x224D, 0x1E31, 0x1E37, 0x1E38, 0x1E32, 0x1E36, 0x1E30, 0x224E, 0x2A41, 0x1E3A,
+ 0x1E1C, 0x1E3D, 0x29FB, 0x1118, 0x1E42, 0x1E43, 0x1E44, 0x1E41, 0x351E, 0x0B7F,
+ 0x111D, 0x3522, 0x1117, 0x3525, 0x3524, 0x3503, 0x3504, 0x3528, 0x224F, 0x0B4D,
+ 0x2349, 0x2328, 0x0085, 0x351A, 0x2A16, 0x0B50, 0x112F, 0x2A15, 0x1141, 0x2329,
+ 0x2A14, 0x1144, 0x2A1A, 0x3520, 0x1143, 0x2A17, 0x232A, 0x232B, 0x34B3, 0x1146,
+ 0x34A4, 0x1110, 0x2A1B, 0x34A7, 0x34AC, 0x34B0, 0x34AA, 0x2A1F, 0x34B2, 0x1E33,
+ 0x1142, 0x34A1, 0x01A2, 0x01C9, 0x01DF, 0x0198, 0x0209, 0x0215, 0x021F, 0x01F5,
+ 0x0234, 0x022A, 0x34A0, 0x349F, 0x34A3, 0x34A6, 0x34A5, 0x2A6D, 0x112C, 0x01C9,
+ 0x0198, 0x2324, 0x2A03, 0x01A2, 0x01DF, 0x01F5, 0x0234, 0x2325, 0x34AE, 0x34AD,
+ 0x0209, 0x022A, 0x021F, 0x0215, 0x1BC2, 0x2085, 0x2070, 0x2051, 0x2056, 0x2058,
+ 0x205E, 0x2083, 0x2066, 0x2069, 0x2071, 0x207B, 0x1BC3, 0x208C, 0x1A5B, 0x2087,
+ 0x206F, 0x1BBC, 0x022A, 0x0234, 0x19B3, 0x19E3, 0x29E6, 0x022A, 0x00DE, 0x29EF,
+ 0x00DC, 0x00DD, 0x34DC, 0x00DF, 0x00E0, 0x2326, 0x2067, 0x205D, 0x2086, 0x205C,
+ 0x2076, 0x2065, 0x2064, 0x2077, 0x204A, 0x207F, 0x2073, 0x207E, 0x2080, 0x2040,
+ 0x2045, 0x01A2, 0x01F5, 0x206B, 0x01C9, 0x0215, 0x34B1, 0x021F, 0x2068, 0x34B4,
+ 0x34B5, 0x34B6, 0x34B7, 0x34B8, 0x34B9, 0x34CF, 0x34BB, 0x0209, 0x208F, 0x208E,
+ 0x0234, 0x2090, 0x2037, 0x2034, 0x203F, 0x203D, 0x2044, 0x2042, 0x204E, 0x2049,
+ 0x2054, 0x00DB, 0x205A, 0x2055, 0x206C, 0x2052, 0x350B, 0x2075, 0x0AFF, 0x2093,
+ 0x2072, 0x3532, 0x3533, 0x0B03, 0x0B04, 0x207C, 0x0B0A, 0x206D, 0x0B06, 0x2053,
+ 0x2036, 0x2033, 0x2031, 0x203C, 0x2043, 0x2041, 0x2050, 0x2046, 0x204D, 0x350A,
+ 0x204F, 0x3509, 0x2059, 0x350D, 0x205B, 0x0209, 0x01A2, 0x2048, 0x0084, 0x2047,
+ 0x0AFB, 0x0AFC, 0x0AFD, 0x206A, 0x0B01, 0x2039, 0x0B02, 0x3517, 0x207D, 0x3519,
+ 0x3518, 0x2082, 0x01C9, 0x45B6, 0x01DF, 0x0B0F, 0x0B10, 0x2A07, 0x0215, 0x2327,
+ 0x45BC, 0x2320, 0x1A67, 0x1A61, 0x45BD, 0x1A6D, 0x0B00, 0x352B, 0x352D, 0x3531,
+ 0x352C, 0x0AF8, 0x3AC8, 0x0AFA, 0x352A, 0x3AC3, 0x0AF4, 0x0AF7, 0x3AC6, 0x3AC9,
+ 0x3AC7, 0x3530, 0x3ACA, 0x0AED, 0x0D80, 0x0AEE, 0x3AC2, 0x0AEB, 0x0AEC, 0x0AEF,
+ 0x0AF0, 0x3508, 0x0AF3, 0x0AF9, 0x0AF5, 0x0AF1, 0x0AF6, 0x0AF2, 0x0E10, 0x0E90,
+ 0x0D9E, 0x0EBA, 0x0CE0, 0x0DE1, 0x0D68, 0x0D07, 0x0E2A, 0x0D84, 0x0E79, 0x0E59,
+ 0x0F8C, 0x0CA6, 0x0EB8, 0x0EA5, 0x0CA8, 0x352F, 0x352E, 0x0D2C, 0x0B0D, 0x0F9C,
+ 0x0D57, 0x0B0E, 0x0FE5, 0x0B0C, 0x0F16, 0x0ED1, 0x0B0B, 0x0F47, 0x0E64, 0x3534,
+ 0x0E10, 0x0E90, 0x3A95, 0x3A82, 0x3A83, 0x3A81, 0x0D68, 0x3A85, 0x3A87, 0x3A9B,
+ 0x3AC5, 0x3AAE, 0x3A90, 0x3A86, 0x3A9C, 0x3A88, 0x3A9A, 0x3AA1, 0x3502, 0x3A94,
+ 0x3AC4, 0x0CA8, 0x0D57, 0x3A93, 0x34F9, 0x3A8C, 0x0F16, 0x34F7, 0x3A92, 0x3A91,
+ 0x3A98, 0x3A97, 0x3A96, 0x34FA, 0x3AB3, 0x0EBA, 0x3A84, 0x0DA4, 0x3AA6, 0x0D2C,
+ 0x3AB4, 0x2089, 0x3AB8, 0x3AB7, 0x00ED, 0x3ABA, 0x3ABC, 0x3511, 0x3ABE, 0x3AB0,
+ 0x3AAF, 0x0D2C, 0x3AB1, 0x3A9D, 0x3AB5, 0x3AB6, 0x0FE5, 0x0E46, 0x3A99, 0x3A9E,
+ 0x0F68, 0x0F47, 0x0E64, 0x0DBD, 0x0E10, 0x0E90, 0x3513, 0x3ABF, 0x0CE0, 0x0DE1,
+ 0x0D68, 0x0D07, 0x3AC0, 0x350C, 0x0E79, 0x350E, 0x1CBA, 0x3AAC, 0x1CA6, 0x3515,
+ 0x350F, 0x1CB9, 0x0E10, 0x1CB3, 0x0E90, 0x0D07, 0x0CE0, 0x0D68, 0x0DE1, 0x34FD,
+ 0x01A2, 0x01C9, 0x34F8, 0x00EF, 0x00EE, 0x3AC1, 0x34FC, 0x3A9F, 0x3AA0, 0x3521,
+ 0x3AAA, 0x3AA3, 0x1CB7, 0x3AA5, 0x3506, 0x3AA7, 0x1CB8, 0x3AA9, 0x0D80, 0x1CBC,
+ 0x1CBE, 0x3AA4, 0x3ABD, 0x3AAB, 0x1E4F, 0x0D2C, 0x0FBD, 0x1E4B, 0x0D57, 0x0DA4,
+ 0x0FE5, 0x0E46, 0x0F16, 0x3AA8, 0x0F68, 0x0F47, 0x0E64, 0x0DBD, 0x3AAD, 0x1E50,
+ 0x1E4A, 0x1E45, 0x1E48, 0x1E47, 0x1CBB, 0x1E4C, 0x1CBD, 0x0D2C, 0x1CBF, 0x1CC0,
+ 0x1CC1, 0x1CC2, 0x0E79, 0x1CAE, 0x1CB2, 0x0CA8, 0x0C9E, 0x0D07, 0x0DA4, 0x0FBD,
+ 0x0F9C, 0x0D57, 0x0FE5, 0x0CE0, 0x0E46, 0x0F16, 0x0F68, 0x2035, 0x0F47, 0x0EBA,
+ 0x0D68, 0x2084, 0x0D9E, 0x0E90, 0x2074, 0x0DBD, 0x1E49, 0x0E64, 0x2079, 0x0E59,
+ 0x1E4D, 0x1E4E, 0x1E53, 0x0E2A, 0x0D84, 0x1E52, 0x0E10, 0x1E54, 0x1F49, 0x1E77,
+ 0x1E7C, 0x1F4A, 0x1E86, 0x1E6D, 0x1E72, 0x1E81, 0x1E95, 0x1E68, 0x1E9F, 0x1EB3,
+ 0x0215, 0x1E8B, 0x1EA4, 0x1F4F, 0x1EBD, 0x1E90, 0x1EC7, 0x1EC2, 0x01A2, 0x01C9,
+ 0x01DF, 0x1EAE, 0x021F, 0x1EE0, 0x1E9A, 0x1EA9, 0x0198, 0x1EF4, 0x1F03, 0x1EFE,
+ 0x3560, 0x356A, 0x1F17, 0x357A, 0x355E, 0x3574, 0x3562, 0x3576, 0x3578, 0x357E,
+ 0x1F0D, 0x1F12, 0x3582, 0x3568, 0x353B, 0x36B9, 0x01F5, 0x3584, 0x1F47, 0x1F46,
+ 0x0209, 0x1F44, 0x1F45, 0x3543, 0x01A2, 0x1F50, 0x022A, 0x0234, 0x0F47, 0x0F68,
+ 0x3566, 0x1F4B, 0x35A9, 0x1F57, 0x0F68, 0x4593, 0x4592, 0x4598, 0x4599, 0x0DBD,
+ 0x1F56, 0x1F54, 0x35A8, 0x357D, 0x1F59, 0x1F55, 0x1F5B, 0x0EBA, 0x3585, 0x3643,
+ 0x0DE1, 0x0CE0, 0x1F58, 0x0D07, 0x1F5A, 0x0E2A, 0x0E79, 0x1F5D, 0x0D84, 0x2092,
+ 0x358B, 0x0E2A, 0x2091, 0x3651, 0x3650, 0x3653, 0x3652, 0x3655, 0x3654, 0x1F21,
+ 0x1F26, 0x3659, 0x3658, 0x365B, 0x365A, 0x365D, 0x365C, 0x3657, 0x3656, 0x01A2,
+ 0x0198, 0x0D68, 0x01C9, 0x0209, 0x01F5, 0x021F, 0x0215, 0x0E10, 0x0E2A, 0x1F4D,
+ 0x1F4E, 0x0DE1, 0x0E79, 0x0FE5, 0x0234, 0x2178, 0x2176, 0x0D2C, 0x217A, 0x022A,
+ 0x217E, 0x2184, 0x0ED1, 0x0CA8, 0x35AA, 0x218C, 0x0D57, 0x0F68, 0x0DBD, 0x0E64,
+ 0x0F9C, 0x219A, 0x0EBA, 0x1FDC, 0x1FC8, 0x0CA6, 0x1FD8, 0x0EA5, 0x0E2A, 0x1FE2,
+ 0x0E59, 0x2198, 0x1FDF, 0x0F8C, 0x2196, 0x0EB8, 0x219C, 0x0E59, 0x35A5, 0x21BC,
+ 0x01C9, 0x01DF, 0x01F5, 0x35AC, 0x21A4, 0x2177, 0x2175, 0x35AB, 0x2179, 0x217F,
+ 0x217D, 0x2183, 0x2181, 0x2189, 0x2185, 0x218B, 0x0DE1, 0x0D80, 0x2187, 0x218D,
+ 0x218F, 0x3535, 0x3580, 0x219B, 0x0E79, 0x2195, 0x21A3, 0x2191, 0x2193, 0x21A7,
+ 0x3586, 0x3587, 0x21A9, 0x21A5, 0x21AD, 0x21B3, 0x21B1, 0x21BB, 0x35A7, 0x21B5,
+ 0x3590, 0x35A6, 0x21AF, 0x21B9, 0x21B7, 0x1F81, 0x01A2, 0x1F7F, 0x1F80, 0x1F7E,
+ 0x358A, 0x1F84, 0x1F86, 0x3660, 0x358D, 0x0234, 0x0215, 0x3594, 0x021F, 0x367A,
+ 0x1F83, 0x366F, 0x366E, 0x3671, 0x1F82, 0x3673, 0x3672, 0x3675, 0x3674, 0x3677,
+ 0x3676, 0x3679, 0x3678, 0x367B, 0x1F89, 0x367D, 0x367C, 0x365F, 0x365E, 0x3665,
+ 0x3680, 0x367E, 0x367F, 0x3685, 0x3664, 0x3663, 0x3661, 0x1F88, 0x1F8A, 0x3682,
+ 0x3683, 0x3684, 0x1F87, 0x1F8F, 0x138D, 0x1358, 0x1359, 0x135A, 0x1349, 0x138E,
+ 0x138F, 0x1390, 0x35B2, 0x133B, 0x1344, 0x1348, 0x1357, 0x135E, 0x1345, 0x3697,
+ 0x3696, 0x3699, 0x3698, 0x369B, 0x369A, 0x369D, 0x369C, 0x369F, 0x369E, 0x36A1,
+ 0x36A0, 0x36A3, 0x36A2, 0x36A5, 0x36A4, 0x368B, 0x36A8, 0x3693, 0x3669, 0x368A,
+ 0x36A9, 0x3662, 0x368C, 0x368E, 0x368F, 0x3690, 0x3691, 0x3692, 0x36B2, 0x3694,
+ 0x3695, 0x36B7, 0x36B6, 0x138A, 0x36B8, 0x022D, 0x0222, 0x35AF, 0x35AE, 0x1389,
+ 0x0237, 0x358C, 0x35B0, 0x139D, 0x17F2, 0x180C, 0x13A0, 0x3589, 0x36B3, 0x36B4,
+ 0x36B5, 0x36AA, 0x36AB, 0x36AC, 0x1D2D, 0x3688, 0x368D, 0x36B0, 0x3687, 0x3686,
+ 0x36AF, 0x36AE, 0x36B1, 0x1D27, 0x3644, 0x1D2E, 0x1A1F, 0x3640, 0x1D33, 0x0198,
+ 0x1D34, 0x1D35, 0x364A, 0x3642, 0x1F8D, 0x3645, 0x1F8B, 0x1D38, 0x1F8E, 0x022A,
+ 0x01F5, 0x217C, 0x45D6, 0x1376, 0x19C5, 0x01DF, 0x019E, 0x2186, 0x1374, 0x01A2,
+ 0x01C9, 0x0209, 0x021F, 0x2192, 0x2194, 0x1342, 0x1A19, 0x135C, 0x01DF, 0x135D,
+ 0x133A, 0x0198, 0x01A2, 0x3648, 0x01F5, 0x1385, 0x0209, 0x218A, 0x135B, 0x364E,
+ 0x1339, 0x0215, 0x1FCE, 0x1FED, 0x1FD7, 0x1FFB, 0x1FD6, 0x1FDD, 0x1FE7, 0x3681,
+ 0x1FCB, 0x1FCA, 0x1FCD, 0x1FCC, 0x1FCF, 0x1FFA, 0x1FD1, 0x1FD0, 0x1FD3, 0x1FD2,
+ 0x1FD5, 0x1FD4, 0x1FD9, 0x43C1, 0x1FDB, 0x1FDA, 0x19E9, 0x43D4, 0x43D9, 0x43A1,
+ 0x1FDE, 0x1FE0, 0x43D3, 0x439B, 0x1FF7, 0x1FE4, 0x1FE8, 0x1FE6, 0x1FEA, 0x1FE5,
+ 0x1FEC, 0x1FE9, 0x217B, 0x21BA, 0x21B6, 0x1FEF, 0x1FF0, 0x1FF2, 0x1FEB, 0x1FF1,
+ 0x439F, 0x1FFC, 0x43A0, 0x43AD, 0x43C4, 0x44C8, 0x447E, 0x44C9, 0x43F2, 0x1FF9,
+ 0x447F, 0x43C3, 0x1FF8, 0x1360, 0x1FF6, 0x1361, 0x443E, 0x43C2, 0x1A70, 0x440D,
+ 0x43C5, 0x3670, 0x1A6F, 0x43C9, 0x1BCE, 0x1BC8, 0x1BAE, 0x1A6E, 0x43AC, 0x440E,
+ 0x1BB2, 0x37C6, 0x01A2, 0x01DF, 0x37C7, 0x37C5, 0x0215, 0x01F5, 0x01C9, 0x0209,
+ 0x0198, 0x37C9, 0x022A, 0x37CB, 0x37CA, 0x0234, 0x37CC, 0x021F, 0x439C, 0x439D,
+ 0x43F4, 0x43F3, 0x4462, 0x4405, 0x43C8, 0x37CD, 0x37CE, 0x37CF, 0x37D0, 0x37D1,
+ 0x37D2, 0x37D3, 0x4410, 0x4407, 0x4404, 0x43F8, 0x43EC, 0x4408, 0x43EE, 0x43DE,
+ 0x1BA4, 0x43F5, 0x37E8, 0x43EF, 0x43D0, 0x43F0, 0x43F9, 0x43CE, 0x43F1, 0x37F8,
+ 0x17E8, 0x439E, 0x43CF, 0x3801, 0x19DD, 0x3803, 0x19CB, 0x43B5, 0x37FF, 0x4411,
+ 0x43D5, 0x43E5, 0x17F5, 0x17F4, 0x3802, 0x381A, 0x3819, 0x17F8, 0x17FB, 0x381B,
+ 0x381C, 0x17F9, 0x17FA, 0x443F, 0x3820, 0x1519, 0x1807, 0x4440, 0x3824, 0x17FD,
+ 0x17FE, 0x17FF, 0x17EA, 0x0209, 0x17F6, 0x17F7, 0x17EE, 0x17EB, 0x17EC, 0x17ED,
+ 0x01A5, 0x3817, 0x3816, 0x17F3, 0x019E, 0x3815, 0x17F0, 0x17EF, 0x01A2, 0x0198,
+ 0x01DF, 0x01C9, 0x0209, 0x01F5, 0x021F, 0x0215, 0x0234, 0x022A, 0x1806, 0x17E9,
+ 0x1801, 0x0198, 0x1803, 0x17F1, 0x1D21, 0x0045, 0x1D23, 0x1D22, 0x1D24, 0x1D23,
+ 0x4441, 0x1D25, 0x1D28, 0x1D20, 0x1D2A, 0x1D29, 0x1D2B, 0x1D2B, 0x1D26, 0x1D2C,
+ 0x1D2F, 0x01CC, 0x1D31, 0x1D30, 0x4464, 0x4463, 0x0215, 0x43D2, 0x0234, 0x43DD,
+ 0x154F, 0x022A, 0x444A, 0x1D39, 0x154E, 0x1535, 0x1D3E, 0x1D3D, 0x1D40, 0x1D3F,
+ 0x1D42, 0x1D41, 0x022A, 0x1B1F, 0x43D7, 0x1808, 0x43E4, 0x45A8, 0x1300, 0x19D1,
+ 0x43DC, 0x3866, 0x3865, 0x43D8, 0x3867, 0x180D, 0x3869, 0x386C, 0x386B, 0x386E,
+ 0x386D, 0x3870, 0x386F, 0x3873, 0x386A, 0x3874, 0x3872, 0x444B, 0x1C5A, 0x1C4A,
+ 0x1C4D, 0x1C50, 0x1C4F, 0x1C4E, 0x1C51, 0x1C59, 0x1C53, 0x1C65, 0x1C58, 0x3871,
+ 0x1C57, 0x1C5C, 0x1C6B, 0x38A4, 0x1C5E, 0x1C5D, 0x1C60, 0x1C5F, 0x1C63, 0x1C64,
+ 0x3888, 0x1C61, 0x1C66, 0x1C67, 0x1C68, 0x1C69, 0x1C6A, 0x1C62, 0x1C6C, 0x3898,
+ 0x3895, 0x3896, 0x3897, 0x389C, 0x3899, 0x389A, 0x389B, 0x38A0, 0x019B, 0x389E,
+ 0x389F, 0x019C, 0x389D, 0x38A1, 0x38A3, 0x1C52, 0x1C6D, 0x1C6E, 0x1C6F, 0x1C70,
+ 0x20C5, 0x20C2, 0x20C7, 0x20C8, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x1C5B, 0x20C6,
+ 0x38C4, 0x38B6, 0x38B5, 0x38BC, 0x38B7, 0x38BA, 0x0218, 0x020C, 0x38BB, 0x01F8,
+ 0x38BD, 0x38BE, 0x38BF, 0x38B9, 0x38A2, 0x38C0, 0x01F5, 0x38D5, 0x38D6, 0x0198,
+ 0x01DF, 0x38DC, 0x01A2, 0x38DA, 0x38DB, 0x01C9, 0x20AB, 0x20AC, 0x0215, 0x0234,
+ 0x20B0, 0x0209, 0x38D9, 0x021F, 0x0198, 0x01A2, 0x01C9, 0x01DF, 0x01F5, 0x0209,
+ 0x01E2, 0x021F, 0x20C1, 0x0234, 0x20C3, 0x20C4, 0x20AD, 0x38D7, 0x0215, 0x38E6,
+ 0x38E5, 0x20AE, 0x38E7, 0x38EA, 0x38E9, 0x38EC, 0x38EB, 0x38DD, 0x38E4, 0x38F0,
+ 0x38DF, 0x38ED, 0x38EE, 0x38E3, 0x022A, 0x20AF, 0x1564, 0x1565, 0x155F, 0x155D,
+ 0x4573, 0x0209, 0x1558, 0x0234, 0x09CC, 0x155E, 0x1A9B, 0x09E3, 0x38E0, 0x38F4,
+ 0x38DE, 0x093B, 0x09EA, 0x38FF, 0x092A, 0x0A4C, 0x1449, 0x0A59, 0x09EA, 0x1445,
+ 0x2321, 0x1441, 0x0A05, 0x4516, 0x43E0, 0x2322, 0x451B, 0x390D, 0x390C, 0x1448,
+ 0x390E, 0x3911, 0x3910, 0x4543, 0x4544, 0x4545, 0x4542, 0x44A7, 0x44A6, 0x1A77,
+ 0x0209, 0x44C5, 0x44AD, 0x451E, 0x01F5, 0x451F, 0x45AA, 0x1AAD, 0x449E, 0x45BE,
+ 0x1440, 0x4595, 0x45C2, 0x145F, 0x1444, 0x1443, 0x1300, 0x1463, 0x1AA7, 0x45C0,
+ 0x43C0, 0x449F, 0x44A0, 0x44A1, 0x021F, 0x45A2, 0x01C9, 0x1BA7, 0x01C9, 0x1B2B,
+ 0x022A, 0x4497, 0x45C3, 0x1BA3, 0x2323, 0x45AC, 0x1442, 0x231C, 0x4594, 0x0215,
+ 0x231D, 0x143F, 0x1522, 0x44F0, 0x455E, 0x4557, 0x38E1, 0x440A, 0x38E2, 0x43E1,
+ 0x44D2, 0x1456, 0x01F5, 0x20BD, 0x38C8, 0x455F, 0x440B, 0x20B6, 0x20B7, 0x20B8,
+ 0x4406, 0x20BA, 0x20BB, 0x4401, 0x44F1, 0x12FC, 0x12FC, 0x12FC, 0x12FC, 0x12FC,
+ 0x440C, 0x231E, 0x12FD, 0x4584, 0x4585, 0x12FE, 0x4588, 0x44C3, 0x4589, 0x44C4,
+ 0x44C2, 0x1300, 0x45A0, 0x450A, 0x0297, 0x0298, 0x02B2, 0x0293, 0x0301, 0x0302,
+ 0x0347, 0x02D1, 0x0460, 0x0415, 0x042E, 0x1477, 0x0402, 0x063F, 0x0512, 0x0486,
+ 0x0513, 0x0520, 0x051C, 0x0521, 0x0533, 0x0516, 0x0528, 0x035E, 0x057F, 0x053E,
+ 0x05EA, 0x0584, 0x0640, 0x0651, 0x0527, 0x063D, 0x0689, 0x0720, 0x06EF, 0x06DC,
+ 0x1490, 0x066A, 0x07F5, 0x076A, 0x082B, 0x086C, 0x09A1, 0x148B, 0x1476, 0x0721,
+ 0x04AD, 0x1495, 0x1489, 0x0059, 0x148A, 0x148E, 0x148F, 0x4400, 0x231F, 0x1528,
+ 0x081C, 0x148D, 0x1492, 0x0234, 0x45C1, 0x236A, 0x0058, 0x14AB, 0x14E0, 0x1488,
+ 0x005A, 0x01F5, 0x14E4, 0x01A2, 0x0056, 0x01DF, 0x0198, 0x0054, 0x149D, 0x0055,
+ 0x0053, 0x1473, 0x1494, 0x391B, 0x391D, 0x3937, 0x391C, 0x391A, 0x393D, 0x391E,
+ 0x391F, 0x392F, 0x3922, 0x3931, 0x3921, 0x392B, 0x3920, 0x3933, 0x3923, 0x3928,
+ 0x392E, 0x3932, 0x3929, 0x3927, 0x05BE, 0x0303, 0x02B3, 0x0487, 0x0641, 0x0388,
+ 0x05D7, 0x0405, 0x0377, 0x053F, 0x0647, 0x0655, 0x394B, 0x394C, 0x058E, 0x0582,
+ 0x393E, 0x0543, 0x3939, 0x394E, 0x04AE, 0x394F, 0x3938, 0x05EF, 0x393A, 0x03A0,
+ 0x06DF, 0x0409, 0x0304, 0x394A, 0x039C, 0x0378, 0x046E, 0x3949, 0x3948, 0x0488,
+ 0x3930, 0x05CB, 0x394D, 0x3947, 0x3926, 0x066D, 0x3936, 0x00FE, 0x0309, 0x029F,
+ 0x0358, 0x034C, 0x0354, 0x035D, 0x0523, 0x0406, 0x0102, 0x0100, 0x3950, 0x3A0E,
+ 0x01DF, 0x0648, 0x06F2, 0x3A0C, 0x3A0D, 0x3A1F, 0x3A1E, 0x3A13, 0x3A11, 0x3A12,
+ 0x3A1D, 0x3A1C, 0x3A20, 0x3A16, 0x3A17, 0x3A21, 0x3A10, 0x01C9, 0x3A0F, 0x3A1B,
+ 0x39D6, 0x3A15, 0x3943, 0x01DF, 0x393C, 0x393B, 0x00F1, 0x393F, 0x3940, 0x3941,
+ 0x01C9, 0x3945, 0x3944, 0x3942, 0x3946, 0x39D4, 0x39D3, 0x39C3, 0x39C4, 0x39C1,
+ 0x39C2, 0x39D2, 0x39C8, 0x01A2, 0x39D1, 0x39C6, 0x39D5, 0x00FF, 0x39C7, 0x0101,
+ 0x39D7, 0x39D8, 0x45C4, 0x39DA, 0x39DB, 0x39DD, 0x14E6, 0x14E5, 0x39DF, 0x39E1,
+ 0x39E0, 0x39E3, 0x39E2, 0x1534, 0x14D0, 0x39E6, 0x14E3, 0x39E8, 0x1B0D, 0x148C,
+ 0x39EB, 0x39EC, 0x1B13, 0x1527, 0x39EE, 0x39F1, 0x39F0, 0x39F3, 0x39F2, 0x14E2,
+ 0x1B31, 0x1A89, 0x14A6, 0x14E1, 0x45A5, 0x147D, 0x1AA1, 0x45B7, 0x0209, 0x01A2,
+ 0x1460, 0x0057, 0x1A7D, 0x01F5, 0x01F5, 0x01C9, 0x01DF, 0x00F4, 0x0048, 0x14D1,
+ 0x45A3, 0x05A0, 0x05B5, 0x05A2, 0x0047, 0x059C, 0x05B2, 0x1B07, 0x45AD, 0x45A7,
+ 0x45AB, 0x45A4, 0x0661, 0x0657, 0x05E2, 0x39CB, 0x031D, 0x3A19, 0x0662, 0x0658,
+ 0x0364, 0x3A1A, 0x033D, 0x39CF, 0x0629, 0x3A14, 0x0328, 0x0344, 0x036F, 0x0343,
+ 0x39FA, 0x0209, 0x00F5, 0x39C9, 0x0639, 0x0259, 0x39CD, 0x39CE, 0x026C, 0x3A18,
+ 0x01A2, 0x031A, 0x00F6, 0x0273, 0x0241, 0x00F7, 0x0607, 0x39F8, 0x39F7, 0x0330,
+ 0x39F9, 0x39FC, 0x39FB, 0x39FE, 0x39FD, 0x0314, 0x39FF, 0x3A02, 0x3A01, 0x0325,
+ 0x3A03, 0x3A0A, 0x3A05, 0x3A09, 0x050B, 0x01F5, 0x047B, 0x3A08, 0x0209, 0x04EF,
+ 0x39D0, 0x01A2, 0x39CA, 0x39CC, 0x0505, 0x3A07, 0x00F0, 0x39C5, 0x3A0B, 0x04C5,
+ 0x0481, 0x047A, 0x0482, 0x04CB, 0x04A2, 0x0494, 0x04A4, 0x0496, 0x04A6, 0x0498,
+ 0x04A5, 0x0497, 0x062C, 0x0573, 0x04F6, 0x04CC, 0x05E4, 0x0615, 0x0637, 0x04E1,
+ 0x04DC, 0x05D4, 0x0638, 0x04DE, 0x0C30, 0x0C31, 0x060A, 0x0617, 0x04F5, 0x0616,
+ 0x0C36, 0x34DF, 0x34DD, 0x04DB, 0x0C42, 0x34E4, 0x34DE, 0x34E1, 0x34E2, 0x34E6,
+ 0x34E5, 0x34E8, 0x34E7, 0x0508, 0x34E9, 0x34E3, 0x34EB, 0x0C3F, 0x0C40, 0x0C41,
+ 0x0677, 0x0C43, 0x0681, 0x01A2, 0x00FB, 0x00FC, 0x067B, 0x0678, 0x01DF, 0x34EA,
+ 0x0C44, 0x0697, 0x34EC, 0x0685, 0x0696, 0x033E, 0x06D5, 0x0C2F, 0x0C34, 0x0C35,
+ 0x06CE, 0x0341, 0x06D8, 0x06B9, 0x0C3A, 0x0C33, 0x068F, 0x05C3, 0x0686, 0x0684,
+ 0x0254, 0x0242, 0x026F, 0x026D, 0x026E, 0x027F, 0x0283, 0x0258, 0x0257, 0x067D,
+ 0x0246, 0x0322, 0x0243, 0x068E, 0x0247, 0x06AD, 0x0274, 0x1533, 0x0272, 0x06CB,
+ 0x05CF, 0x1FA4, 0x1A83, 0x34ED, 0x34EE, 0x34EF, 0x0248, 0x0271, 0x0284, 0x0244,
+ 0x34F4, 0x0336, 0x04EC, 0x0333, 0x0315, 0x04C3, 0x1FA6, 0x04C2, 0x04ED, 0x1B25,
+ 0x43FF, 0x04EE, 0x1B99, 0x45A9, 0x04C4, 0x050A, 0x45A6, 0x1B97, 0x4359, 0x06D9,
+ 0x05C4, 0x4363, 0x4361, 0x4366, 0x03B0, 0x06CF, 0x067A, 0x06AA, 0x0266, 0x05A9,
+ 0x0672, 0x030E, 0x05BA, 0x145C, 0x0635, 0x0613, 0x1451, 0x1C85, 0x06BC, 0x06B0,
+ 0x06BB, 0x06AF, 0x06B8, 0x06AC, 0x045B, 0x0449, 0x1450, 0x06C4, 0x06C5, 0x435A,
+ 0x4358, 0x435E, 0x435C, 0x4364, 0x06A8, 0x4367, 0x4362, 0x4371, 0x4369, 0x436B,
+ 0x436E, 0x4360, 0x4374, 0x34E0, 0x4378, 0x06B5, 0x07AD, 0x07B5, 0x07B1, 0x34F1,
+ 0x34F2, 0x34F3, 0x0794, 0x34F5, 0x34F6, 0x07AC, 0x07B9, 0x0172, 0x4376, 0x437A,
+ 0x438E, 0x0168, 0x01C9, 0x0770, 0x459A, 0x459D, 0x077F, 0x0771, 0x0198, 0x01F5,
+ 0x016B, 0x077B, 0x0780, 0x0169, 0x0887, 0x077E, 0x077D, 0x0151, 0x0158, 0x079E,
+ 0x014E, 0x014F, 0x0150, 0x0153, 0x0152, 0x0796, 0x0154, 0x0157, 0x0156, 0x015A,
+ 0x0798, 0x079B, 0x0155, 0x016C, 0x016D, 0x016E, 0x015E, 0x015D, 0x015C, 0x0163,
+ 0x0174, 0x0166, 0x0161, 0x0164, 0x0165, 0x0160, 0x016A, 0x0162, 0x0159, 0x079C,
+ 0x0167, 0x19B9, 0x0809, 0x0806, 0x1BA8, 0x0807, 0x0804, 0x015B, 0x18C5, 0x19BF,
+ 0x080B, 0x150C, 0x152E, 0x0805, 0x080F, 0x150B, 0x0843, 0x083F, 0x0845, 0x0841,
+ 0x0844, 0x0840, 0x0846, 0x0842, 0x0852, 0x0811, 0x0854, 0x0813, 0x0853, 0x0808,
+ 0x0855, 0x0812, 0x1843, 0x1847, 0x0888, 0x1848, 0x0871, 0x1FAE, 0x1849, 0x0879,
+ 0x080E, 0x1FA7, 0x0810, 0x1851, 0x086E, 0x0876, 0x184F, 0x1855, 0x0877, 0x0873,
+ 0x0776, 0x0777, 0x07D0, 0x0740, 0x07A5, 0x07A3, 0x1A25, 0x088F, 0x0847, 0x0890,
+ 0x080A, 0x0880, 0x087E, 0x1863, 0x1FA3, 0x1865, 0x1864, 0x1862, 0x2338, 0x18DD,
+ 0x18E3, 0x233A, 0x07B3, 0x18BF, 0x18CB, 0x1FBA, 0x18E9, 0x1FB4, 0x1FB3, 0x07B2,
+ 0x07A2, 0x079F, 0x233B, 0x079A, 0x0799, 0x0795, 0x0797, 0x079D, 0x07BB, 0x1BD4,
+ 0x07B8, 0x07B0, 0x07B6, 0x1BD3, 0x07BA, 0x07A1, 0x1955, 0x195B, 0x1961, 0x1BBD,
+ 0x196D, 0x1A2B, 0x1979, 0x194F, 0x0215, 0x145B, 0x198B, 0x1991, 0x197F, 0x1985,
+ 0x1973, 0x19A9, 0x1A07, 0x2334, 0x2335, 0x2336, 0x2337, 0x2330, 0x2331, 0x2332,
+ 0x2333, 0x232C, 0x232D, 0x19FB, 0x232E, 0x199D, 0x19A3, 0x1A01, 0x1BCF, 0x232F,
+ 0x07A9, 0x07A6, 0x2308, 0x07A4, 0x07A8, 0x07A7, 0x0781, 0x2309, 0x07BC, 0x07BD,
+ 0x230A, 0x07BE, 0x230B, 0x2304, 0x01F5, 0x2305, 0x2306, 0x2307, 0x0209, 0x0215,
+ 0x021F, 0x1466, 0x2300, 0x0234, 0x2301, 0x2302, 0x022A, 0x2303, 0x22FC, 0x22FD,
+ 0x22FE, 0x22FF, 0x2318, 0x22EA, 0x22EB, 0x22E4, 0x234B, 0x234C, 0x2344, 0x2340,
+ 0x234E, 0x115F, 0x1171, 0x1172, 0x116B, 0x116C, 0x116D, 0x116E, 0x0884, 0x0881,
+ 0x1166, 0x087F, 0x0883, 0x0882, 0x0814, 0x0815, 0x0897, 0x0898, 0x1167, 0x1168,
+ 0x1FB8, 0x1169, 0x1FB7, 0x1162, 0x1FBB, 0x1163, 0x1164, 0x1165, 0x113F, 0x1140,
+ 0x2A10, 0x2A11, 0x2A20, 0x2A21, 0x2A23, 0x2A19, 0x021F, 0x3A5E, 0x3A5D, 0x3A60,
+ 0x3A5F, 0x3A62, 0x3A61, 0x3A64, 0x3A63, 0x10F3, 0x10F4, 0x3A67, 0x10ED, 0x3A69,
+ 0x3A68, 0x3A6B, 0x3A6A, 0x3A6D, 0x10EE, 0x3A6F, 0x01C9, 0x01DF, 0x0198, 0x01A2,
+ 0x3A72, 0x3A75, 0x10EF, 0x10E6, 0x3A76, 0x3A79, 0x3A78, 0x10E7, 0x3A7A, 0x3A7D,
+ 0x3A7C, 0x3A7F, 0x3A7E, 0x11DB, 0x3A80, 0x0FE2, 0x0005, 0x0FFF, 0x0F3A, 0x01A2,
+ 0x0EE9, 0x0103, 0x0209, 0x0105, 0x0104, 0x0EC9, 0x0ECA, 0x0ECB, 0x0EE5, 0x0EA1,
+ 0x0EA2, 0x0EA3, 0x0D01, 0x0D02, 0x0D03, 0x0D17, 0x0EDB, 0x0F23, 0x0F73, 0x0DF0,
+ 0x0CED, 0x399B, 0x399C, 0x39A7, 0x0D09, 0x399F, 0x39A0, 0x39A1, 0x39A2, 0x39A3,
+ 0x39A4, 0x39A5, 0x39A6, 0x0CAE, 0x39A8, 0x39A9, 0x39AA, 0x398D, 0x398C, 0x399E,
+ 0x399D, 0x398B, 0x3990, 0x0F81, 0x3992, 0x0F82, 0x0F30, 0x398F, 0x3995, 0x3991,
+ 0x0F33, 0x2104, 0x2106, 0x2108, 0x20FA, 0x20FC, 0x398E, 0x20FE, 0x2100, 0x20F2,
+ 0x20F4, 0x20F6, 0x20F8, 0x20EA, 0x20EC, 0x20EE, 0x20F0, 0x126A, 0x3994, 0x0CE6,
+ 0x0E36, 0x0DE3, 0x0DE4, 0x0DE6, 0x0DF9, 0x0DF8, 0x0DD3, 0x0E1B, 0x0E38, 0x0DF2,
+ 0x0DF4, 0x0DF7, 0x0D6F, 0x0E1D, 0x0E1E, 0x0E37, 0x39AE, 0x0CA0, 0x39BE, 0x1DD8,
+ 0x0DED, 0x0DEE, 0x0E4D, 0x0E5D, 0x0DCC, 0x0DEC, 0x0DC8, 0x0DEA, 0x0E01, 0x0D66,
+ 0x0D3E, 0x39BB, 0x39BC, 0x39BD, 0x3A34, 0x39BF, 0x39C0, 0x3A32, 0x3A33, 0x3A36,
+ 0x01A2, 0x01F5, 0x0109, 0x3A37, 0x3996, 0x0D3F, 0x3993, 0x0D74, 0x3998, 0x3999,
+ 0x0D61, 0x0D38, 0x0D39, 0x0DFC, 0x0DFD, 0x1DD7, 0x1D82, 0x1D90, 0x1DE3, 0x1DE4,
+ 0x1DC9, 0x1DCA, 0x399A, 0x1DE1, 0x1DE2, 0x1DE6, 0x0E24, 0x0CA3, 0x1DCD, 0x0E67,
+ 0x0E16, 0x0DD2, 0x0F79, 0x0F57, 0x0E9A, 0x3997, 0x0CB3, 0x1D9F, 0x1DA2, 0x1DA5,
+ 0x1D8F, 0x3A4E, 0x1D96, 0x1D9A, 0x3A4D, 0x1D9B, 0x1D81, 0x1D83, 0x1D86, 0x1D8A,
+ 0x1D76, 0x3A4C, 0x1D78, 0x1D7A, 0x1D7E, 0x3A4B, 0x1DC6, 0x3A5C, 0x3A5B, 0x3A4F,
+ 0x3A50, 0x3A51, 0x3A52, 0x3A53, 0x3A54, 0x3A55, 0x3A56, 0x3A59, 0x3A58, 0x0F7B,
+ 0x3A5A, 0x0F4F, 0x01F5, 0x0F19, 0x0FEB, 0x0CB4, 0x010F, 0x0CF3, 0x0F6C, 0x01A2,
+ 0x01DF, 0x0110, 0x01C9, 0x0F78, 0x3A57, 0x0F80, 0x010E, 0x0F6E, 0x0B28, 0x0B3D,
+ 0x0B44, 0x02D0, 0x0B2C, 0x46F1, 0x0357, 0x47F1, 0x47F6, 0x4810, 0x03BD, 0x0389,
+ 0x03BD, 0x03BD, 0x03AD, 0x03B2, 0x47C5, 0x47C7, 0x47CA, 0x47E4, 0x47A5, 0x47A8,
+ 0x47AD, 0x479A, 0x479E, 0x479F, 0x48A0, 0x48AD, 0x486A, 0x0578, 0x48CA, 0x489E,
+ 0x2B0B, 0x2B0C, 0x2B2A, 0x2B04, 0x2B06, 0x2B08, 0x2B09, 0x2AFF, 0x2B00, 0x2B01,
+ 0x2B02, 0x2AFB, 0x2AFC, 0x02AE, 0x2AFD, 0x2AFE, 0x0372, 0x0346, 0x0485, 0x037C,
+ 0x0BE5, 0x04E6, 0x0BEE, 0x0BEB, 0x2ACE, 0x0BF1, 0x2AD0, 0x2AD2, 0x0767, 0x2AD4,
+ 0x081B, 0x0769, 0x2AC8, 0x2AC9, 0x2ACB, 0x2ACC, 0x2AC3, 0x2AC4, 0x032A, 0x02EF,
+ 0x2AC5, 0x2AC6, 0x2ABA, 0x03E2, 0x037B, 0x2ABC, 0x2ABF, 0x2AC1, 0x01C8, 0x2AE4,
+ 0x01C2, 0x01C0, 0x01C4, 0x01DD, 0x2A94, 0x2A97, 0x2A9A, 0x0208, 0x2A85, 0x2A8E,
+ 0x0214, 0x01F4, 0x01BF, 0x0229, 0x03DD, 0x2A79, 0x03F9, 0x03F7, 0x2BDE, 0x03F6,
+ 0x2BD5, 0x2B97, 0x0BF5, 0x0C0C, 0x0C0F, 0x0BFF, 0x0C02, 0x0C0A, 0x0C06, 0x0458,
+ 0x0BF4, 0x0BF8, 0x0BFC, 0x0BE4, 0x0BE9, 0x0BED, 0x0BF0, 0x0369, 0x05AA, 0x05AB,
+ 0x0367, 0x036A, 0x036B, 0x0447, 0x0368, 0x0C01, 0x0C04, 0x19B1, 0x02DB, 0x0BB8,
+ 0x0069, 0x02DA, 0x0BCF, 0x0068, 0x01A1, 0x0215, 0x19AE, 0x19AF, 0x006C, 0x19B0,
+ 0x0BBA, 0x006A, 0x0C90, 0x0C83, 0x0C91, 0x0FDE, 0x0C8C, 0x0C85, 0x19AA, 0x19AB,
+ 0x19AC, 0x18D7, 0x0FCB, 0x1895, 0x189B, 0x18A1, 0x1D9E, 0x1D7C, 0x1D85, 0x1D88,
+ 0x1D8B, 0x1D89, 0x1D95, 0x1DC5, 0x101C, 0x1DEA, 0x1DEB, 0x0DA9, 0x0DA8, 0x1AD1,
+ 0x0D89, 0x0DB2, 0x0DB1, 0x0D90, 0x0F0B, 0x0F0C, 0x0F08, 0x0EFE, 0x01F5, 0x0209,
+ 0x021F, 0x0198, 0x01A2, 0x1FB9, 0x1FB5, 0x1FB6, 0x19D7, 0x1A4F, 0x1A43, 0x1A49,
+ 0x1A31, 0x1A37, 0x1AC5, 0x1A3D, 0x1A71, 0x1ABF, 0x1F9F, 0x1FA0, 0x1ACB, 0x1FA1,
+ 0x1FA2, 0x1F9B, 0x1F9C, 0x1F9E, 0x1F99, 0x1F93, 0x1F94, 0x1F96, 0x1FB0, 0x1FB2,
+ 0x1FAB, 0x1FAD, 0x1FA8, 0x1FA5, 0x1A0D, 0x1A13, 0x19EF, 0x19F5, 0x150D, 0x1507,
+ 0x1508, 0x150A, 0x1503, 0x1504, 0x1FAA, 0x1BC7, 0x1BA5, 0x1BCA, 0x1BCB, 0x1BCC,
+ 0x1BCD, 0x1BC4, 0x1BC5, 0x1BC6, 0x1BC9, 0x45D7, 0x45D8, 0x45D2, 0x45D3, 0x45D4,
+ 0x45D5, 0x1BB0, 0x1BB1, 0x1BB3, 0x1BA0, 0x1BAD, 0x1BAF, 0x1BA9, 0x1BAA, 0x1BAB,
+ 0x1BAC, 0x459B, 0x459C, 0x4596, 0x4597, 0x1B19, 0x1AEF, 0x1AF5, 0x1FA9, 0x1AFB,
+ 0x1B01, 0x1AD7, 0x1FB1, 0x1ADD, 0x1AE3, 0x1AE9, 0x02A2, 0x089B, 0x06FF, 0x0700,
+ 0x0524, 0x0701, 0x20E1, 0x20E3, 0x20E5, 0x20E7, 0x20D9, 0x20DB, 0x20DD, 0x20DF,
+ 0x20D1, 0x20D3, 0x20D5, 0x20D7, 0x20C9, 0x20CB, 0x20CD, 0x20CF, 0x0594, 0x05C7,
+ 0x063E, 0x0646, 0x0591, 0x058C, 0x0592, 0x0593, 0x051B, 0x0579, 0x057C, 0x0590,
+ 0x0519, 0x0517, 0x0518, 0x051A, 0x06A0, 0x06A1, 0x06C6, 0x06A4, 0x06A5, 0x069E,
+ 0x4792, 0x47F5, 0x47B1, 0x47E9, 0x470F, 0x4845, 0x46CD, 0x4609, 0x4608, 0x47A4,
+ 0x47C1, 0x47C6, 0x4869, 0x45E8, 0x46F8, 0x472C, 0x4760, 0x4839, 0x1B9F, 0x46CC,
+ 0x1505, 0x1509, 0x47EF, 0x482C, 0x48AF, 0x4687, 0x4742, 0x478E, 0x47E3, 0x45F2,
+ 0x4899, 0x4875, 0x488F, 0x4893, 0x4718, 0x1C8D, 0x1C86, 0x1C87, 0x1C88, 0x1459,
+ 0x145A, 0x1457, 0x1458, 0x1452, 0x1453, 0x1454, 0x1BA2, 0x1455, 0x144E, 0x144F,
+ 0x1467, 0x0043, 0x0044, 0x151F, 0x1520, 0x1521, 0x145E, 0x143B, 0x151B, 0x1436,
+ 0x1531, 0x440F, 0x4402, 0x4403, 0x43EA, 0x43EB, 0x43ED, 0x43E6, 0x43E7, 0x43E8,
+ 0x43E9, 0x43E2, 0x43E3, 0x43BE, 0x43BF, 0x439A, 0x4482, 0x4483, 0x1506, 0x4458,
+ 0x4459, 0x4452, 0x4453, 0x4454, 0x4455, 0x446E, 0x446F, 0x446B, 0x4468, 0x4469,
+ 0x4465, 0x443A, 0x443B, 0x443C, 0x443D, 0x4436, 0x4437, 0x4438, 0x4439, 0x4432,
+ 0x1FAF, 0x4433, 0x4434, 0x4435, 0x444E, 0x444F, 0x1FAC, 0x4503, 0x44D8, 0x44D9,
+ 0x44D3, 0x44D4, 0x44D5, 0x44EE, 0x44EF, 0x44EA, 0x44EB, 0x44EC, 0x44ED, 0x44E6,
+ 0x44E7, 0x44E8, 0x44E9, 0x44E2, 0x44E3, 0x44BE, 0x44BF, 0x449A, 0x449B, 0x44AC,
+ 0x4582, 0x4583, 0x4560, 0x4561, 0x455A, 0x455B, 0x455C, 0x455D, 0x4556, 0x4538,
+ 0x4539, 0x4532, 0x4533, 0x451A, 0x451C, 0x451D, 0x4518, 0x4519, 0x4512, 0x2608,
+ 0x2630, 0x25BF, 0x25D5, 0x2701, 0x01F5, 0x0209, 0x0198, 0x01A2, 0x13A8, 0x13AA,
+ 0x26E9, 0x26EA, 0x26E7, 0x26E3, 0x26E4, 0x26DD, 0x26DE, 0x26DF, 0x26E0, 0x26F9,
+ 0x26FA, 0x26FB, 0x26FC, 0x26F5, 0x26F6, 0x26F7, 0x26F8, 0x26F1, 0x26F2, 0x26ED,
+ 0x26EF, 0x26F0, 0x26C9, 0x26CA, 0x26CB, 0x1F95, 0x26CC, 0x26C5, 0x26C6, 0x26C7,
+ 0x26C8, 0x26C1, 0x26C2, 0x26C0, 0x26D3, 0x26CD, 0x26CE, 0x09ED, 0x09EC, 0x0A28,
+ 0x09F2, 0x0A3B, 0x14E7, 0x0940, 0x13A6, 0x13A7, 0x13A1, 0x09CF, 0x09CC, 0x0A18,
+ 0x0A17, 0x0702, 0x06F8, 0x03A2, 0x03A1, 0x02E9, 0x0371, 0x04B9, 0x0596, 0x0597,
+ 0x05F6, 0x030D, 0x0472, 0x048E, 0x0526, 0x0525, 0x050F, 0x04E5, 0x1F9A, 0x0462,
+ 0x0461, 0x0438, 0x045F, 0x045E, 0x0435, 0x0434, 0x0437, 0x0436, 0x0599, 0x0598,
+ 0x066C, 0x066B, 0x0558, 0x0557, 0x057E, 0x057D, 0x054A, 0x0549, 0x0556, 0x0555,
+ 0x0542, 0x0541, 0x0548, 0x0547, 0x070D, 0x070C, 0x070F, 0x070E, 0x05E8, 0x05DC,
+ 0x070A, 0x0723, 0x0722, 0x03C9, 0x03C8, 0x13ED, 0x13EE, 0x0265, 0x02DC, 0x028F,
+ 0x0264, 0x028B, 0x0260, 0x028D, 0x028E, 0x0263, 0x0373, 0x05BD, 0x13F2, 0x13F1,
+ 0x13F7, 0x13F8, 0x13EF, 0x13F4, 0x13F0, 0x13F3, 0x13DD, 0x13DE, 0x13DA, 0x13DB,
+ 0x13DC, 0x13D7, 0x13D8, 0x13D9, 0x13E3, 0x13F6, 0x13E7, 0x13E8, 0x13E5, 0x13E6,
+ 0x13E2, 0x13E4, 0x13DF, 0x13E0, 0x13E1, 0x1049, 0x104A, 0x048C, 0x1047, 0x1048,
+ 0x1043, 0x1044, 0x0401, 0x1058, 0x1059, 0x105A, 0x105B, 0x1054, 0x1055, 0x1056,
+ 0x1057, 0x1050, 0x1F97, 0x1F9D, 0x1051, 0x1052, 0x1F98, 0x1053, 0x104C, 0x104D,
+ 0x104E, 0x104F, 0x1064, 0x0397, 0x046C, 0x1061, 0x0576, 0x0568, 0x0393, 0x0387,
+ 0x042C, 0x0423, 0x02BC, 0x02BB, 0x0530, 0x052F, 0x043B, 0x05F8, 0x0419, 0x06A3,
+ 0x071C, 0x064B, 0x0470, 0x071E, 0x071D, 0x05BB, 0x05A8, 0x02B5, 0x02B4, 0x04B4,
+ 0x04B3, 0x02D5, 0x02D4, 0x332E, 0x332F, 0x332A, 0x332B, 0x3328, 0x3329, 0x3322,
+ 0x3323, 0x3324, 0x3325, 0x333E, 0x333F, 0x3340, 0x3341, 0x333A, 0x333B, 0x333C,
+ 0x333D, 0x3336, 0x3337, 0x3338, 0x3339, 0x3332, 0x3333, 0x3334, 0x3335, 0x330E,
+ 0x330F, 0x3310, 0x3311, 0x330A, 0x330B, 0x330C, 0x330D, 0x3306, 0x3307, 0x3308,
+ 0x3309, 0x3302, 0x3303, 0x3304, 0x3305, 0x331E, 0x331F, 0x3320, 0x3321, 0x331A,
+ 0x331B, 0x331C, 0x331D, 0x3316, 0x3317, 0x3318, 0x3319, 0x3312, 0x3313, 0x3314,
+ 0x3315, 0x32EE, 0x32EF, 0x32F0, 0x32F1, 0x32EA, 0x32EB, 0x32EC, 0x32ED, 0x32E6,
+ 0x32E7, 0x32F2, 0x32F3, 0x32D1, 0x32C8, 0x32C9, 0x32C2, 0x32C3, 0x32C4, 0x32C5,
+ 0x32DE, 0x32DF, 0x32E0, 0x32E1, 0x32DA, 0x32DB, 0x32DC, 0x32DD, 0x32D6, 0x32D7,
+ 0x32D8, 0x32D9, 0x32D2, 0x32D3, 0x32D4, 0x32D5, 0x336C, 0x336A, 0x336D, 0x336E,
+ 0x3367, 0x3368, 0x336B, 0x3369, 0x3363, 0x3364, 0x01F5, 0x0209, 0x0198, 0x01A2,
+ 0x12BA, 0x12BC, 0x3373, 0x3374, 0x12EE, 0x12CB, 0x12B1, 0x12B2, 0x12B3, 0x12B4,
+ 0x12AC, 0x12B0, 0x335B, 0x335C, 0x335D, 0x335E, 0x3357, 0x3358, 0x3359, 0x335A,
+ 0x3353, 0x3354, 0x12CA, 0x12D1, 0x12AA, 0x12E8, 0x12EA, 0x12EB, 0x12EC, 0x12E3,
+ 0x12E4, 0x12E5, 0x12E6, 0x12DF, 0x12E0, 0x12E1, 0x12E2, 0x12D7, 0x12D9, 0x12DC,
+ 0x12DE, 0x12F9, 0x12F7, 0x12F8, 0x334E, 0x12F3, 0x12F4, 0x12B8, 0x12B9, 0x12AD,
+ 0x12AE, 0x12AF, 0x12B5, 0x12D0, 0x12D4, 0x12D5, 0x12D6, 0x12CC, 0x12CD, 0x2628,
+ 0x2629, 0x261E, 0x261F, 0x2621, 0x261A, 0x261B, 0x25EF, 0x25F0, 0x25E6, 0x25E7,
+ 0x25E8, 0x25E9, 0x25E3, 0x25E4, 0x25E5, 0x2603, 0x2604, 0x2605, 0x2606, 0x25FC,
+ 0x25FF, 0x2600, 0x2602, 0x01B2, 0x25F8, 0x25F9, 0x25F3, 0x020F, 0x0230, 0x25F5,
+ 0x01B3, 0x023A, 0x01B5, 0x01B4, 0x01B7, 0x01B6, 0x01B9, 0x01B8, 0x25F7, 0x01BA,
+ 0x25CD, 0x25CE, 0x0024, 0x0019, 0x0027, 0x0026, 0x0029, 0x0028, 0x002B, 0x002A,
+ 0x001A, 0x25CF, 0x001C, 0x001B, 0x25D0, 0x25C9, 0x25CA, 0x25CB, 0x25CC, 0x25C5,
+ 0x25C6, 0x25C4, 0x25D8, 0x25D1, 0x25D2, 0x25AB, 0x25AD, 0x25AE, 0x25AF, 0x25AA,
+ 0x25A4, 0x25A6, 0x259F, 0x25BE, 0x25BB, 0x25B4, 0x25B5, 0x269C, 0x2695, 0x2697,
+ 0x2698, 0x26AD, 0x26AE, 0x2677, 0x2673, 0x2674, 0x266D, 0x266E, 0x268E, 0x268B,
+ 0x2686, 0x2687, 0x267E, 0x267F, 0x2682, 0x2683, 0x2658, 0x2659, 0x265A, 0x265B,
+ 0x2654, 0x2655, 0x2656, 0x2657, 0x2650, 0x2651, 0x2631, 0x2632, 0x262A, 0x262B,
+ 0x262C, 0x262D, 0x2648, 0x2649, 0x264A, 0x264B, 0x2644, 0x2645, 0x2646, 0x2647,
+ 0x2640, 0x2641, 0x2642, 0x2643, 0x263C, 0x263D, 0x263E, 0x263F, 0x312E, 0x312F,
+ 0x3130, 0x3131, 0x312A, 0x312B, 0x312C, 0x312D, 0x3126, 0x3127, 0x3128, 0x3129,
+ 0x3124, 0x3125, 0x313E, 0x313F, 0x3140, 0x3141, 0x313A, 0x313B, 0x313C, 0x313D,
+ 0x3136, 0x3137, 0x3139, 0x3132, 0x3118, 0x3119, 0x3112, 0x3113, 0x3114, 0x3115,
+ 0x30EE, 0x30EF, 0x30F0, 0x01B5, 0x30EA, 0x30EB, 0x3188, 0x01B9, 0x3184, 0x3185,
+ 0x01B2, 0x01D1, 0x01E5, 0x01D0, 0x020F, 0x01FB, 0x0225, 0x021B, 0x023A, 0x319E,
+ 0x019E, 0x01B3, 0x319F, 0x31A0, 0x31A1, 0x319A, 0x319B, 0x319C, 0x319D, 0x3196,
+ 0x3197, 0x3178, 0x3179, 0x3172, 0x3173, 0x3174, 0x3175, 0x314E, 0x314F, 0x3150,
+ 0x3151, 0x314A, 0x314B, 0x314C, 0x314D, 0x3146, 0x3147, 0x3148, 0x3149, 0x3142,
+ 0x3143, 0x3144, 0x3145, 0x315E, 0x315F, 0x3160, 0x3161, 0x315A, 0x315B, 0x315C,
+ 0x315D, 0x3156, 0x45BA, 0x3157, 0x322D, 0x3228, 0x3229, 0x3222, 0x3223, 0x323F,
+ 0x3238, 0x3239, 0x3232, 0x3233, 0x3234, 0x3235, 0x320E, 0x320F, 0x3210, 0x3211,
+ 0x320A, 0x320B, 0x320C, 0x320D, 0x3206, 0x3207, 0x31E8, 0x31E9, 0x31E2, 0x31E3,
+ 0x31E4, 0x31E5, 0x31FE, 0x31FF, 0x31FA, 0x45BB, 0x31FB, 0x31F8, 0x31F9, 0x31F2,
+ 0x31F3, 0x31F4, 0x31F5, 0x31CE, 0x31CF, 0x180E, 0x31D0, 0x31D1, 0x180F, 0x1812,
+ 0x1811, 0x31CA, 0x1813, 0x1816, 0x1815, 0x1818, 0x1817, 0x31CB, 0x31CC, 0x31C6,
+ 0x31C7, 0x2EC5, 0x2EC6, 0x2EE0, 0x2EE1, 0x2EDA, 0x2EDB, 0x2ED7, 0x2FBC, 0x2F98,
+ 0x2F99, 0x2F92, 0x2F93, 0x2F94, 0x2F95, 0x2F6E, 0x2F6F, 0x2F6B, 0x2F4C, 0x3028,
+ 0x3029, 0x3022, 0x3023, 0x303F, 0x3038, 0x3039, 0x3032, 0x3033, 0x3034, 0x3035,
+ 0x300E, 0x183C, 0x300F, 0x3010, 0x3011, 0x300A, 0x300B, 0x3007, 0x3008, 0x3009,
+ 0x3002, 0x3003, 0x3004, 0x3005, 0x301E, 0x301F, 0x3020, 0x3021, 0x301A, 0x301B,
+ 0x301C, 0x301D, 0x3016, 0x3017, 0x2FE8, 0x2FE9, 0x2FE2, 0x2FE3, 0x2FE4, 0x2FE5,
+ 0x2FFE, 0x2FFF, 0x3000, 0x3001, 0x2FFA, 0x2FFB, 0x2FFC, 0x2FFD, 0x2FF6, 0x2FF7,
+ 0x2FF8, 0x2FF9, 0x2FF2, 0x2FF3, 0x2FF4, 0x2FF5, 0x2FCE, 0x2FCF, 0x2FD0, 0x2FD1,
+ 0x2FCA, 0x2FCB, 0x2FCC, 0x2FCD, 0x2FC6, 0x2FC7, 0x2FC8, 0x2FC9, 0x2FC2, 0x2FC3,
+ 0x2FC4, 0x2FC5, 0x2FDE, 0x2FDF, 0x2FD8, 0x2FD9, 0x2FD2, 0x2FD3, 0x2FD4, 0x2FD5,
+ 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30A6, 0x30A7,
+ 0x05E3, 0x05D3, 0x062E, 0x060C, 0x062F, 0x060D, 0x0570, 0x0562, 0x0571, 0x0563,
+ 0x072D, 0x072E, 0x064C, 0x064D, 0x05D9, 0x036C, 0x044A, 0x044B, 0x02EE, 0x02ED,
+ 0x05DA, 0x05DB, 0x0559, 0x0724, 0x0725, 0x02EB, 0x0674, 0x068C, 0x0477, 0x06BF,
+ 0x05F3, 0x0644, 0x0653, 0x066E, 0x041B, 0x05CA, 0x05CC, 0x05F7, 0x057A, 0x0595,
+ 0x05C0, 0x05C5, 0x03BE, 0x0418, 0x043A, 0x045D, 0x072C, 0x02AF, 0x0361, 0x039F,
+ 0x0716, 0x071F, 0x0726, 0x072B, 0x06E3, 0x06E4, 0x06EB, 0x06F4, 0x0834, 0x0838,
+ 0x07E9, 0x0836, 0x0789, 0x0788, 0x0791, 0x0790, 0x089F, 0x089E, 0x067F, 0x0694,
+ 0x06B2, 0x06D2, 0x05AC, 0x05DD, 0x061A, 0x065F, 0x04E6, 0x0538, 0x0551, 0x056A,
+ 0x0424, 0x044C, 0x047E, 0x049C, 0x0485, 0x04AB, 0x0510, 0x053D, 0x03FB, 0x0412,
+ 0x042D, 0x045C, 0x0346, 0x0372, 0x0395, 0x03BD, 0x0291, 0x02AE, 0x06BE, 0x05AC,
+ 0x045C, 0x07C5, 0x07E7, 0x07F0, 0x076E, 0x0783, 0x078F, 0x0827, 0x0819, 0x077A,
+ 0x0779, 0x02BD, 0x0749, 0x0763, 0x0779, 0x07C2, 0x0869, 0x05F9, 0x0268, 0x06B2,
+ 0x06D2, 0x085E, 0x0863, 0x07C5, 0x07F4, 0x07FA, 0x02C6, 0x02EF, 0x032A, 0x036D,
+ 0x06BE, 0x1DEE, 0x1DED, 0x1DF0, 0x1DEF, 0x1DF2, 0x1DF1, 0x1DF4, 0x1DF3, 0x1DF6,
+ 0x1DF5, 0x1DF8, 0x1DF7, 0x06DB, 0x0267, 0x02A8, 0x063C, 0x0669, 0x0688, 0x069C,
+ 0x0554, 0x0578, 0x05BC, 0x05E9, 0x05AC, 0x05DD, 0x04E6, 0x0538, 0x03E2, 0x1E0A,
+ 0x1E09, 0x1E0C, 0x1E0B, 0x040E, 0x0867, 0x086B, 0x089A, 0x0832, 0x083D, 0x085E,
+ 0x0863, 0x0816, 0x081B, 0x082A, 0x07C5, 0x07F4, 0x07FA, 0x07FE, 0x0802, 0x07FC,
+ 0x0800, 0x01A2, 0x0198, 0x01DF, 0x01C9, 0x0209, 0x01F5, 0x021F, 0x0215, 0x0234,
+ 0x022A, 0x080C, 0x0819, 0x07D8, 0x07ED, 0x07F2, 0x07F8, 0x0779, 0x078D, 0x07AA,
+ 0x07C2, 0x0749, 0x0763, 0x0310, 0x0819, 0x0867, 0x086B, 0x1596, 0x1595, 0x0827,
+ 0x1597, 0x159A, 0x1599, 0x159C, 0x159B, 0x159E, 0x159D, 0x15A0, 0x159F, 0x15A2,
+ 0x15A1, 0x15A4, 0x15A3, 0x082F, 0x082F, 0x083B, 0x0800, 0x080C, 0x0819, 0x07D8,
+ 0x07ED, 0x07F2, 0x07F8, 0x0779, 0x078D, 0x0765, 0x0769, 0x0861, 0x0827, 0x0885,
+ 0x0779, 0x07C2, 0x2A2D, 0x2A2F, 0x0865, 0x2A33, 0x0869, 0x019D, 0x01B1, 0x01CF,
+ 0x01E4, 0x021A, 0x0224, 0x022F, 0x0239, 0x01CF, 0x01E4, 0x01FA, 0x020E, 0x15BD,
+ 0x15BC, 0x15BF, 0x15BE, 0x15C1, 0x15C0, 0x15C3, 0x15C2, 0x15C5, 0x15C4, 0x15C7,
+ 0x15C6, 0x022F, 0x0239, 0x019D, 0x01B1, 0x021A, 0x0224, 0x022F, 0x0239, 0x01CF,
+ 0x01E4, 0x01FA, 0x020E, 0x022F, 0x0239, 0x019D, 0x01B1, 0x01FA, 0x020E, 0x15DB,
+ 0x0621, 0x05FF, 0x06D6, 0x04BA, 0x03D5, 0x06FC, 0x03E2, 0x040E, 0x067F, 0x0694,
+ 0x06B2, 0x06D2, 0x05AC, 0x05DD, 0x061A, 0x065F, 0x0538, 0x0551, 0x056A, 0x0424,
+ 0x044C, 0x047E, 0x049C, 0x0485, 0x04AB, 0x0510, 0x053D, 0x03FB, 0x0412, 0x042D,
+ 0x045C, 0x0346, 0x0372, 0x0395, 0x03BD, 0x0291, 0x02AE, 0x02D0, 0x0300, 0x0554,
+ 0x05BC, 0x05E9, 0x04AB, 0x0510, 0x053D, 0x0412, 0x042D, 0x0395, 0x03B2, 0x03E2,
+ 0x040E, 0x02C6, 0x02EF, 0x036D, 0x06BE, 0x06DB, 0x0267, 0x02A8, 0x063C, 0x0669,
+ 0x0688, 0x069C, 0x0424, 0x044C, 0x047E, 0x049C, 0x0389, 0x03B2, 0x03E2, 0x040E,
+ 0x02C6, 0x02EF, 0x032A, 0x036D, 0x06BE, 0x06DB, 0x0267, 0x02A8, 0x0291, 0x02D0,
+ 0x0300, 0x067F, 0x0694, 0x06B2, 0x06D2, 0x05AC, 0x05DD, 0x061A, 0x065F, 0x04E6,
+ 0x0538, 0x0551, 0x056A, 0x0291, 0x02AE, 0x02D0, 0x0300, 0x067F, 0x0694, 0x06B2,
+ 0x06D2, 0x05AC, 0x05DD, 0x061A, 0x065F, 0x04E6, 0x0538, 0x0551, 0x056A, 0x0554,
+ 0x0578, 0x05BC, 0x05E9, 0x0485, 0x04AB, 0x0510, 0x053D, 0x03FB, 0x0412, 0x042D,
+ 0x045C, 0x0346, 0x0372, 0x0395, 0x03BD, 0x063C, 0x0669, 0x0688, 0x069C, 0x05BC,
+ 0x05E9, 0x0485, 0x01D0, 0x01B2, 0x01FB, 0x01E5, 0x021B, 0x020F, 0x0230, 0x0225,
+ 0x01B3, 0x023A, 0x01D0, 0x01B2, 0x01FB, 0x01E5, 0x021B, 0x020F, 0x0230, 0x0225,
+ 0x01B3, 0x023A, 0x01D0, 0x01B2, 0x01FB, 0x0510, 0x021B, 0x020F, 0x0230, 0x03FB,
+ 0x01B3, 0x023A, 0x0412, 0x042D, 0x045C, 0x0424, 0x044C, 0x047E, 0x049C, 0x0389,
+ 0x03B2, 0x03E2, 0x040E, 0x02C6, 0x02EF, 0x032A, 0x036D, 0x06BE, 0x0267, 0x02A8,
+ 0x04E6, 0x0538, 0x0551, 0x056A, 0x0424, 0x044C, 0x047E, 0x049C, 0x0389, 0x03B2,
+ 0x03E2, 0x040E, 0x2A52, 0x02C6, 0x02EF, 0x2A58, 0x032A, 0x036D, 0x0346, 0x0372,
+ 0x0395, 0x2A64, 0x0291, 0x02AE, 0x0300, 0x067F, 0x0694, 0x06B2, 0x06D2, 0x05AC,
+ 0x05DD, 0x061A, 0x065F, 0x0412, 0x042D, 0x045C, 0x0346, 0x0372, 0x0395, 0x0291,
+ 0x02AE, 0x0300, 0x067F, 0x0694, 0x06B2, 0x2A4F, 0x06D2, 0x06BE, 0x0267, 0x02A8,
+ 0x063C, 0x0669, 0x0688, 0x069C, 0x0554, 0x05BC, 0x05E9, 0x0485, 0x04AB, 0x0510,
+ 0x053D, 0x06BE, 0x06DB, 0x0267, 0x02A8, 0x063C, 0x0669, 0x0688, 0x069C, 0x0554,
+ 0x0578, 0x05BC, 0x05E9, 0x0485, 0x04AB, 0x0510, 0x053D, 0x04E6, 0x0538, 0x0551,
+ 0x056A, 0x0424, 0x044C, 0x047E, 0x049C, 0x0389, 0x03B2, 0x03E2, 0x040E, 0x02C6,
+ 0x02EF, 0x032A, 0x036D, 0x05AC, 0x05DD, 0x061A, 0x065F, 0x04E6, 0x0538, 0x0551,
+ 0x056A, 0x0424, 0x044C, 0x047E, 0x049C, 0x0389, 0x03B2, 0x03E2, 0x040E, 0x03FB,
+ 0x0412, 0x042D, 0x045C, 0x0346, 0x0372, 0x0395, 0x03BD, 0x0291, 0x02AE, 0x02D0,
+ 0x0300, 0x067F, 0x0694, 0x06B2, 0x06D2, 0x0485, 0x04AB, 0x0510, 0x053D, 0x03FB,
+ 0x0412, 0x042D, 0x045C, 0x0346, 0x0372, 0x0395, 0x03BD, 0x0291, 0x02AE, 0x02D0,
+ 0x0300, 0x02C6, 0x02EF, 0x032A, 0x036D, 0x06BE, 0x06DB, 0x0267, 0x02A8, 0x063C,
+ 0x0669, 0x0688, 0x069C, 0x0554, 0x0578, 0x05BC, 0x05E9, 0x0389, 0x03B2, 0x03E2,
+ 0x040E, 0x02C6, 0x02EF, 0x032A, 0x036D, 0x06BE, 0x06DB, 0x2A13, 0x0267, 0x02A8,
+ 0x063C, 0x0669, 0x0688, 0x069C, 0x067F, 0x0694, 0x06B2, 0x06D2, 0x05AC, 0x05DD,
+ 0x061A, 0x065F, 0x04E6, 0x0538, 0x0551, 0x056A, 0x0424, 0x044C, 0x047E, 0x049C,
+ 0x0192, 0x0193, 0x0194, 0x0195, 0x0234, 0x018F, 0x0190, 0x0191, 0x0209, 0x0215,
+ 0x021F, 0x022A, 0x01A2, 0x01C9, 0x01DF, 0x01F5, 0x0196, 0x0197, 0x4355, 0x4356,
+ 0x4357, 0x4351, 0x4352, 0x4353, 0x4354, 0x434D, 0x434E, 0x434F, 0x4350, 0x4349,
+ 0x434A, 0x434B, 0x434C, 0x4335, 0x4336, 0x4337, 0x4338, 0x4331, 0x4332, 0x4333,
+ 0x4334, 0x432D, 0x432E, 0x432F, 0x4330, 0x4329, 0x432A, 0x432B, 0x432C, 0x4345,
+ 0x4346, 0x4347, 0x4348, 0x4341, 0x4342, 0x4343, 0x4344, 0x433D, 0x433E, 0x433F,
+ 0x4340, 0x4339, 0x433A, 0x433B, 0x433C, 0x4195, 0x4196, 0x4197, 0x4198, 0x4191,
+ 0x4192, 0x4193, 0x4194, 0x418D, 0x418E, 0x418F, 0x4190, 0x4189, 0x418A, 0x418B,
+ 0x418C, 0x41A5, 0x41A6, 0x41A7, 0x41A8, 0x41A1, 0x41A2, 0x41A3, 0x41A4, 0x419D,
+ 0x419E, 0x419F, 0x41A0, 0x4199, 0x419A, 0x419B, 0x419C, 0x4175, 0x4176, 0x4177,
+ 0x4178, 0x4171, 0x4172, 0x4173, 0x4174, 0x416D, 0x416E, 0x416F, 0x4170, 0x4169,
+ 0x416A, 0x416B, 0x416C, 0x4185, 0x4186, 0x4187, 0x4188, 0x4181, 0x4182, 0x2D71,
+ 0x2D72, 0x4183, 0x4184, 0x417D, 0x417E, 0x2D6F, 0x2D70, 0x417F, 0x4180, 0x4179,
+ 0x417A, 0x2D75, 0x2D76, 0x417B, 0x417C, 0x4155, 0x4156, 0x4157, 0x4158, 0x2D73,
+ 0x2D74, 0x4151, 0x4152, 0x4153, 0x4154, 0x414D, 0x414E, 0x414F, 0x4150, 0x2D98,
+ 0x2D9D, 0x2D97, 0x2D9E, 0x2D93, 0x2D94, 0x2D83, 0x2D84, 0x2D89, 0x2D8A, 0x2D99,
+ 0x2D9A, 0x2D7B, 0x2D8E, 0x2D9C, 0x2D8D, 0x2D79, 0x2D78, 0x2D7A, 0x2D77, 0x2D7D,
+ 0x2D60, 0x2D7E, 0x2D61, 0x2C78, 0x2D6D, 0x2D87, 0x2D88, 0x4149, 0x2D7C, 0x2D64,
+ 0x2D65, 0x414A, 0x414B, 0x414C, 0x4165, 0x4166, 0x4167, 0x4168, 0x4161, 0x4162,
+ 0x4163, 0x4164, 0x415D, 0x415E, 0x415F, 0x4160, 0x4159, 0x415A, 0x415B, 0x2DB2,
+ 0x2DB1, 0x415C, 0x4135, 0x4136, 0x4137, 0x2DB8, 0x4138, 0x2DBD, 0x4131, 0x4132,
+ 0x2DBE, 0x4133, 0x4134, 0x2D7F, 0x2D80, 0x2D81, 0x2D82, 0x2DC4, 0x2DC3, 0x2D85,
+ 0x2D86, 0x2DC8, 0x2DC7, 0x2DCA, 0x2DC9, 0x2DCC, 0x2DCB, 0x2DCE, 0x2DCD, 0x412D,
+ 0x412E, 0x412F, 0x4130, 0x4129, 0x412A, 0x412B, 0x412C, 0x4145, 0x4146, 0x4147,
+ 0x4148, 0x2D9B, 0x4141, 0x4142, 0x4143, 0x4144, 0x413D, 0x413E, 0x413F, 0x4140,
+ 0x4139, 0x16B6, 0x16B5, 0x16B8, 0x16B7, 0x16BA, 0x16B9, 0x16BC, 0x16BB, 0x413A,
+ 0x413B, 0x16C0, 0x16BF, 0x413C, 0x4215, 0x4216, 0x4217, 0x4218, 0x4211, 0x4212,
+ 0x4213, 0x4214, 0x420D, 0x420E, 0x420F, 0x4210, 0x4209, 0x420A, 0x420B, 0x420C,
+ 0x4225, 0x4226, 0x4227, 0x4228, 0x4221, 0x4222, 0x4223, 0x4224, 0x421D, 0x421E,
+ 0x421F, 0x4220, 0x4219, 0x421A, 0x421B, 0x421C, 0x41F5, 0x41F6, 0x41F7, 0x41F8,
+ 0x41F1, 0x41F2, 0x41F3, 0x41F4, 0x41ED, 0x41EE, 0x41EF, 0x41F0, 0x41E9, 0x41EA,
+ 0x41EB, 0x41EC, 0x4205, 0x4206, 0x4207, 0x4208, 0x4201, 0x4202, 0x4203, 0x4204,
+ 0x41FD, 0x41FE, 0x41FF, 0x4200, 0x41F9, 0x41FA, 0x41FB, 0x41FC, 0x41D5, 0x41D6,
+ 0x41D7, 0x41D8, 0x41D1, 0x41D2, 0x41D3, 0x41D4, 0x41CD, 0x41CE, 0x41CF, 0x41D0,
+ 0x41C9, 0x41CA, 0x41CB, 0x2E4D, 0x2E4E, 0x2E44, 0x2E43, 0x41CC, 0x41E5, 0x2E48,
+ 0x2E47, 0x41E6, 0x41E7, 0x41E8, 0x41E1, 0x2E49, 0x2E4A, 0x41E2, 0x41E3, 0x41E4,
+ 0x41DD, 0x41DE, 0x41DF, 0x16DF, 0x16E0, 0x2E4B, 0x2E4C, 0x16F9, 0x16FA, 0x16FB,
+ 0x16FC, 0x16F5, 0x16F6, 0x2E60, 0x2E5F, 0x2E62, 0x2E61, 0x16F7, 0x16F8, 0x2E66,
+ 0x2E65, 0x16F0, 0x16EF, 0x16ED, 0x16EE, 0x16F4, 0x16F3, 0x16F1, 0x16F2, 0x2E70,
+ 0x2E6F, 0x2E72, 0x2E71, 0x2E74, 0x2E73, 0x2E76, 0x2E75, 0x2E78, 0x2E77, 0x2E7A,
+ 0x2E79, 0x2E7C, 0x2E7B, 0x16DE, 0x2E7D, 0x16DD, 0x16E8, 0x16E2, 0x16E3, 0x16E1,
+ 0x16E4, 0x16FD, 0x16FE, 0x16FF, 0x1700, 0x16E9, 0x16EA, 0x16EB, 0x16EC, 0x1708,
+ 0x1702, 0x16E7, 0x1701, 0x1703, 0x16E6, 0x1704, 0x16E5, 0x170D, 0x41E0, 0x41D9,
+ 0x41DA, 0x0215, 0x021F, 0x16DC, 0x170E, 0x41DB, 0x41DC, 0x41B5, 0x41B6, 0x41B7,
+ 0x41B8, 0x41B1, 0x41B2, 0x01C9, 0x01DF, 0x0198, 0x01A2, 0x41B3, 0x01F5, 0x41B4,
+ 0x0209, 0x0234, 0x022A, 0x41AD, 0x41AE, 0x41AF, 0x41B0, 0x41A9, 0x41AA, 0x41AB,
+ 0x41AC, 0x41C5, 0x41C6, 0x41C7, 0x41C8, 0x41C1, 0x41C2, 0x1705, 0x1706, 0x1707,
+ 0x41C3, 0x1709, 0x170A, 0x170B, 0x170C, 0x41C4, 0x41BD, 0x41BE, 0x41BF, 0x41C0,
+ 0x41B9, 0x41BA, 0x41BB, 0x41BC, 0x4295, 0x4296, 0x4297, 0x4298, 0x4291, 0x4292,
+ 0x4293, 0x4294, 0x428D, 0x428E, 0x428F, 0x4290, 0x4289, 0x428A, 0x428B, 0x428C,
+ 0x42A5, 0x42A6, 0x42A7, 0x42A8, 0x42A1, 0x42A2, 0x42A3, 0x42A4, 0x429D, 0x429E,
+ 0x429F, 0x42A0, 0x4299, 0x429A, 0x429B, 0x429C, 0x4275, 0x4276, 0x4277, 0x4278,
+ 0x4271, 0x4272, 0x4273, 0x4274, 0x426D, 0x426E, 0x426F, 0x4270, 0x4269, 0x426A,
+ 0x426B, 0x426C, 0x4285, 0x4286, 0x4287, 0x4288, 0x4281, 0x4282, 0x4283, 0x4284,
+ 0x427D, 0x427E, 0x427F, 0x4280, 0x4279, 0x427A, 0x427B, 0x427C, 0x4255, 0x4256,
+ 0x4257, 0x4258, 0x4251, 0x4252, 0x4253, 0x4254, 0x424D, 0x424E, 0x424F, 0x4250,
+ 0x4249, 0x424A, 0x424B, 0x424C, 0x4265, 0x4266, 0x4267, 0x4268, 0x4261, 0x4262,
+ 0x4263, 0x4264, 0x425D, 0x425E, 0x425F, 0x4260, 0x4259, 0x425A, 0x425B, 0x425C,
+ 0x4235, 0x4236, 0x4237, 0x4238, 0x4231, 0x4232, 0x4233, 0x4234, 0x422D, 0x422E,
+ 0x422F, 0x4230, 0x4229, 0x422A, 0x422B, 0x422C, 0x4245, 0x4246, 0x4247, 0x4248,
+ 0x4241, 0x4242, 0x4243, 0x4244, 0x423D, 0x423E, 0x423F, 0x4240, 0x4239, 0x423A,
+ 0x423B, 0x423C, 0x4315, 0x4316, 0x4317, 0x4318, 0x4311, 0x4312, 0x4313, 0x1710,
+ 0x170F, 0x1714, 0x1711, 0x4314, 0x1716, 0x171A, 0x1719, 0x171C, 0x171B, 0x171E,
+ 0x171D, 0x1720, 0x171F, 0x1722, 0x1721, 0x430D, 0x430E, 0x430F, 0x4310, 0x4309,
+ 0x430A, 0x430B, 0x430C, 0x172C, 0x172B, 0x4325, 0x4326, 0x1730, 0x172F, 0x1732,
+ 0x1731, 0x4327, 0x4328, 0x4321, 0x4322, 0x4323, 0x4324, 0x431D, 0x431E, 0x431F,
+ 0x4320, 0x4319, 0x431A, 0x431B, 0x431C, 0x42F5, 0x42F6, 0x42F7, 0x42F8, 0x42F1,
+ 0x42F2, 0x42F3, 0x42F4, 0x42ED, 0x42EE, 0x42EF, 0x42F0, 0x42E9, 0x42EA, 0x42EB,
+ 0x42EC, 0x4305, 0x4306, 0x4307, 0x4308, 0x4301, 0x4302, 0x4303, 0x4304, 0x42FD,
+ 0x42FE, 0x42FF, 0x4300, 0x42F9, 0x42FA, 0x42FB, 0x42FC, 0x42D5, 0x42D6, 0x42D7,
+ 0x42D8, 0x42D1, 0x42D2, 0x42D3, 0x42D4, 0x42CD, 0x42CE, 0x42CF, 0x42D0, 0x42C9,
+ 0x42CA, 0x42CB, 0x42CC, 0x42E5, 0x42E6, 0x42E7, 0x42E8, 0x42E1, 0x42E2, 0x42E3,
+ 0x42E4, 0x42DD, 0x42DE, 0x42DF, 0x42E0, 0x42D9, 0x42DA, 0x42DB, 0x42DC, 0x42B5,
+ 0x42B6, 0x42B7, 0x42B8, 0x42B1, 0x42B2, 0x42B3, 0x42B4, 0x42AD, 0x42AE, 0x42AF,
+ 0x42B0, 0x42A9, 0x42AA, 0x42AB, 0x42AC, 0x42C5, 0x42C6, 0x42C7, 0x42C8, 0x1745,
+ 0x42C1, 0x42C2, 0x42C3, 0x42C4, 0x42BD, 0x42BE, 0x42BF, 0x42C0, 0x42B9, 0x42BA,
+ 0x42BB, 0x42BC, 0x3F95, 0x1753, 0x1752, 0x1755, 0x1754, 0x1757, 0x1756, 0x1759,
+ 0x1758, 0x175B, 0x175A, 0x175D, 0x175C, 0x175F, 0x175E, 0x1761, 0x1760, 0x1763,
+ 0x1762, 0x3F96, 0x1764, 0x1767, 0x1766, 0x1769, 0x1768, 0x176B, 0x176A, 0x176D,
+ 0x176C, 0x176F, 0x176E, 0x1771, 0x1770, 0x3F97, 0x3F98, 0x3F91, 0x3F92, 0x3F93,
+ 0x3F94, 0x3F8D, 0x3F8E, 0x3F8F, 0x3F90, 0x3F89, 0x3F8A, 0x3F8B, 0x3F8C, 0x3FA5,
+ 0x3FA6, 0x3FA7, 0x3FA8, 0x3FA1, 0x3FA2, 0x3FA3, 0x1772, 0x3FA4, 0x3F9D, 0x3F9E,
+ 0x3F9F, 0x3FA0, 0x3F99, 0x3F9A, 0x3F9B, 0x3F9C, 0x3F75, 0x01A2, 0x0198, 0x01DF,
+ 0x01C9, 0x0209, 0x01F5, 0x021F, 0x0215, 0x0234, 0x022A, 0x3F76, 0x3F77, 0x3F78,
+ 0x3F71, 0x3F72, 0x3F73, 0x3F74, 0x3F6D, 0x3F6E, 0x3F6F, 0x3F70, 0x3F69, 0x3F6A,
+ 0x3F6B, 0x3F6C, 0x3F85, 0x3F86, 0x3F87, 0x3F88, 0x3F81, 0x3F82, 0x3F83, 0x3F84,
+ 0x3F7D, 0x3F7E, 0x3F7F, 0x3F80, 0x3F79, 0x3F7A, 0x3F7B, 0x3F7C, 0x3F55, 0x3F56,
+ 0x3F57, 0x3F58, 0x3F51, 0x3F52, 0x3F53, 0x3F54, 0x3F4D, 0x1776, 0x3F4E, 0x3F4F,
+ 0x3F50, 0x3F49, 0x3F4A, 0x3F4B, 0x3F4C, 0x3F65, 0x3F66, 0x3F67, 0x3F68, 0x3F61,
+ 0x3F62, 0x1787, 0x1786, 0x1789, 0x1788, 0x178B, 0x178A, 0x178D, 0x3F63, 0x178F,
+ 0x178E, 0x1791, 0x1790, 0x1793, 0x1792, 0x1795, 0x3F64, 0x1797, 0x1796, 0x3F5D,
+ 0x1798, 0x179B, 0x179A, 0x177E, 0x179C, 0x177F, 0x177D, 0x3F5E, 0x179D, 0x3F5F,
+ 0x3F60, 0x3F59, 0x3F5A, 0x3F5B, 0x3F5C, 0x3F35, 0x3F36, 0x3F37, 0x3F38, 0x3F31,
+ 0x3F32, 0x3F33, 0x3F34, 0x3F2D, 0x3F2E, 0x3F2F, 0x3F30, 0x3F29, 0x3F2A, 0x01A2,
+ 0x0198, 0x01DF, 0x01C9, 0x0209, 0x01F5, 0x021F, 0x0215, 0x0234, 0x022A, 0x3F2B,
+ 0x3F2C, 0x3F45, 0x3F46, 0x3F47, 0x3F48, 0x3F41, 0x3F42, 0x3F43, 0x3F44, 0x3F3D,
+ 0x3F3E, 0x3F3F, 0x3F40, 0x3F39, 0x3F3A, 0x3F3B, 0x3F3C, 0x4015, 0x4016, 0x4017,
+ 0x4018, 0x4011, 0x4012, 0x4013, 0x4014, 0x400D, 0x400E, 0x400F, 0x4010, 0x4009,
+ 0x400A, 0x400B, 0x400C, 0x4025, 0x4026, 0x4027, 0x4028, 0x4021, 0x4022, 0x4023,
+ 0x4024, 0x401D, 0x401E, 0x401F, 0x4020, 0x4019, 0x401A, 0x401B, 0x401C, 0x3FF5,
+ 0x3FF6, 0x3FF7, 0x3FF8, 0x3FF1, 0x3FF2, 0x3FF3, 0x3FF4, 0x3FED, 0x3FEE, 0x3FEF,
+ 0x3FF0, 0x3FE9, 0x3FEA, 0x3FEB, 0x3FEC, 0x4005, 0x4006, 0x4007, 0x4008, 0x4001,
+ 0x4002, 0x4003, 0x4004, 0x3FFD, 0x3FFE, 0x3FFF, 0x4000, 0x3FF9, 0x3FFA, 0x3FFB,
+ 0x3FFC, 0x3FD5, 0x3FD6, 0x3FD7, 0x3FD8, 0x3FD1, 0x3FD2, 0x3FD3, 0x3FD4, 0x3FCD,
+ 0x3FCE, 0x3FCF, 0x3FD0, 0x3FC9, 0x3FCA, 0x3FCB, 0x3FCC, 0x3FE5, 0x3FE6, 0x3FE7,
+ 0x3FE8, 0x3FE1, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x3FE2, 0x08A8, 0x08A9,
+ 0x08AA, 0x3FE3, 0x3FE4, 0x08AF, 0x3FDD, 0x3FDE, 0x3FDF, 0x3FE0, 0x08B4, 0x08B5,
+ 0x08B6, 0x08B7, 0x08B8, 0x08BA, 0x08BD, 0x08BE, 0x08BF, 0x08C0, 0x08C1, 0x08C2,
+ 0x08C7, 0x08C8, 0x08C9, 0x08CA, 0x3FD9, 0x3FDA, 0x3FDB, 0x3FDC, 0x3FB5, 0x3FB6,
+ 0x3FB7, 0x3FB8, 0x3FB1, 0x3FB2, 0x3FB3, 0x3FB4, 0x3FAD, 0x3FAE, 0x3FAF, 0x3FB0,
+ 0x3FA9, 0x3FAA, 0x3FAB, 0x3FAC, 0x0913, 0x3FC5, 0x3FC6, 0x3FC7, 0x3FC8, 0x3FC1,
+ 0x3FC2, 0x3FC3, 0x3FC4, 0x3FBD, 0x3FBE, 0x3FBF, 0x3FC0, 0x3FB9, 0x3FBA, 0x3FBB,
+ 0x3FBC, 0x4095, 0x4096, 0x4097, 0x4098, 0x4091, 0x4092, 0x4093, 0x4094, 0x408D,
+ 0x408E, 0x408F, 0x4090, 0x4089, 0x408A, 0x408B, 0x408C, 0x40A5, 0x40A6, 0x40A7,
+ 0x40A8, 0x40A1, 0x40A2, 0x40A3, 0x40A4, 0x409D, 0x409E, 0x409F, 0x40A0, 0x4099,
+ 0x409A, 0x409B, 0x409C, 0x4075, 0x4076, 0x4077, 0x4078, 0x4071, 0x4072, 0x4073,
+ 0x4074, 0x406D, 0x406E, 0x406F, 0x4070, 0x4069, 0x406A, 0x406B, 0x406C, 0x4085,
+ 0x4086, 0x4087, 0x4088, 0x4081, 0x4082, 0x4083, 0x4084, 0x407D, 0x407E, 0x407F,
+ 0x4080, 0x4079, 0x407A, 0x407B, 0x407C, 0x4055, 0x4056, 0x4057, 0x4058, 0x4051,
+ 0x4052, 0x4053, 0x4054, 0x0B39, 0x404D, 0x404E, 0x0B4B, 0x0B48, 0x0B54, 0x0B4E,
+ 0x0B5A, 0x404F, 0x0B60, 0x0B5D, 0x0B66, 0x4050, 0x0B6C, 0x0B69, 0x4049, 0x404A,
+ 0x404B, 0x404C, 0x4065, 0x4066, 0x4067, 0x4068, 0x4061, 0x4062, 0x4063, 0x4064,
+ 0x405D, 0x405E, 0x405F, 0x4060, 0x4059, 0x405A, 0x405B, 0x405C, 0x10AE, 0x10AD,
+ 0x10B0, 0x10AF, 0x10B2, 0x4035, 0x10B4, 0x10B3, 0x10B6, 0x4036, 0x4037, 0x10B7,
+ 0x4038, 0x4031, 0x4032, 0x4033, 0x10BF, 0x10BE, 0x10C1, 0x10C0, 0x10C3, 0x10C2,
+ 0x10C5, 0x10C4, 0x10C7, 0x10C6, 0x10C9, 0x10C8, 0x10CB, 0x10CA, 0x10CD, 0x10CC,
+ 0x4034, 0x402D, 0x402E, 0x402F, 0x4030, 0x4029, 0x402A, 0x402B, 0x402C, 0x4045,
+ 0x4046, 0x4047, 0x4048, 0x10DB, 0x4041, 0x4042, 0x4043, 0x4044, 0x403D, 0x403E,
+ 0x403F, 0x4040, 0x4039, 0x403A, 0x403B, 0x403C, 0x4115, 0x4116, 0x4117, 0x4118,
+ 0x4111, 0x4112, 0x4113, 0x4114, 0x410D, 0x410E, 0x410F, 0x4110, 0x4109, 0x410A,
+ 0x410B, 0x410C, 0x4125, 0x4126, 0x4127, 0x4128, 0x4121, 0x4122, 0x4123, 0x4124,
+ 0x411D, 0x411E, 0x411F, 0x4120, 0x4119, 0x411A, 0x411B, 0x411C, 0x40F5, 0x40F6,
+ 0x40F7, 0x40F8, 0x40F1, 0x40F2, 0x40F3, 0x40F4, 0x40ED, 0x40EE, 0x40EF, 0x40F0,
+ 0x40E9, 0x40EA, 0x40EB, 0x40EC, 0x4105, 0x4106, 0x4107, 0x4108, 0x4101, 0x4102,
+ 0x4103, 0x4104, 0x40FD, 0x40FE, 0x40FF, 0x4100, 0x40F9, 0x40FA, 0x40FB, 0x40FC,
+ 0x40D5, 0x40D6, 0x40D7, 0x40D8, 0x40D1, 0x40D2, 0x40D3, 0x40D4, 0x40CD, 0x40CE,
+ 0x40CF, 0x40D0, 0x40C9, 0x40CA, 0x40CB, 0x40CC, 0x40E5, 0x40E6, 0x40E7, 0x40E8,
+ 0x40E1, 0x40E2, 0x128F, 0x128E, 0x1291, 0x1290, 0x1293, 0x1292, 0x40E3, 0x1294,
+ 0x1296, 0x1295, 0x1298, 0x1297, 0x129A, 0x1299, 0x40E4, 0x129B, 0x40DD, 0x40DE,
+ 0x40DF, 0x40E0, 0x40D9, 0x40DA, 0x40DB, 0x40DC, 0x40B5, 0x40B6, 0x40B7, 0x40B8,
+ 0x40B1, 0x12A7, 0x40B2, 0x40B3, 0x40B4, 0x40AD, 0x40AE, 0x40AF, 0x40B0, 0x40A9,
+ 0x40AA, 0x40AB, 0x40AC, 0x40C5, 0x40C6, 0x40C7, 0x40C8, 0x40C1, 0x40C2, 0x40C3,
+ 0x40C4, 0x40BD, 0x40BE, 0x40BF, 0x40C0, 0x40B9, 0x40BA, 0x40BB, 0x40BC, 0x48AB,
+ 0x490A, 0x490B, 0x48AC, 0x4909, 0x4975, 0x48A7, 0x48A9, 0x48A1, 0x48A2, 0x48A3,
+ 0x48A5, 0x489A, 0x4974, 0x489D, 0x4908, 0x48BA, 0x497B, 0x48B6, 0x48B7, 0x48B8,
+ 0x48B9, 0x4979, 0x48B3, 0x490D, 0x48B5, 0x4976, 0x490C, 0x4977, 0x4978, 0x021F,
+ 0x022A, 0x0234, 0x018E, 0x01F5, 0x0209, 0x0215, 0x018A, 0x018B, 0x018C, 0x018D,
+ 0x0186, 0x0187, 0x0188, 0x0189, 0x01F5, 0x0209, 0x0215, 0x01A2, 0x0234, 0x0234,
+ 0x01C9, 0x01DF, 0x022A, 0x022A, 0x0234, 0x0234, 0x0215, 0x021F, 0x021F, 0x021F,
+ 0x0182, 0x0183, 0x0184, 0x0185, 0x01A2, 0x01C9, 0x0180, 0x0181, 0x0209, 0x0209,
+ 0x01C9, 0x01DF, 0x01C9, 0x01DF, 0x01F5, 0x01F5, 0x01A2, 0x01C9, 0x01DF, 0x01DF,
+ 0x0215, 0x021F, 0x022A, 0x0234, 0x01DF, 0x01DF, 0x01F5, 0x0209, 0x01DF, 0x01F5,
+ 0x0209, 0x01C9, 0x01F5, 0x01F5, 0x01F5, 0x01F5, 0x01F5, 0x0209, 0x01DF, 0x01DF,
+ 0x01A2, 0x01C9, 0x01DF, 0x01DF, 0x01F5, 0x0209, 0x017E, 0x017F, 0x021F, 0x022A,
+ 0x0234, 0x01F5, 0x01DF, 0x01F5, 0x0209, 0x0215, 0x0215, 0x021F, 0x022A, 0x0234,
+ 0x01C9, 0x01DF, 0x01F5, 0x0209, 0x022A, 0x0234, 0x01A2, 0x01C9, 0x01F5, 0x0209,
+ 0x0215, 0x021F, 0x0234, 0x01A2, 0x01C9, 0x01DF, 0x0209, 0x0215, 0x021F, 0x022A,
+ 0x3ED1, 0x3ED2, 0x3ED3, 0x3ED4, 0x3ECD, 0x3ECE, 0x3ECF, 0x3ED0, 0x3EC9, 0x3ECA,
+ 0x3ECB, 0x3ECC, 0x3EC5, 0x3EC6, 0x3EC7, 0x3EC8, 0x3EE1, 0x3EE2, 0x3EE3, 0x3EE4,
+ 0x3EDD, 0x3EDE, 0x3EDF, 0x3EE0, 0x3ED9, 0x3EDA, 0x3EDB, 0x3EDC, 0x3ED5, 0x3ED6,
+ 0x3ED7, 0x3ED8, 0x3EB1, 0x3EB2, 0x3EB3, 0x3EB4, 0x3EAD, 0x3EAE, 0x3EAF, 0x3EB0,
+ 0x3EA9, 0x3EAA, 0x3EAB, 0x3EAC, 0x3EA5, 0x3EA6, 0x3EA7, 0x3EA8, 0x3EC1, 0x3EC2,
+ 0x3EC3, 0x3EC4, 0x3EBD, 0x3EBE, 0x3EBF, 0x3EC0, 0x3EB9, 0x3EBA, 0x3EBB, 0x3EBC,
+ 0x3EB5, 0x3EB6, 0x3EB7, 0x3EB8, 0x3E91, 0x3E92, 0x3E93, 0x3E94, 0x3E8D, 0x3E8E,
+ 0x3E8F, 0x3E90, 0x3E89, 0x3E8A, 0x3E8B, 0x3E8C, 0x3E85, 0x3E86, 0x3E87, 0x3E88,
+ 0x3EA1, 0x3EA2, 0x3EA3, 0x3EA4, 0x3E9D, 0x3E9E, 0x3E9F, 0x3EA0, 0x3E99, 0x3E9A,
+ 0x3E9B, 0x3E9C, 0x3E95, 0x3E96, 0x3E97, 0x3E98, 0x3E71, 0x3E72, 0x3E73, 0x3E74,
+ 0x3E6D, 0x3E6E, 0x3E6F, 0x3E70, 0x3E69, 0x3E6A, 0x3E6B, 0x3E6C, 0x3E65, 0x3E66,
+ 0x3E67, 0x3E68, 0x3E81, 0x3E82, 0x3E83, 0x3E84, 0x3E7D, 0x3E7E, 0x3E7F, 0x3E80,
+ 0x3E79, 0x3E7A, 0x3E7B, 0x3E7C, 0x3E75, 0x3E76, 0x3E77, 0x3E78, 0x3F25, 0x3F26,
+ 0x3F27, 0x3F28, 0x3F11, 0x3F12, 0x3F13, 0x3F14, 0x3F0D, 0x3F1E, 0x3F1F, 0x3F20,
+ 0x3F19, 0x464C, 0x270E, 0x270D, 0x2710, 0x270F, 0x2712, 0x2711, 0x2714, 0x2713,
+ 0x2716, 0x2715, 0x2718, 0x2717, 0x271A, 0x2719, 0x271C, 0x271B, 0x271E, 0x271D,
+ 0x2720, 0x271F, 0x2722, 0x2721, 0x2724, 0x2723, 0x2726, 0x2725, 0x2728, 0x2727,
+ 0x272A, 0x2756, 0x272C, 0x272B, 0x272E, 0x272D, 0x2730, 0x272F, 0x2732, 0x2731,
+ 0x2734, 0x2733, 0x2736, 0x2735, 0x2738, 0x2737, 0x273A, 0x2739, 0x273C, 0x273B,
+ 0x273E, 0x276F, 0x2740, 0x273F, 0x2742, 0x274F, 0x2744, 0x2778, 0x278A, 0x2745,
+ 0x275B, 0x275A, 0x274A, 0x2749, 0x274C, 0x274B, 0x1BFE, 0x274D, 0x2729, 0x276B,
+ 0x2750, 0x1BD5, 0x2751, 0x1BD9, 0x1BDA, 0x2758, 0x276C, 0x1BDC, 0x1BDB, 0x1BDE,
+ 0x1BDD, 0x1BE0, 0x1BE6, 0x1BE2, 0x2764, 0x275F, 0x1BDF, 0x1BE3, 0x277C, 0x2762,
+ 0x276A, 0x1BE1, 0x1BE5, 0x2760, 0x275E, 0x1BD6, 0x275D, 0x275C, 0x2769, 0x1BED,
+ 0x1BEE, 0x2747, 0x277A, 0x2741, 0x276D, 0x1BEF, 0x1BF6, 0x276E, 0x2789, 0x1BEC,
+ 0x1BF2, 0x1BE7, 0x1BF7, 0x278B, 0x1BD8, 0x1BE9, 0x2757, 0x2768, 0x1BE4, 0x2761,
+ 0x2763, 0x2766, 0x1BE8, 0x1BEA, 0x2767, 0x278C, 0x2785, 0x2743, 0x2784, 0x273D,
+ 0x1BFD, 0x1BFC, 0x2790, 0x278F, 0x278E, 0x2793, 0x2792, 0x278D, 0x2791, 0x279A,
+ 0x2787, 0x2788, 0x27A9, 0x2799, 0x279C, 0x279B, 0x279F, 0x27A2, 0x27A0, 0x1BD7,
+ 0x1BFF, 0x27A3, 0x27A4, 0x279E, 0x279D, 0x27AA, 0x27A6, 0x27A1, 0x27A5, 0x27AB,
+ 0x27AC, 0x27A7, 0x1BEB, 0x277B, 0x1C02, 0x1C00, 0x2782, 0x1C03, 0x1C04, 0x2781,
+ 0x27C5, 0x27C6, 0x2746, 0x1C16, 0x1C18, 0x1BFA, 0x1C17, 0x1C15, 0x27BE, 0x1BF0,
+ 0x27C0, 0x27BF, 0x27C2, 0x27C1, 0x27C4, 0x27C3, 0x27BD, 0x27C7, 0x27C8, 0x1C29,
+ 0x1C28, 0x1C01, 0x1C2B, 0x2779, 0x27D2, 0x1C24, 0x27CE, 0x1C2A, 0x277E, 0x27D1,
+ 0x27D4, 0x27D3, 0x1C27, 0x1C22, 0x27CF, 0x27D0, 0x27CD, 0x27F1, 0x2759, 0x277D,
+ 0x27D5, 0x2765, 0x2755, 0x274E, 0x340C, 0x2752, 0x2753, 0x2754, 0x27D6, 0x27E5,
+ 0x27D7, 0x27D8, 0x27EA, 0x27E9, 0x27EC, 0x27EB, 0x27F2, 0x277F, 0x27F3, 0x27F4,
+ 0x27ED, 0x27EE, 0x27EF, 0x27F0, 0x2783, 0x27F5, 0x27F9, 0x27FA, 0x27FB, 0x27FC,
+ 0x27F7, 0x27F8, 0x2771, 0x27F6, 0x2774, 0x1C1B, 0x2809, 0x280A, 0x1BFB, 0x2780,
+ 0x280B, 0x280C, 0x1BF5, 0x3406, 0x3405, 0x3408, 0x3407, 0x340A, 0x3409, 0x1C1C,
+ 0x340B, 0x340E, 0x340D, 0x3410, 0x340F, 0x3412, 0x3411, 0x3414, 0x3413, 0x3417,
+ 0x3400, 0x3418, 0x3416, 0x33FE, 0x3419, 0x3415, 0x33FF, 0x3402, 0x3401, 0x3404,
+ 0x3403, 0x341B, 0x341A, 0x341C, 0x3421, 0x341E, 0x341D, 0x3420, 0x341F, 0x3428,
+ 0x3422, 0x3434, 0x3426, 0x3427, 0x3429, 0x3430, 0x3435, 0x3431, 0x342E, 0x3423,
+ 0x342F, 0x3425, 0x3436, 0x342C, 0x3424, 0x3432, 0x342A, 0x342B, 0x342D, 0x2C6A,
+ 0x3433, 0x2C64, 0x2C65, 0x2C70, 0x2C7A, 0x2D23, 0x2C71, 0x2C79, 0x01C9, 0x01A2,
+ 0x01DF, 0x2D1C, 0x2C6B, 0x2C8C, 0x2CAA, 0x2CA5, 0x2C91, 0x47D2, 0x0198, 0x2C86,
+ 0x2CA4, 0x2CB7, 0x2C80, 0x2C7F, 0x2CD2, 0x2CCC, 0x2C8D, 0x2CC5, 0x2CD3, 0x2CBB,
+ 0x2CA9, 0x2CBC, 0x2CB0, 0x2C7B, 0x2CAB, 0x47D3, 0x2C87, 0x2C08, 0x2CC0, 0x1BF8,
+ 0x2CF5, 0x2CF6, 0x1BF1, 0x47D4, 0x286E, 0x286D, 0x2C9F, 0x1BF4, 0x2CB6, 0x2776,
+ 0x2770, 0x2773, 0x2CB1, 0x287A, 0x2CEF, 0x2D15, 0x287B, 0x2879, 0x287C, 0x2D59,
+ 0x2AB7, 0x2AB9, 0x2D53, 0x1BF3, 0x2D20, 0x2772, 0x2AAD, 0x2AAE, 0x1BF9, 0x2786,
+ 0x2777, 0x1C14, 0x2AAF, 0x288C, 0x2C72, 0x288B, 0x1C23, 0x1C21, 0x2AA9, 0x2D5D,
+ 0x1C1E, 0x1C1F, 0x2AB2, 0x1C1D, 0x1C25, 0x2C85, 0x1C26, 0x1C20, 0x1C11, 0x2A70,
+ 0x2C6C, 0x2C68, 0x2ADA, 0x2C66, 0x2A7F, 0x2A82, 0x2CAE, 0x2CB3, 0x2A8B, 0x1C13,
+ 0x2A7C, 0x2AB5, 0x1C08, 0x1C07, 0x2CB4, 0x2CA6, 0x2CBD, 0x2CC2, 0x2D4D, 0x2CA1,
+ 0x2CAD, 0x2CA7, 0x2CB8, 0x2D49, 0x2D26, 0x2D4E, 0x2D33, 0x1C19, 0x2CB9, 0x2CBE,
+ 0x1C06, 0x1C05, 0x2AEB, 0x2D38, 0x1C0B, 0x2C97, 0x1C0C, 0x1C0D, 0x1C10, 0x1C0F,
+ 0x1C0E, 0x1C1A, 0x1C0A, 0x1C09, 0x1C12, 0x2A88, 0x2AE8, 0x2AEA, 0x2AED, 0x2AEC,
+ 0x2D56, 0x2AEE, 0x2AEF, 0x2AF0, 0x2AE0, 0x2AF3, 0x2AE2, 0x2AF5, 0x2B0A, 0x2AE5,
+ 0x2AE6, 0x2AE7, 0x2C1D, 0x2AE1, 0x2ADB, 0x2AE3, 0x2CCB, 0x2C1E, 0x2C1F, 0x2C20,
+ 0x2CD7, 0x2CD8, 0x2CDD, 0x2CE0, 0x2CE3, 0x2C1A, 0x2C1B, 0x2C19, 0x2CEE, 0x2AD7,
+ 0x2AD8, 0x2ADF, 0x2CF7, 0x2CFD, 0x2CFE, 0x2CFF, 0x2D05, 0x2D06, 0x2D07, 0x2ADC,
+ 0x2ADD, 0x2D0F, 0x2D16, 0x2D19, 0x2C16, 0x2AC7, 0x2C15, 0x2C1C, 0x2E7E, 0x2EA9,
+ 0x2E82, 0x2E80, 0x2E85, 0x2E83, 0x2E88, 0x2E86, 0x2E8A, 0x2E89, 0x2E90, 0x2E8C,
+ 0x2E98, 0x2E99, 0x2E9A, 0x2E9B, 0x2E95, 0x2E97, 0x2B68, 0x2B65, 0x2E92, 0x2E94,
+ 0x2EAC, 0x2EAE, 0x2E9E, 0x2EA7, 0x2EA2, 0x2EA4, 0x2EB1, 0x2EAF, 0x2EB3, 0x2EB2,
+ 0x2EB6, 0x293A, 0x2EBB, 0x2EBA, 0x2EC1, 0x2AD9, 0x2E8E, 0x2C17, 0x2935, 0x2E96,
+ 0x293C, 0x2C18, 0x2A6E, 0x2E9D, 0x2BC1, 0x2A71, 0x2BC5, 0x2A74, 0x2A77, 0x2BC8,
+ 0x2A7D, 0x2A7A, 0x2BD0, 0x2BCD, 0x2BD6, 0x2BD3, 0x2BDC, 0x2BD9, 0x2A80, 0x2AB0,
+ 0x2A86, 0x2A83, 0x36E7, 0x2C13, 0x2ADE, 0x2A8C, 0x2A89, 0x36E8, 0x2ABD, 0x2A95,
+ 0x2C10, 0x2C12, 0x2A9B, 0x2A8F, 0x2B35, 0x2B32, 0x2B3B, 0x2B38, 0x2B41, 0x2B3E,
+ 0x2B47, 0x2B44, 0x2B4D, 0x2B4A, 0x2B53, 0x2B50, 0x2B59, 0x2B56, 0x2B5F, 0x2B5C,
+ 0x01C9, 0x2E84, 0x2C00, 0x2AA1, 0x36EA, 0x1880, 0x2ABB, 0x2B2F, 0x2C05, 0x2A92,
+ 0x2A98, 0x2EB4, 0x187F, 0x01A2, 0x2AA4, 0x2AB8, 0x2ACA, 0x36E3, 0x1878, 0x2B6B,
+ 0x2AB6, 0x2AC0, 0x1877, 0x2EA8, 0x021F, 0x2EBE, 0x2ACD, 0x1875, 0x187A, 0x2AE9,
+ 0x36E5, 0x0198, 0x2C23, 0x2AF1, 0x2C25, 0x2B05, 0x2B07, 0x2AF7, 0x2B7C, 0x2B7E,
+ 0x2B91, 0x2B8C, 0x2B8E, 0x2BA0, 0x2B03, 0x2B82, 0x2B9C, 0x2C6E, 0x2C8A, 0x47E1,
+ 0x1894, 0x47DF, 0x47E2, 0x47E0, 0x2C8F, 0x2C8E, 0x2C7D, 0x36EB, 0x2C83, 0x2C89,
+ 0x2C94, 0x2C81, 0x2AB4, 0x2C0D, 0x2EB7, 0x2E7F, 0x2E8B, 0x2E93, 0x2EAB, 0x2E9C,
+ 0x2EA5, 0x2EA6, 0x2EA3, 0x2EC0, 0x2EBF, 0x2EBC, 0x2EAA, 0x2EAD, 0x2EB0, 0x2C75,
+ 0x2E87, 0x2EB5, 0x2EBD, 0x2E81, 0x2E9F, 0x2EB8, 0x2E91, 0x2E8D, 0x2BF7, 0x2EA1,
+ 0x2EA0, 0x2BF2, 0x2EB9, 0x2E8F, 0x2EC2, 0x2C73, 0x2CF2, 0x36EF, 0x2CF9, 0x2CF3,
+ 0x2D03, 0x2A9E, 0x2CFB, 0x187D, 0x2D0B, 0x2D0A, 0x1884, 0x2D11, 0x2D17, 0x293B,
+ 0x2D02, 0x2D01, 0x2AA8, 0x2CFA, 0x2939, 0x1882, 0x187C, 0x1876, 0x36E9, 0x36ED,
+ 0x1C3C, 0x1C3D, 0x1C2D, 0x2B2C, 0x187E, 0x2C30, 0x2C14, 0x1C3A, 0x2D13, 0x2953,
+ 0x2B62, 0x2BF0, 0x2D3E, 0x294E, 0x2AD5, 0x2AC2, 0x2955, 0x2ACF, 0x2AD1, 0x2AD3,
+ 0x2D42, 0x2D1A, 0x2D46, 0x2D4A, 0x2CAC, 0x2C93, 0x2CD9, 0x2CB2, 0x2BFA, 0x2AAA,
+ 0x2CF0, 0x2D09, 0x2CE4, 0x2D08, 0x2D3A, 0x2D1D, 0x2D10, 0x1C3B, 0x2CF8, 0x2D00,
+ 0x2952, 0x187B, 0x1879, 0x022A, 0x1870, 0x2954, 0x1C41, 0x1881, 0x186A, 0x186C,
+ 0x36E4, 0x36E6, 0x186B, 0x1883, 0x36D5, 0x36EE, 0x36D4, 0x36EC, 0x36D3, 0x36D6,
+ 0x345D, 0x3473, 0x3457, 0x01F5, 0x345E, 0x47DC, 0x36D7, 0x0B5B, 0x0209, 0x0215,
+ 0x47D6, 0x47DB, 0x47D8, 0x0B61, 0x47DA, 0x01DF, 0x36D8, 0x3460, 0x36DC, 0x3461,
+ 0x345C, 0x36DA, 0x345B, 0x0B5E, 0x36F0, 0x1869, 0x3462, 0x36F1, 0x0B49, 0x022A,
+ 0x36DE, 0x47DD, 0x01C9, 0x01DF, 0x345A, 0x3459, 0x3469, 0x3464, 0x3465, 0x3468,
+ 0x3458, 0x345F, 0x346F, 0x3466, 0x36DD, 0x346D, 0x0198, 0x01A2, 0x0203, 0x186D,
+ 0x0215, 0x0B6A, 0x0B6D, 0x0209, 0x0215, 0x021F, 0x01C9, 0x0234, 0x3463, 0x17BA,
+ 0x17CD, 0x348B, 0x17B9, 0x17D2, 0x0198, 0x0234, 0x0215, 0x0209, 0x17D4, 0x17D0,
+ 0x17D1, 0x021F, 0x17CF, 0x17CE, 0x17B8, 0x343F, 0x0140, 0x17C9, 0x344A, 0x343D,
+ 0x01F5, 0x17C8, 0x0142, 0x17C6, 0x17C7, 0x17CA, 0x17D5, 0x343C, 0x17CB, 0x17CC,
+ 0x01C9, 0x01DF, 0x0143, 0x0144, 0x17BB, 0x01A2, 0x17D7, 0x17D8, 0x0145, 0x17E0,
+ 0x17E2, 0x343B, 0x17D6, 0x346A, 0x346E, 0x17DC, 0x17E4, 0x3467, 0x17D3, 0x17E7,
+ 0x346C, 0x17DA, 0x3477, 0x0146, 0x3449, 0x346B, 0x3476, 0x3475, 0x347C, 0x01C9,
+ 0x022A, 0x17E1, 0x347D, 0x347E, 0x3445, 0x3444, 0x3446, 0x1867, 0x1866, 0x347F,
+ 0x3482, 0x3481, 0x3486, 0x3480, 0x3488, 0x348A, 0x1874, 0x348C, 0x3487, 0x3489,
+ 0x3485, 0x1DC8, 0x348E, 0x348D, 0x01DF, 0x1DAA, 0x1871, 0x186F, 0x3483, 0x3484,
+ 0x1873, 0x0B1C, 0x186E, 0x0B6E, 0x0B58, 0x0B13, 0x0B1F, 0x0B19, 0x01EC, 0x188B,
+ 0x1890, 0x1DAE, 0x188A, 0x17E3, 0x17DF, 0x1889, 0x1872, 0x17E6, 0x1DAB, 0x0B70,
+ 0x17E5, 0x0B25, 0x47DE, 0x0B79, 0x1DA9, 0x0B52, 0x0B82, 0x0B86, 0x0B1A, 0x188D,
+ 0x188E, 0x188F, 0x0B71, 0x1891, 0x0B8C, 0x47D7, 0x022A, 0x1DBB, 0x0215, 0x0209,
+ 0x01F5, 0x17BC, 0x17BD, 0x17BE, 0x021F, 0x17BF, 0x17C0, 0x0234, 0x17C1, 0x17C2,
+ 0x17C3, 0x17C4, 0x17C5, 0x0B38, 0x0B17, 0x47D9, 0x0B4A, 0x0B53, 0x0B5C, 0x0B5F,
+ 0x0B14, 0x0B47, 0x0B62, 0x0B65, 0x0B68, 0x0B6B, 0x0B59, 0x0B8A, 0x0B56, 0x0B7A,
+ 0x0141, 0x0B7D, 0x17D9, 0x0B3B, 0x0B80, 0x0B26, 0x0B84, 0x0B77, 0x0B87, 0x0B74,
+ 0x0B89, 0x0B88, 0x0B8E, 0x0B8D, 0x47D5, 0x0B83, 0x3470, 0x3471, 0x3472, 0x1DDC,
+ 0x3474, 0x1DD4, 0x1DE0, 0x1DE5, 0x3478, 0x3479, 0x347A, 0x347B, 0x1D9D, 0x1DDF,
+ 0x1DDE, 0x1DE7, 0x120C, 0x1210, 0x120D, 0x120E, 0x1DB1, 0x1DB4, 0x1DB5, 0x1DC7,
+ 0x1DBE, 0x1DC1, 0x1DC2, 0x1DC3, 0x1DE8, 0x1DCF, 0x1DCC, 0x0198, 0x01A2, 0x2B34,
+ 0x2B31, 0x2B74, 0x2B40, 0x2B2E, 0x021F, 0x2B75, 0x2B6F, 0x2B2B, 0x2B70, 0x2B71,
+ 0x2B43, 0x2B76, 0x2B3D, 0x2B49, 0x2B4F, 0x1DDB, 0x2B55, 0x1DDD, 0x2B67, 0x2B3A,
+ 0x2B37, 0x2B52, 0x2B72, 0x2B5B, 0x2B46, 0x2B4C, 0x2B73, 0x2B6A, 0x2B6D, 0x2B58,
+ 0x0198, 0x01A2, 0x01C9, 0x01DF, 0x021F, 0x2AF8, 0x2AF9, 0x2AFA, 0x0234, 0x01F5,
+ 0x2AF4, 0x11FD, 0x0209, 0x2AF2, 0x2AF6, 0x0215, 0x1211, 0x11FF, 0x11FE, 0x123A,
+ 0x120F, 0x1215, 0x1201, 0x11FC, 0x022A, 0x1212, 0x1213, 0x1214, 0x1DD6, 0x1216,
+ 0x1217, 0x1218, 0x2B61, 0x1D94, 0x1243, 0x1238, 0x1DCB, 0x1239, 0x2B6E, 0x1DDA,
+ 0x1237, 0x1208, 0x1264, 0x1265, 0x1236, 0x1263, 0x1DA6, 0x123D, 0x1DD9, 0x2B5E,
+ 0x11FB, 0x2B64, 0x1221, 0x1D77, 0x1D79, 0x1D7B, 0x1DB2, 0x1D8D, 0x1D97, 0x1DAC,
+ 0x1D84, 0x1DB6, 0x1DB7, 0x1DBC, 0x1106, 0x1107, 0x1108, 0x1109, 0x1155, 0x1156,
+ 0x1157, 0x1158, 0x125E, 0x125F, 0x1260, 0x1261, 0x215C, 0x126B, 0x126C, 0x126D,
+ 0x1204, 0x1205, 0x120A, 0x1209, 0x120B, 0x1200, 0x123C, 0x1202, 0x215A, 0x2164,
+ 0x1206, 0x1207, 0x2162, 0x20E4, 0x2166, 0x2168, 0x20CA, 0x0B16, 0x20CE, 0x20D0,
+ 0x20CC, 0x0B22, 0x20D2, 0x0B2B, 0x0B2E, 0x0B31, 0x0B34, 0x0B37, 0x0B3A, 0x0B40,
+ 0x0B43, 0x0B46, 0x20DA, 0x20DC, 0x20E6, 0x20E8, 0x20E2, 0x20D4, 0x20D6, 0x20D8,
+ 0x0B64, 0x0B67, 0x20DE, 0x20E0, 0x2102, 0x0B73, 0x0B76, 0x0B7C, 0x210C, 0x210E,
+ 0x2110, 0x2136, 0x2114, 0x2134, 0x2118, 0x2138, 0x213A, 0x213C, 0x210A, 0x2140,
+ 0x2116, 0x2144, 0x213E, 0x2148, 0x0B11, 0x2132, 0x2130, 0x2142, 0x0B1D, 0x0B20,
+ 0x0B23, 0x0B29, 0x212E, 0x0B2F, 0x0B32, 0x0B35, 0x212C, 0x0B3E, 0x0B41, 0x212A,
+ 0x214A, 0x214C, 0x214E, 0x2150, 0x2112, 0x2154, 0x2156, 0x2158, 0x211A, 0x211C,
+ 0x211E, 0x2120, 0x2122, 0x2124, 0x2126, 0x2128, 0x216A, 0x216C, 0x216E, 0x2170,
+ 0x2172, 0x2174, 0x2152, 0x215E, 0x2169, 0x216B, 0x216D, 0x216F, 0x2171, 0x2173,
+ 0x2146, 0x2160, 0x4644, 0x4645, 0x4647, 0x464E, 0x463F, 0x4640, 0x4640, 0x4642,
+ 0x4639, 0x463B, 0x463C, 0x463D, 0x4661, 0x4662, 0x4663, 0x4627, 0x461F, 0x4620,
+ 0x4621, 0x4622, 0x48CF, 0x4619, 0x461A, 0x461D, 0x4611, 0x4612, 0x4613, 0x4614,
+ 0x4638, 0x4634, 0x4636, 0x4637, 0x22E0, 0x22DC, 0x4916, 0x22DF, 0x462F, 0x22DD,
+ 0x22DE, 0x4630, 0x22E7, 0x4631, 0x4915, 0x4748, 0x22E8, 0x22E1, 0x22E2, 0x22E3,
+ 0x462C, 0x22E5, 0x462D, 0x4629, 0x22F0, 0x22F9, 0x462A, 0x22E9, 0x22F4, 0x22F7,
+ 0x22F6, 0x22E6, 0x22F8, 0x22F5, 0x22FA, 0x22FB, 0x462A, 0x462A, 0x48CB, 0x4912,
+ 0x45F6, 0x45F7, 0x45EF, 0x45F0, 0x45F3, 0x45F1, 0x45E6, 0x45EA, 0x45EB, 0x45ED,
+ 0x45DE, 0x45DC, 0x230F, 0x45DF, 0x2310, 0x490E, 0x2312, 0x230D, 0x230E, 0x4970,
+ 0x230C, 0x460B, 0x2316, 0x2317, 0x2314, 0x2311, 0x460C, 0x2313, 0x48CE, 0x114D,
+ 0x4603, 0x45E4, 0x4604, 0x1154, 0x4605, 0x45F9, 0x115A, 0x45FF, 0x4911, 0x4602,
+ 0x115E, 0x45F8, 0x1160, 0x1161, 0x2319, 0x2315, 0x45FD, 0x490F, 0x48CC, 0x492F,
+ 0x231A, 0x231B, 0x4713, 0x48E1, 0x4715, 0x470C, 0x470D, 0x470E, 0x4711, 0x4709,
+ 0x4705, 0x470B, 0x48E0, 0x4700, 0x1178, 0x4706, 0x4708, 0x492E, 0x117C, 0x4721,
+ 0x117D, 0x117E, 0x4723, 0x471F, 0x4725, 0x491C, 0x4932, 0x471E, 0x4933, 0x471A,
+ 0x471C, 0x471D, 0x4931, 0x4930, 0x118A, 0x118B, 0x4716, 0x3DD9, 0x3DDA, 0x118F,
+ 0x1190, 0x1191, 0x3DD3, 0x3DD4, 0x3DD5, 0x3DD6, 0x3DCF, 0x3DD0, 0x3DD1, 0x3DD2,
+ 0x3DCB, 0x3DCC, 0x3DCD, 0x3DCE, 0x3DE7, 0x3DE8, 0x3DE9, 0x3DEA, 0x3DE3, 0x3DE4,
+ 0x3DE5, 0x3DE6, 0x3DDF, 0x3DE0, 0x3DE1, 0x3DE2, 0x3DDB, 0x3DDC, 0x3DDD, 0x3DDE,
+ 0x3E57, 0x3E58, 0x3E59, 0x3E5A, 0x3E53, 0x3E54, 0x3E55, 0x3E56, 0x3E4F, 0x3E50,
+ 0x3E51, 0x3E52, 0x3E4B, 0x3E4C, 0x3E4D, 0x3E4E, 0x3E63, 0x3E64, 0x3E5F, 0x3E60,
+ 0x3E61, 0x3E62, 0x3E5B, 0x3E5C, 0x3E5D, 0x3E5E, 0x3B37, 0x3B38, 0x3B39, 0x35B6,
+ 0x35B5, 0x35B8, 0x35B7, 0x35BA, 0x35B9, 0x35BC, 0x35BB, 0x35BE, 0x35BD, 0x35C0,
+ 0x35BF, 0x35C2, 0x35C1, 0x35C4, 0x35C3, 0x35C6, 0x35C5, 0x35C8, 0x35C7, 0x35CA,
+ 0x35C9, 0x35CC, 0x35CB, 0x35CE, 0x35CD, 0x35D0, 0x35CF, 0x35D2, 0x35D1, 0x35D4,
+ 0x35D3, 0x35D6, 0x35D5, 0x35D8, 0x35D7, 0x3B3A, 0x3B33, 0x35DC, 0x35DB, 0x233D,
+ 0x233E, 0x233F, 0x235C, 0x235F, 0x2343, 0x235E, 0x235D, 0x35E6, 0x35E5, 0x35E8,
+ 0x35E7, 0x35EA, 0x35E9, 0x35EC, 0x35EB, 0x35EE, 0x35ED, 0x35F0, 0x35EF, 0x35F2,
+ 0x35F1, 0x35F4, 0x35F3, 0x234D, 0x2350, 0x234F, 0x2352, 0x2351, 0x235A, 0x2359,
+ 0x233C, 0x2341, 0x2342, 0x3607, 0x3608, 0x3605, 0x3606, 0x360C, 0x2346, 0x2345,
+ 0x361E, 0x2347, 0x361D, 0x2364, 0x2360, 0x2370, 0x22EF, 0x2375, 0x2361, 0x2362,
+ 0x22F2, 0x22ED, 0x22EE, 0x22EC, 0x22C8, 0x3619, 0x22F3, 0x361F, 0x235B, 0x35D9,
+ 0x35DA, 0x22C9, 0x361A, 0x35DD, 0x35DE, 0x35DF, 0x35E0, 0x35E1, 0x35E2, 0x35E3,
+ 0x35E4, 0x2395, 0x2396, 0x2397, 0x22F1, 0x2399, 0x239A, 0x3CF3, 0x3CF7, 0x3BAB,
+ 0x3D26, 0x3BB9, 0x3BB8, 0x3BBA, 0x3BB7, 0x3BB3, 0x3BB4, 0x362E, 0x3BB1, 0x3617,
+ 0x3618, 0x3632, 0x3631, 0x3630, 0x3ADE, 0x3616, 0x3635, 0x3615, 0x3D1F, 0x3ADD,
+ 0x361B, 0x3ADB, 0x361C, 0x3638, 0x3636, 0x3639, 0x3637, 0x363C, 0x3628, 0x363D,
+ 0x3BC7, 0x362A, 0x3BAE, 0x363E, 0x363F, 0x3BC8, 0x363B, 0x363A, 0x362F, 0x362D,
+ 0x3BAC, 0x362C, 0x3AE1, 0x3624, 0x3AE2, 0x3633, 0x3634, 0x3BAD, 0x3629, 0x3BB5,
+ 0x3626, 0x3627, 0x3BB2, 0x3BC3, 0x3BC4, 0x3620, 0x362B, 0x3622, 0x3623, 0x3BC9,
+ 0x3625, 0x3B8B, 0x3B8C, 0x3B8D, 0x3B8E, 0x3B8F, 0x3B90, 0x3B91, 0x3B92, 0x3B93,
+ 0x3B94, 0x3B95, 0x3B96, 0x35F7, 0x35F8, 0x35F9, 0x35FA, 0x3603, 0x3604, 0x3601,
+ 0x35FE, 0x3D1E, 0x35FD, 0x35FF, 0x3602, 0x3600, 0x3B9A, 0x3D1D, 0x3D1C, 0x3BA7,
+ 0x3D1B, 0x3609, 0x360A, 0x360B, 0x35F6, 0x360D, 0x360E, 0x360F, 0x3610, 0x3611,
+ 0x3612, 0x3613, 0x3614, 0x35F5, 0x3621, 0x3B97, 0x3B98, 0x3B99, 0x3BCA, 0x35FB,
+ 0x35FC, 0x3BBD, 0x3BBE, 0x3BBC, 0x3BC1, 0x3BBB, 0x3BC2, 0x3D21, 0x3D20, 0x3D22,
+ 0x3BC6, 0x3BBF, 0x3BC0, 0x3BC5, 0x3DB8, 0x3B4C, 0x3B4B, 0x3B4E, 0x3B4D, 0x3B50,
+ 0x3B4F, 0x3B52, 0x3B51, 0x3B54, 0x3B53, 0x3B56, 0x3B55, 0x3B58, 0x3B57, 0x3B5A,
+ 0x3B59, 0x3B9B, 0x3B9C, 0x3B9D, 0x3B9E, 0x3B9F, 0x3BA0, 0x3BA1, 0x3BA2, 0x3B64,
+ 0x3B63, 0x3BA5, 0x3BA6, 0x3B68, 0x3B67, 0x3B6A, 0x3B69, 0x3B6C, 0x3B6B, 0x3B6E,
+ 0x3B6D, 0x3B70, 0x3B6F, 0x3B72, 0x3B71, 0x3B74, 0x3B73, 0x3B76, 0x3B75, 0x3B78,
+ 0x3B77, 0x3B7A, 0x3B79, 0x3B7C, 0x3B7B, 0x3B7E, 0x3B7D, 0x3B80, 0x3B7F, 0x3B82,
+ 0x3B81, 0x3B84, 0x3B83, 0x3B86, 0x3B85, 0x3B88, 0x3B87, 0x3B8A, 0x3B89, 0x3BA3,
+ 0x3BA4, 0x3BA9, 0x3BAA, 0x3BA8, 0x3378, 0x3377, 0x337A, 0x3379, 0x337D, 0x337B,
+ 0x337E, 0x337C, 0x3380, 0x337F, 0x3382, 0x3381, 0x3384, 0x3383, 0x3386, 0x3385,
+ 0x3389, 0x3387, 0x3388, 0x338A, 0x338C, 0x338B, 0x338E, 0x338D, 0x3390, 0x338F,
+ 0x3392, 0x3391, 0x3394, 0x3393, 0x3396, 0x3395, 0x3398, 0x3397, 0x339A, 0x3399,
+ 0x339B, 0x339C, 0x339E, 0x339D, 0x33A0, 0x339F, 0x33A2, 0x33A1, 0x33A4, 0x33A3,
+ 0x33A6, 0x33A5, 0x33A8, 0x33A7, 0x33AA, 0x33A9, 0x33AC, 0x33AB, 0x33AE, 0x33AD,
+ 0x33B0, 0x33AF, 0x33B2, 0x33B1, 0x33B4, 0x33B3, 0x33B5, 0x3BD1, 0x3BD2, 0x33BA,
+ 0x33B7, 0x3BCD, 0x3BD6, 0x33BB, 0x3BCE, 0x3BD4, 0x3BD0, 0x3BDA, 0x33B9, 0x3BDC,
+ 0x3BDB, 0x3BDE, 0x3BDD, 0x01A2, 0x3BD3, 0x3BE2, 0x33BC, 0x3BE4, 0x3BE6, 0x3BE3,
+ 0x3BCF, 0x3BE8, 0x3BEA, 0x3BE7, 0x3BE9, 0x01C9, 0x1176, 0x1175, 0x33B8, 0x1177,
+ 0x117A, 0x1179, 0x1174, 0x117B, 0x01F5, 0x0209, 0x118E, 0x3BD7, 0x3BD8, 0x3BD9,
+ 0x0215, 0x021F, 0x10F8, 0x3BFE, 0x3BFD, 0x10F9, 0x10F7, 0x1102, 0x3C01, 0x10FD,
+ 0x10FF, 0x10FE, 0x1101, 0x1100, 0x10FC, 0x10FB, 0x10FA, 0x3D0B, 0x3D0C, 0x3D0E,
+ 0x33B6, 0x3D0F, 0x3D10, 0x3D0D, 0x3D12, 0x3D13, 0x3D14, 0x3D15, 0x3D16, 0x3D17,
+ 0x3D18, 0x3D11, 0x3D1A, 0x10F6, 0x10E5, 0x10E9, 0x10EC, 0x10E8, 0x1103, 0x1104,
+ 0x1105, 0x3D23, 0x3D24, 0x3D25, 0x3D19, 0x3D27, 0x3D28, 0x3D29, 0x3D2A, 0x3D2B,
+ 0x3D2C, 0x3D2D, 0x3D30, 0x3D31, 0x3D32, 0x3D33, 0x3D34, 0x3D35, 0x3D36, 0x3D37,
+ 0x3D38, 0x3D39, 0x3D3A, 0x3D3B, 0x3D3C, 0x3D3D, 0x3D3E, 0x3D3F, 0x3D40, 0x3D41,
+ 0x3D42, 0x3D43, 0x3D44, 0x3D45, 0x3D46, 0x3D47, 0x3D48, 0x3D49, 0x3D4A, 0x3D4B,
+ 0x3D4C, 0x1114, 0x1145, 0x1138, 0x113C, 0x1151, 0x1184, 0x10EA, 0x10EB, 0x1147,
+ 0x1113, 0x1149, 0x10F0, 0x114A, 0x1148, 0x1170, 0x1119, 0x113E, 0x11D3, 0x11D4,
+ 0x11D9, 0x11DA, 0x11D7, 0x110C, 0x110D, 0x110E, 0x110B, 0x1111, 0x11DD, 0x11DE,
+ 0x11DF, 0x1112, 0x11DC, 0x11D8, 0x3CAC, 0x1116, 0x11E8, 0x111E, 0x11E7, 0x110F,
+ 0x1115, 0x111A, 0x11F3, 0x11F2, 0x11E1, 0x112D, 0x11E0, 0x11E2, 0x11F9, 0x11F8,
+ 0x121D, 0x1182, 0x1187, 0x1186, 0x122A, 0x1188, 0x121F, 0x1220, 0x121E, 0x1226,
+ 0x1222, 0x1224, 0x1244, 0x1245, 0x1246, 0x3C8C, 0x3C8B, 0x3C8E, 0x3C8D, 0x3C90,
+ 0x3C8F, 0x3C92, 0x3C91, 0x3C94, 0x3C93, 0x3C96, 0x3C95, 0x3C98, 0x3C97, 0x3C9A,
+ 0x3C99, 0x123F, 0x1240, 0x1241, 0x1242, 0x3CA0, 0x3C9F, 0x123B, 0x3CA1, 0x3CA4,
+ 0x3CA3, 0x3CA6, 0x3CA5, 0x3CA8, 0x3CA7, 0x3CAA, 0x3CA9, 0x2BB5, 0x3CAB, 0x3CAE,
+ 0x3CAD, 0x3CB0, 0x3CAF, 0x3CB2, 0x3CB1, 0x3CB4, 0x3CB3, 0x3CB6, 0x3CB5, 0x3CB8,
+ 0x3CB7, 0x3CBA, 0x3CB9, 0x3CBC, 0x3CBB, 0x3CBE, 0x3CBD, 0x3CC0, 0x3CBF, 0x3CC2,
+ 0x3CC1, 0x3CC4, 0x3CC3, 0x3CC6, 0x3CC5, 0x3CC8, 0x3CC7, 0x3CCA, 0x3CC9, 0x3CCC,
+ 0x3CCB, 0x1262, 0x1268, 0x3CD0, 0x3CCF, 0x3CCD, 0x3CCE, 0x3CD4, 0x3CD3, 0x3CD6,
+ 0x3CD5, 0x1266, 0x1269, 0x3CD1, 0x3CD2, 0x3CDC, 0x3CDB, 0x3CDE, 0x3CDD, 0x3CE0,
+ 0x3CDF, 0x3CE2, 0x3CE1, 0x3CE4, 0x3CE3, 0x3CE6, 0x3CE5, 0x3CE8, 0x3CE7, 0x3CEA,
+ 0x3CE9, 0x1223, 0x118D, 0x3CFD, 0x1271, 0x1270, 0x1185, 0x1267, 0x3CFC, 0x118C,
+ 0x126F, 0x1227, 0x1228, 0x1229, 0x122C, 0x122B, 0x3CDA, 0x122D, 0x0063, 0x0234,
+ 0x0062, 0x0065, 0x1181, 0x005F, 0x1183, 0x0061, 0x3CFE, 0x125A, 0x2BAF, 0x2BB0,
+ 0x2BB1, 0x3CD9, 0x2BB3, 0x3CEB, 0x3CEC, 0x2BB6, 0x2BB2, 0x3CEF, 0x3CF0, 0x3CED,
+ 0x3CEE, 0x3D03, 0x3CF4, 0x3CF5, 0x3CF6, 0x2BAD, 0x2BAE, 0x3CF1, 0x3CF2, 0x3CFB,
+ 0x3CFF, 0x3CF9, 0x3CFA, 0x2BAB, 0x3D00, 0x3D01, 0x3D02, 0x3D04, 0x2BAC, 0x3D05,
+ 0x3D06, 0x3D07, 0x3D08, 0x3D09, 0x3D0A, 0x125C, 0x2C39, 0x2C3B, 0x005D, 0x005C,
+ 0x2C3A, 0x005E, 0x0060, 0x0066, 0x3CF8, 0x022A, 0x01DF, 0x3CD7, 0x3CD8, 0x125B,
+ 0x0064, 0x125D, 0x124E, 0x124F, 0x1250, 0x1251, 0x1252, 0x1253, 0x1254, 0x1255,
+ 0x1256, 0x1259, 0x1258, 0x2C3F, 0x1257, 0x2C38, 0x2BB4, 0x3D4E, 0x3D4D, 0x3D75,
+ 0x3D9B, 0x3D52, 0x3D51, 0x3D4F, 0x3D50, 0x3D56, 0x3D55, 0x3D58, 0x3D57, 0x3D5A,
+ 0x3D59, 0x3D53, 0x3D54, 0x3D5E, 0x3D5D, 0x3D60, 0x3D5F, 0x3D62, 0x3D61, 0x3D64,
+ 0x3D63, 0x3D66, 0x3D65, 0x3D68, 0x3D67, 0x3D6A, 0x3D69, 0x3D6C, 0x3D6B, 0x3D6E,
+ 0x3D6D, 0x3D70, 0x3D6F, 0x3D72, 0x3D71, 0x3D74, 0x3D73, 0x3D76, 0x3D86, 0x3D78,
+ 0x3D77, 0x3D7A, 0x3D79, 0x3D7C, 0x3D7B, 0x3D7E, 0x3D7D, 0x3D80, 0x3D7F, 0x3D82,
+ 0x3D81, 0x3D84, 0x3D83, 0x3D5C, 0x3D85, 0x3D88, 0x3D87, 0x3D8A, 0x3D89, 0x3D8C,
+ 0x3D8B, 0x3D8E, 0x3D8D, 0x3D90, 0x3D8F, 0x3D92, 0x3D91, 0x3DB3, 0x3D93, 0x3D96,
+ 0x3DA4, 0x3D98, 0x3D97, 0x3D9A, 0x3D99, 0x3D9C, 0x3D94, 0x3D9E, 0x3D5B, 0x3DA0,
+ 0x3D9F, 0x3D2F, 0x3D2E, 0x3DA2, 0x3DA1, 0x3D9D, 0x3DA3, 0x3DA6, 0x3DA5, 0x3DA8,
+ 0x3DA7, 0x3DAA, 0x3DA9, 0x3DAD, 0x3DAB, 0x3DAE, 0x3DC8, 0x3DB1, 0x3DAF, 0x3DB2,
+ 0x3DAC, 0x3DB5, 0x3DC4, 0x3DB6, 0x3DB0, 0x3DBA, 0x3DB7, 0x3DC9, 0x3DB4, 0x3DBC,
+ 0x3DBB, 0x3DBE, 0x3DBD, 0x3DC0, 0x3DBF, 0x3DC2, 0x3DC1, 0x3D95, 0x3DC3, 0x3DC6,
+ 0x3DC5, 0x3DCA, 0x3DC7, 0x4919, 0x4918, 0x466C, 0x3DD7, 0x3DEF, 0x3E1A, 0x48D0,
+ 0x466F, 0x4671, 0x48D1, 0x3DD8, 0x4673, 0x4675, 0x491A, 0x4677, 0x4676, 0x491B,
+ 0x4679, 0x4626, 0x4625, 0x467C, 0x46A1, 0x467E, 0x48D2, 0x4684, 0x4682, 0x491D,
+ 0x4683, 0x491E, 0x4686, 0x4688, 0x4689, 0x469E, 0x4928, 0x3DF7, 0x3DEB, 0x3DEE,
+ 0x3DED, 0x3DF0, 0x3DEC, 0x3DF2, 0x3DF1, 0x3E03, 0x3DF3, 0x3DF6, 0x3DF5, 0x3DF8,
+ 0x3DF4, 0x3DFA, 0x3DF9, 0x3DFF, 0x3DFB, 0x3DFE, 0x3DFD, 0x3E00, 0x3DFC, 0x3E02,
+ 0x3E01, 0x3E07, 0x4921, 0x3E06, 0x3E05, 0x3E08, 0x3E04, 0x3E0A, 0x3E09, 0x3E0C,
+ 0x3E0B, 0x3E0E, 0x3E0D, 0x3E10, 0x3E0F, 0x3E12, 0x3E11, 0x3E14, 0x3E24, 0x3E16,
+ 0x3E15, 0x3E18, 0x3E17, 0x3E2F, 0x3E19, 0x3E1C, 0x3E1B, 0x3E1E, 0x3E1D, 0x3E20,
+ 0x3E1F, 0x3E22, 0x3E21, 0x3DB9, 0x3E23, 0x3E26, 0x3E25, 0x3E28, 0x3E27, 0x3E2A,
+ 0x3E29, 0x3E2C, 0x3E2B, 0x3E2E, 0x3E2D, 0x3E30, 0x3E40, 0x3E32, 0x3E31, 0x3E34,
+ 0x3E33, 0x3E36, 0x3E35, 0x3E38, 0x3E37, 0x3E3A, 0x3E39, 0x3E3C, 0x3E3B, 0x3E3E,
+ 0x3E3D, 0x3E13, 0x3E3F, 0x3E42, 0x3E41, 0x3E44, 0x3E43, 0x3E46, 0x3E45, 0x3E48,
+ 0x3E47, 0x3E4A, 0x3E49, 0x468E, 0x48D3, 0x468A, 0x468D, 0x4691, 0x4692, 0x48D4,
+ 0x491F, 0x48D5, 0x4695, 0x468F, 0x4690, 0x46AA, 0x497A, 0x4696, 0x4697, 0x4921,
+ 0x47F2, 0x46A0, 0x46A0, 0x48D6, 0x46C7, 0x4952, 0x46A2, 0x48ED, 0x48D7, 0x46A6,
+ 0x46A9, 0x46AC, 0x46A4, 0x472D, 0x4729, 0x472B, 0x472A, 0x472F, 0x472E, 0x4728,
+ 0x4934, 0x4736, 0x4735, 0x473A, 0x48E3, 0x4935, 0x4739, 0x4740, 0x493A, 0x4937,
+ 0x4936, 0x4746, 0x4741, 0x4744, 0x4745, 0x4747, 0x48E4, 0x4749, 0x474A, 0x4910,
+ 0x474C, 0x4938, 0x474F, 0x476C, 0x4752, 0x4759, 0x4757, 0x493B, 0x475A, 0x4733,
+ 0x475C, 0x493D, 0x493C, 0x4765, 0x4763, 0x4766, 0x48E5, 0x48E6, 0x475D, 0x476D,
+ 0x48E9, 0x4770, 0x476F, 0x48E7, 0x4773, 0x493E, 0x4775, 0x493F, 0x4624, 0x4920,
+ 0x477A, 0x4940, 0x477C, 0x4942, 0x4941, 0x4777, 0x48E8, 0x4944, 0x4787, 0x4784,
+ 0x4943, 0x4786, 0x48EC, 0x4946, 0x4787, 0x48EB, 0x478E, 0x4789, 0x478A, 0x494C,
+ 0x48F3, 0x4948, 0x47AB, 0x48EE, 0x4791, 0x4799, 0x4949, 0x494B, 0x494A, 0x47A3,
+ 0x47A0, 0x47A5, 0x48EF, 0x47A7, 0x47A6, 0x47BF, 0x4945, 0x494D, 0x494D, 0x478C,
+ 0x48E6, 0x47AF, 0x47AE, 0x48F0, 0x494E, 0x48F2, 0x47B5, 0x47B7, 0x47B9, 0x4951,
+ 0x47BA, 0x48F1, 0x494F, 0x47C4, 0x47C2, 0x48F4, 0x47C8, 0x4652, 0x4953, 0x4955,
+ 0x48F5, 0x4956, 0x47CC, 0x47D1, 0x47CE, 0x4957, 0x47E4, 0x47E6, 0x4958, 0x47E8,
+ 0x4959, 0x48F6, 0x4929, 0x47ED, 0x495A, 0x47EE, 0x48F8, 0x47EC, 0x4670, 0x492A,
+ 0x495B, 0x47F2, 0x47F8, 0x4860, 0x47F3, 0x480B, 0x48F9, 0x47F9, 0x47F7, 0x48FB,
+ 0x495C, 0x47FC, 0x47FB, 0x47FA, 0x47FE, 0x47FF, 0x47FD, 0x4805, 0x4810, 0x4806,
+ 0x4800, 0x4804, 0x4618, 0x4808, 0x4803, 0x480A, 0x4809, 0x495F, 0x495D, 0x48FA,
+ 0x495E, 0x4813, 0x4812, 0x4963, 0x4815, 0x492B, 0x4816, 0x48FC, 0x48FE, 0x4962,
+ 0x4961, 0x481D, 0x487E, 0x481F, 0x481E, 0x4822, 0x4820, 0x4824, 0x4821, 0x4827,
+ 0x4823, 0x4826, 0x4825, 0x48FD, 0x4828, 0x482B, 0x482A, 0x482E, 0x48FF, 0x4964,
+ 0x482F, 0x4833, 0x4832, 0x4836, 0x4900, 0x4965, 0x4855, 0x4901, 0x4966, 0x483D,
+ 0x4902, 0x484A, 0x4843, 0x4967, 0x484C, 0x484E, 0x484D, 0x4854, 0x4853, 0x4913,
+ 0x4969, 0x496D, 0x4856, 0x4914, 0x4858, 0x485D, 0x485A, 0x48CD, 0x4960, 0x486B,
+ 0x4868, 0x496A, 0x496B, 0x4876, 0x486E, 0x487A, 0x4879, 0x487D, 0x4878, 0x486D,
+ 0x496C, 0x4903, 0x487F, 0x496E, 0x4881, 0x488C, 0x4904, 0x4891, 0x468B, 0x4971,
+ 0x496F, 0x4906, 0x4905, 0x4972, 0x4896, 0x4973, 0x4907, 0x4898, 0x4898, 0x3B34,
+ 0x3B35, 0x3B36, 0x3B2F, 0x3B30, 0x3B31, 0x3B32, 0x3B2B, 0x3B2C, 0x3B2D, 0x3B2E,
+ 0x3B47, 0x3B48, 0x3B49, 0x3B4A, 0x3B43, 0x3B44, 0x3B45, 0x3B46, 0x3B3F, 0x3B40,
+ 0x3B41, 0x3B42, 0x3B3B, 0x3B3C, 0x3B3D, 0x3B3E, 0x3B17, 0x3B18, 0x3B19, 0x3B1A,
+ 0x3B13, 0x3B14, 0x3B15, 0x3B16, 0x3B0F, 0x3B10, 0x3B11, 0x3B12, 0x3B0B, 0x3B0C,
+ 0x3B0D, 0x3B0E, 0x3B27, 0x3B28, 0x3B29, 0x2BA7, 0x3B2A, 0x3B23, 0x3B24, 0x3B25,
+ 0x3B26, 0x3B1F, 0x3B20, 0x3B21, 0x3B22, 0x3B1B, 0x3B1C, 0x3B1D, 0x3B1E, 0x3AF7,
+ 0x3AF8, 0x3AF9, 0x3AFA, 0x3AF3, 0x3AF4, 0x3AF5, 0x3AF6, 0x3AEF, 0x3AF0, 0x3AF1,
+ 0x2BA8, 0x3AF2, 0x3AEB, 0x3AEC, 0x3AED, 0x3AEE, 0x3B07, 0x3B08, 0x3B09, 0x3B0A,
+ 0x3B03, 0x3B04, 0x3B05, 0x3B06, 0x3AFF, 0x3B00, 0x3B01, 0x3B02, 0x3AFB, 0x3AFC,
+ 0x3AFD, 0x3AFE, 0x3AD7, 0x3AD8, 0x3AD9, 0x466B, 0x466D, 0x3EE6, 0x3EE5, 0x3EE8,
+ 0x3EE7, 0x466A, 0x3EE9, 0x3F0A, 0x4673, 0x3EEE, 0x3EED, 0x3EF0, 0x3EEF, 0x3EF2,
+ 0x3EF1, 0x3EF4, 0x3EF3, 0x3EF6, 0x3EF5, 0x3EF8, 0x3EF7, 0x3EFA, 0x3EF9, 0x3EFC,
+ 0x3EFB, 0x3EFE, 0x3EFD, 0x3F00, 0x3EFF, 0x3F02, 0x3F09, 0x3F04, 0x3F03, 0x3F06,
+ 0x3F05, 0x3F08, 0x3F07, 0x3F21, 0x3F1A, 0x3F0C, 0x3ADA, 0x3F10, 0x3F0B, 0x3AD3,
+ 0x3F0E, 0x3AD4, 0x3AD5, 0x3F0F, 0x3AD6, 0x3F16, 0x3F15, 0x3F18, 0x3F17, 0x3F1C,
+ 0x46D4, 0x46CB, 0x3F1B, 0x46CA, 0x3F1D, 0x3ACF, 0x3AD0, 0x3F22, 0x46C6, 0x3F24,
+ 0x3F23, 0x3AD1, 0x3AD2, 0x3ACB, 0x3ACC, 0x4699, 0x3ACD, 0x3ACE, 0x3AE7, 0x3AE8,
+ 0x3AE9, 0x3AEA, 0x3AE3, 0x3AE4, 0x3AE5, 0x3AE6, 0x3ADF, 0x3AE0, 0x3ADC, 0x3BB6,
+ 0x3BAF, 0x46C4, 0x3BB0, 0x46C3, 0x3B65, 0x3B66, 0x46CF, 0x3B5F, 0x46D3, 0x3B60,
+ 0x3B61, 0x3B62, 0x3B5B, 0x3B5C, 0x3B5D, 0x3B5E, 0x3C37, 0x3C38, 0x3C39, 0x3C3A,
+ 0x3C33, 0x3C34, 0x3C35, 0x3C36, 0x3C2F, 0x3C30, 0x3C31, 0x3C32, 0x3C2B, 0x3C2C,
+ 0x3C2D, 0x3C2E, 0x3C47, 0x3C48, 0x3C49, 0x3C4A, 0x3C43, 0x3C44, 0x3C45, 0x3C46,
+ 0x3C3F, 0x3C40, 0x3C41, 0x3C42, 0x46D2, 0x3C3B, 0x3C3C, 0x3C3D, 0x3C3E, 0x3C17,
+ 0x3C18, 0x3C19, 0x3C1A, 0x3C13, 0x3C14, 0x3C15, 0x3C16, 0x3C0F, 0x3C10, 0x3C11,
+ 0x3C12, 0x3C0B, 0x3C0C, 0x3C0D, 0x3C0E, 0x3C27, 0x3C28, 0x3C29, 0x3C2A, 0x3C23,
+ 0x46D0, 0x3C24, 0x3C25, 0x3C26, 0x3C1F, 0x3C20, 0x3C21, 0x3C22, 0x3C1B, 0x3C1C,
+ 0x3C1D, 0x3C1E, 0x3BF7, 0x3BF8, 0x3BF9, 0x3BFA, 0x3BF3, 0x3BF4, 0x3BF5, 0x3BF6,
+ 0x3BEF, 0x3BF0, 0x3BF1, 0x3BF2, 0x3BEB, 0x3BEC, 0x3BED, 0x3BEE, 0x3C07, 0x3C08,
+ 0x3C09, 0x3C0A, 0x3C03, 0x3C04, 0x3C05, 0x3C06, 0x3BFF, 0x3C00, 0x3C02, 0x3BFB,
+ 0x3BFC, 0x3BD5, 0x3BCB, 0x3BCC, 0x3BE5, 0x3BDF, 0x3BE0, 0x3BE1, 0x3CA2, 0x3C9B,
+ 0x3C9C, 0x3C9D, 0x3C9E, 0x3C77, 0x3C78, 0x3C79, 0x3C7A, 0x3C73, 0x3C74, 0x3C75,
+ 0x3C76, 0x3C6F, 0x3C70, 0x3C71, 0x3C72, 0x3C6B, 0x3C6C, 0x3C6D, 0x3C6E, 0x3C87,
+ 0x3C88, 0x3C89, 0x3C8A, 0x3C83, 0x3C84, 0x3C85, 0x3C86, 0x3C7F, 0x3C80, 0x3C81,
+ 0x3C82, 0x3C7B, 0x3C7C, 0x3C7D, 0x3C7E, 0x3C57, 0x3C58, 0x3C59, 0x3C5A, 0x3C53,
+ 0x3C54, 0x3C55, 0x3C56, 0x3C4F, 0x3C50, 0x3C51, 0x3C52, 0x3C4B, 0x2BB8, 0x2BB7,
+ 0x2BBA, 0x2BB9, 0x2BBC, 0x2BBB, 0x3C4C, 0x2BBD, 0x3C4D, 0x3C4E, 0x2C33, 0x2C50,
+ 0x2C35, 0x2C34, 0x2C37, 0x2C36, 0x3C67, 0x3C68, 0x3C69, 0x3C6A, 0x2C3D, 0x2C3C,
+ 0x2C57, 0x2C3E, 0x2C41, 0x2C40, 0x2C43, 0x2C42, 0x2C45, 0x2C44, 0x2C47, 0x2C46,
+ 0x2C49, 0x2C48, 0x2C4B, 0x2C4A, 0x2C4D, 0x2C4C, 0x2C51, 0x2C4E, 0x2C60, 0x2C55,
+ 0x2C53, 0x2C52, 0x2BA9, 0x2C56, 0x2C54, 0x2BAA, 0x2C59, 0x2C58, 0x2C5B, 0x2C5A,
+ 0x2C5D, 0x2C5C, 0x2C5F, 0x2C5E, 0x2C61, 0x2C62, 0x2C63, 0x3C63, 0x3C64, 0x3C65,
+ 0x3C66, 0x2C4F, 0x460D, 0x47B6, 0x46CE, 0x48D9, 0x465A, 0x48D8, 0x46B1, 0x46B0,
+ 0x46B2, 0x46B7, 0x46B8, 0x46B9, 0x46B8, 0x46BC, 0x46BD, 0x4922, 0x46BF, 0x46C0,
+ 0x46C2, 0x4694, 0x4894, 0x47B4, 0x47D0, 0x46F3, 0x464F, 0x479B, 0x48C4, 0x4925,
+ 0x46C1, 0x464A, 0x4649, 0x46D6, 0x46DB, 0x4926, 0x46DD, 0x46DA, 0x46D8, 0x48DA,
+ 0x46DF, 0x46E1, 0x46E3, 0x46E0, 0x48DB, 0x46E5, 0x46E7, 0x4927, 0x46EC, 0x46F6,
+ 0x46EE, 0x48DE, 0x46F1, 0x48DD, 0x48DC, 0x4600, 0x4601, 0x46F7, 0x46F2, 0x47EB,
+ 0x48F7, 0x46F8, 0x46F9, 0x46FA, 0x46FE, 0x46FC, 0x492C, 0x48DF, 0x4703, 0x467B,
+ 0x4954, 0x465F, 0x4660, 0x467A, 0x4655, 0x483B, 0x4668, 0x469B, 0x4674, 0x4727,
+ 0x485E, 0x4653, 0x4650, 0x478F, 0x45F4, 0x483C, 0x4646, 0x48E2, 0x4717, 0x4837,
+ 0x4884, 0x465E, 0x4651, 0x482D, 0x48BF, 0x4654, 0x460D, 0x48C0, 0x48C7, 0x46B1,
+ 0x4605, 0x4864, 0x461D, 0x0E3A, 0x4682, 0x486C, 0x48C9, 0x4680, 0x4659, 0x464B,
+ 0x45FE, 0x489F, 0x46BB, 0x4648, 0x45F6, 0x45F3, 0x45E7, 0x461A, 0x45EA, 0x4643,
+ 0x47C3, 0x4846, 0x461F, 0x488A, 0x45FA, 0x46BD, 0x4656, 0x4625, 0x4649, 0x48C6,
+ 0x3C5F, 0x3C60, 0x3C61, 0x3C62, 0x3C5B, 0x3C5C, 0x3C5D, 0x3C5E, 0x0210, 0x021C,
+ 0x0226, 0x0231, 0x01B3, 0x01D1, 0x01E6, 0x01FC, 0x0D05, 0x0D15, 0x0D16, 0x01E8,
+ 0x0D18, 0x0D3B, 0x0D3D, 0x0D63, 0x0D72, 0x0D71, 0x01E9, 0x0D73, 0x01EA, 0x0D64,
+ 0x01EB, 0x0DDD, 0x0F8A, 0x0FFE, 0x0FA7, 0x0FA6, 0x0FA9, 0x4917, 0x0FFD, 0x0FFC,
+ 0x0E77, 0x0E87, 0x0E88, 0x01D9, 0x0DDF, 0x01DA, 0x0E05, 0x0E04, 0x01E6, 0x01E7,
+ 0x01D5, 0x01D6, 0x4758, 0x0FA8, 0x01D7, 0x01D8, 0x01D2, 0x476B, 0x01D3, 0x01D4,
+ 0x0E56, 0x0030, 0x0035, 0x0032, 0x0C8E, 0x0DEF, 0x0DCE, 0x0C8F, 0x0CF0, 0x0CBC,
+ 0x0C95, 0x473E, 0x3EEB, 0x3EEC, 0x0D00, 0x0CEF, 0x3EEA, 0x0CC0, 0x0CBE, 0x0F74,
+ 0x4734, 0x0ED7, 0x0F18, 0x0F1B, 0x0ED3, 0x0FEF, 0x0009, 0x0E76, 0x472D, 0x0FEE,
+ 0x0E57, 0x0011, 0x0034, 0x002E, 0x0D65, 0x0033, 0x002D, 0x0D0B, 0x0031, 0x3F01,
+ 0x0EDA, 0x002F, 0x0DCD, 0x0036, 0x0F4D, 0x012B, 0x4708, 0x0EE8, 0x0DD9, 0x0D0C,
+ 0x0DDB, 0x0127, 0x0C8D, 0x0CBF, 0x0CC1, 0x0128, 0x0C96, 0x0D04, 0x0CBD, 0x0129,
+ 0x0EC7, 0x012A, 0x0123, 0x0124, 0x0DDA, 0x0F1F, 0x0F21, 0x0F49, 0x0125, 0x0126,
+ 0x021F, 0x022A, 0x0234, 0x0122, 0x1C36, 0x1C37, 0x1C38, 0x1C39, 0x1C32, 0x1C33,
+ 0x1C34, 0x1C35, 0x1C2E, 0x1C2F, 0x1C30, 0x1C31, 0x1C2C, 0x0204, 0x0205, 0x0210,
+ 0x01FF, 0x0200, 0x0201, 0x0202, 0x01EF, 0x01FC, 0x01FD, 0x01FE, 0x01ED, 0x01EE,
+ 0x01DF, 0x01F5, 0x0209, 0x02CE, 0x0234, 0x01A2, 0x1892, 0x1893, 0x0EEA, 0x01F5,
+ 0x188C, 0x1885, 0x1886, 0x0EEB, 0x0EEC, 0x1887, 0x1888, 0x36DF, 0x0EE6, 0x0E55,
+ 0x0663, 0x0E26, 0x0687, 0x0E3B, 0x36E0, 0x36E1, 0x36E2, 0x36DB, 0x0EE7, 0x36D9,
+ 0x1868, 0x2936, 0x2937, 0x2938, 0x2931, 0x2932, 0x2933, 0x2934, 0x292D, 0x292E,
+ 0x4751, 0x292F, 0x2930, 0x2945, 0x4795, 0x4797, 0x4796, 0x4798, 0x2941, 0x2942,
+ 0x2943, 0x2944, 0x293D, 0x293E, 0x293F, 0x2940, 0x2919, 0x291A, 0x291B, 0x291C,
+ 0x2915, 0x2916, 0x2917, 0x2918, 0x2911, 0x2912, 0x2913, 0x4847, 0x4851, 0x4852,
+ 0x4862, 0x4864, 0x488E, 0x4897, 0x489B, 0x46AF, 0x4939, 0x47F4, 0x2914, 0x290D,
+ 0x45DA, 0x290E, 0x290F, 0x2910, 0x45F5, 0x2929, 0x4619, 0x292A, 0x4643, 0x463E,
+ 0x4642, 0x292B, 0x4657, 0x465B, 0x4664, 0x4667, 0x292C, 0x2925, 0x2926, 0x2927,
+ 0x2928, 0x2921, 0x2922, 0x2923, 0x2924, 0x291D, 0x291E, 0x291F, 0x2920, 0x2962,
+ 0x2963, 0x295E, 0x295F, 0x2960, 0x2961, 0x295A, 0x295B, 0x295C, 0x295D, 0x2956,
+ 0x2957, 0x2958, 0x2959, 0x1C46, 0x1C47, 0x1C48, 0x1C49, 0x1C42, 0x1C43, 0x1C44,
+ 0x1C45, 0x1C3E, 0x1C3F, 0x1C40, 0x294F, 0x2950, 0x2951, 0x294A, 0x294B, 0x294C,
+ 0x294D, 0x2946, 0x2947, 0x2948, 0x0E20, 0x0E3E, 0x0E3C, 0x2949, 0x0E54, 0x17DD,
+ 0x022A, 0x0234, 0x01F5, 0x0209, 0x0215, 0x17DB, 0x17DE, 0x2CE7, 0x2CEA, 0x2CED,
+ 0x2CC1, 0x0E75, 0x2CC6, 0x2CCA, 0x0E73, 0x2D0E, 0x2D0D, 0x2C92, 0x2C98, 0x2C99,
+ 0x2C9E, 0x0E85, 0x022A, 0x0234, 0x01F5, 0x0209, 0x0215, 0x021F, 0x3443, 0x3440,
+ 0x3441, 0x3442, 0x343E, 0x3437, 0x3438, 0x3439, 0x343A, 0x3453, 0x3454, 0x3455,
+ 0x3456, 0x344F, 0x3450, 0x3451, 0x3452, 0x344B, 0x344C, 0x344D, 0x344E, 0x3447,
+ 0x3448, 0x2D47, 0x2D4B, 0x2D4F, 0x2D50, 0x2D36, 0x2D3B, 0x2D3F, 0x2D43, 0x2D2A,
+ 0x2D2E, 0x2D30, 0x2D34, 0x2D1E, 0x2D21, 0x2D24, 0x2D28, 0x2CA3, 0x2D55, 0x2D58,
+ 0x2D5B, 0x2C76, 0x2C88, 0x2C9A, 0x2D51, 0x2D54, 0x2D57, 0x2D5A, 0x2D5E, 0x2CE5,
+ 0x2CE8, 0x2CEB, 0x2CF1, 0x2CDA, 0x2CDB, 0x2CDE, 0x2CE1, 0x2CCF, 0x2CD0, 0x2CD4,
+ 0x2CD5, 0x2CC3, 0x2CC7, 0x2CC8, 0x2CCD, 0x2D12, 0x47C9, 0x2C95, 0x2C9B, 0x2C9C,
+ 0x2CA0, 0x2D45, 0x47C3, 0x2D39, 0x2D3D, 0x2D41, 0x2D27, 0x2D2C, 0x2D2D, 0x2D32,
+ 0x2775, 0x2748, 0x2805, 0x2806, 0x0E60, 0x2807, 0x2808, 0x2801, 0x0E86, 0x0E9E,
+ 0x0E9F, 0x0EA0, 0x2802, 0x2803, 0x2804, 0x27FD, 0x27FE, 0x27FF, 0x2800, 0x27D9,
+ 0x27DA, 0x27DB, 0x27DC, 0x27E6, 0x27E7, 0x27E8, 0x27E1, 0x27E2, 0x27E3, 0x27E4,
+ 0x27DD, 0x27DE, 0x27DF, 0x27E0, 0x27B9, 0x27BA, 0x27BB, 0x27BC, 0x27B5, 0x27B6,
+ 0x27B7, 0x27B8, 0x27B1, 0x27B2, 0x27B3, 0x480C, 0x4844, 0x27B4, 0x27AD, 0x27AE,
+ 0x27AF, 0x27B0, 0x27C9, 0x1000, 0x1001, 0x0D87, 0x27CA, 0x4840, 0x27CB, 0x0007,
+ 0x27CC, 0x2795, 0x2796, 0x2797, 0x2798, 0x2794, 0x27A8, 0x2875, 0x2876, 0x2877,
+ 0x2878, 0x2871, 0x2872, 0x2873, 0x2874, 0x286F, 0x2870, 0x2889, 0x288A, 0x2885,
+ 0x2886, 0x2887, 0x2888, 0x2881, 0x4827, 0x2882, 0x2883, 0x2884, 0x287D, 0x287E,
+ 0x4838, 0x287F, 0x2880, 0x2859, 0x285A, 0x285B, 0x285C, 0x2855, 0x2856, 0x2857,
+ 0x2858, 0x2851, 0x2852, 0x2853, 0x2854, 0x284D, 0x284E, 0x47E4, 0x284F, 0x2850,
+ 0x2869, 0x286A, 0x286B, 0x286C, 0x2865, 0x2866, 0x2867, 0x2868, 0x2861, 0x2862,
+ 0x2863, 0x2864, 0x285D, 0x285E, 0x285F, 0x2860, 0x2839, 0x283A, 0x283B, 0x283C,
+ 0x2835, 0x2836, 0x2837, 0x2838, 0x2831, 0x2832, 0x46C9, 0x2833, 0x2834, 0x282D,
+ 0x282E, 0x282F, 0x2830, 0x2849, 0x284A, 0x284B, 0x284C, 0x2845, 0x2846, 0x2847,
+ 0x2848, 0x2841, 0x2842, 0x2843, 0x2844, 0x283D, 0x283E, 0x283F, 0x2840, 0x2819,
+ 0x281A, 0x281B, 0x281C, 0x2815, 0x2816, 0x2817, 0x2818, 0x2811, 0x2812, 0x2813,
+ 0x2814, 0x280D, 0x280E, 0x280F, 0x2810, 0x2829, 0x282A, 0x282B, 0x282C, 0x2825,
+ 0x2826, 0x2827, 0x2828, 0x2821, 0x2822, 0x2823, 0x2824, 0x281D, 0x281E, 0x281F,
+ 0x2820, 0x28F9, 0x28FA, 0x28FB, 0x28FC, 0x28F5, 0x28F6, 0x28F7, 0x28F8, 0x28F1,
+ 0x28F2, 0x28F3, 0x28F4, 0x28ED, 0x28EE, 0x28EF, 0x28F0, 0x2909, 0x290A, 0x290B,
+ 0x290C, 0x2905, 0x2906, 0x2907, 0x2908, 0x2901, 0x2902, 0x2903, 0x2904, 0x28FD,
+ 0x484A, 0x4852, 0x4887, 0x28FE, 0x2B5A, 0x2B5D, 0x28FF, 0x2900, 0x28D9, 0x28DA,
+ 0x4870, 0x2B66, 0x28DB, 0x28DC, 0x28D5, 0x4877, 0x4894, 0x28D6, 0x4897, 0x28D7,
+ 0x28D8, 0x2BD4, 0x2BD7, 0x2BDA, 0x28D1, 0x28D2, 0x28D3, 0x28D4, 0x47A9, 0x4898,
+ 0x48BB, 0x28CD, 0x28CE, 0x28CF, 0x28D0, 0x4789, 0x28E9, 0x28EA, 0x28EB, 0x477D,
+ 0x2A78, 0x4895, 0x28EC, 0x4788, 0x489B, 0x48A7, 0x48BE, 0x4924, 0x28E5, 0x2BD1,
+ 0x2A72, 0x2A6F, 0x47B2, 0x2B2D, 0x2BC9, 0x47AD, 0x2A7E, 0x2A7B, 0x4784, 0x2BCE,
+ 0x2A75, 0x47BE, 0x2BDD, 0x2BC6, 0x28E6, 0x28E7, 0x28E8, 0x28E1, 0x28E2, 0x28E3,
+ 0x28E4, 0x28DD, 0x28DE, 0x28DF, 0x2B57, 0x28E0, 0x28B9, 0x28BA, 0x28BB, 0x28BC,
+ 0x28B5, 0x28B6, 0x28B7, 0x28B8, 0x28B1, 0x485D, 0x28B2, 0x28B3, 0x28B4, 0x28AD,
+ 0x28AE, 0x28AF, 0x28B0, 0x28C9, 0x28CA, 0x28CB, 0x28CC, 0x28C5, 0x28C6, 0x28C7,
+ 0x28C8, 0x28C1, 0x28C2, 0x28C3, 0x28C4, 0x28BD, 0x28BE, 0x28BF, 0x28C0, 0x2899,
+ 0x289A, 0x289B, 0x4923, 0x289C, 0x2B54, 0x2B60, 0x2895, 0x4947, 0x4950, 0x2B63,
+ 0x2896, 0x48BD, 0x2897, 0x2898, 0x2891, 0x48EB, 0x2B69, 0x2892, 0x4657, 0x2893,
+ 0x46EF, 0x2CDC, 0x48C3, 0x460A, 0x4761, 0x4781, 0x4794, 0x2CE9, 0x479C, 0x2CFC,
+ 0x2D0C, 0x47A0, 0x2D18, 0x2D14, 0x2894, 0x48C1, 0x288D, 0x48C2, 0x288E, 0x288F,
+ 0x2890, 0x28A9, 0x28AA, 0x28AB, 0x28AC, 0x28A5, 0x28A6, 0x28A7, 0x28A8, 0x28A1,
+ 0x28A2, 0x28A3, 0x28A4, 0x2BC2, 0x289D, 0x289E, 0x289F, 0x28A0, 0x0139, 0x2AA2,
+ 0x013A, 0x013B, 0x2AA5, 0x2A9F, 0x013C, 0x4776, 0x2AB1, 0x2A8A, 0x2A8D, 0x022A,
+ 0x4846, 0x4845, 0x4843, 0x2A90, 0x4847, 0x2A96, 0x2A99, 0x2A9C, 0x483C, 0x483F,
+ 0x2ABE, 0x2A93, 0x0234, 0x0137, 0x0138, 0x01F5, 0x0209, 0x0215, 0x021F, 0x0198,
+ 0x01A2, 0x01C9, 0x01DF, 0x33BD, 0x013D, 0x013E, 0x013F, 0x33D6, 0x33D8, 0x33DA,
+ 0x33DC, 0x33CE, 0x33D0, 0x33D2, 0x33D4, 0x33C6, 0x33C8, 0x33CA, 0x33CC, 0x33BE,
+ 0x33C0, 0x33C2, 0x33C4, 0x33F6, 0x33F8, 0x33FA, 0x33FC, 0x33EE, 0x33F0, 0x33F2,
+ 0x33F4, 0x33E6, 0x33E8, 0x33EA, 0x33EC, 0x33DE, 0x33E0, 0x33E2, 0x33E4, 0x33D7,
+ 0x33D9, 0x33DB, 0x33DD, 0x33CF, 0x33D1, 0x33D3, 0x33D5, 0x33C7, 0x33C9, 0x33CB,
+ 0x33CD, 0x33BF, 0x33C1, 0x33C3, 0x33C5, 0x33F7, 0x33F9, 0x33FB, 0x33FD, 0x33EF,
+ 0x33F1, 0x33F3, 0x33F5, 0x33E7, 0x33E9, 0x33EB, 0x33ED, 0x33DF, 0x33E1, 0x33E3,
+ 0x33E5, 0x06E7, 0x029D, 0x048A, 0x029B, 0x03C4, 0x0433, 0x0432, 0x06E8, 0x058B,
+ 0x0294, 0x05ED, 0x03C5, 0x0466, 0x0465, 0x0468, 0x0540, 0x05C2, 0x06E6, 0x034E,
+ 0x0588, 0x0529, 0x0351, 0x0671, 0x03C7, 0x03C6, 0x054D, 0x02A1, 0x0670, 0x068B,
+ 0x068A, 0x0AC5, 0x0AC7, 0x0AC9, 0x0ACB, 0x0ABD, 0x0ABF, 0x0AC1, 0x0AC3, 0x0AB5,
+ 0x0AB7, 0x0AB9, 0x0ABB, 0x0AAD, 0x0AAF, 0x0AB1, 0x0AB3, 0x0AE5, 0x0AE7, 0x0AE9,
+ 0x0FA0, 0x0FEA, 0x0FE9, 0x0ADD, 0x0F6F, 0x0FEC, 0x0F71, 0x0C7B, 0x0ADF, 0x0F9E,
+ 0x0FE7, 0x0AE1, 0x0AE3, 0x0AD5, 0x0AD7, 0x0AD9, 0x0ADB, 0x0ACD, 0x0ACF, 0x0AD1,
+ 0x0AD3, 0x0AE6, 0x0AE8, 0x0AEA, 0x0ADE, 0x0AE0, 0x0AE2, 0x0AE4, 0x0AD6, 0x0AD8,
+ 0x0ADA, 0x0ADC, 0x0ACE, 0x0AD0, 0x0AD2, 0x0AD4, 0x0AA5, 0x0ED4, 0x0AA7, 0x0AA9,
+ 0x0AAB, 0x0A9D, 0x0A9F, 0x0AA1, 0x0AA3, 0x0A95, 0x0A97, 0x0A99, 0x0A9B, 0x0A8D,
+ 0x0A8F, 0x0A91, 0x0A93, 0x0AA6, 0x0AA8, 0x0AAA, 0x0AAC, 0x0A9E, 0x0AA0, 0x0AA2,
+ 0x0AA4, 0x0A96, 0x0A98, 0x0A9A, 0x0EDD, 0x0EDE, 0x0EDF, 0x0F6A, 0x0EE3, 0x0F70,
+ 0x0F50, 0x0F34, 0x0F56, 0x0F5A, 0x0F7C, 0x0F7D, 0x0F7E, 0x0A9C, 0x0FE8, 0x0F83,
+ 0x0E96, 0x0FE0, 0x0FF3, 0x0FF4, 0x0EBC, 0x0FF8, 0x0A8E, 0x0FFA, 0x0F53, 0x0E94,
+ 0x0F6D, 0x0ED6, 0x0FF5, 0x0C73, 0x0ED5, 0x0FF9, 0x0CE9, 0x0CE2, 0x0CE4, 0x0EE2,
+ 0x0E5B, 0x0F9F, 0x0EBD, 0x0D2E, 0x0A90, 0x0E68, 0x0A92, 0x0DDE, 0x0F1D, 0x000D,
+ 0x0E66, 0x0A94, 0x0DC4, 0x0E12, 0x0E14, 0x0E15, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E30,
+ 0x0C74, 0x0C75, 0x0C76, 0x0C77, 0x0CAA, 0x0CAB, 0x0CAC, 0x0CAD, 0x0AC6, 0x0AC8,
+ 0x0ACA, 0x0ACC, 0x0ABE, 0x0AC0, 0x0AC2, 0x0AC4, 0x0E7B, 0x0AB6, 0x0AB8, 0x0ABA,
+ 0x0ABC, 0x0E7C, 0x0E92, 0x0E93, 0x0AAE, 0x0AB0, 0x0AB2, 0x0CE7, 0x0AB4, 0x08E3,
+ 0x0904, 0x0903, 0x08E4, 0x0CB0, 0x0CB1, 0x08B9, 0x0C7C, 0x0E48, 0x0918, 0x0917,
+ 0x091A, 0x0919, 0x0083, 0x08F0, 0x08EF, 0x08F8, 0x08F7, 0x0DC3, 0x0D2F, 0x0D59,
+ 0x0D5A, 0x0D6A, 0x0D6B, 0x0DBF, 0x0DC1, 0x08FA, 0x08F9, 0x08F2, 0x08F1, 0x08F6,
+ 0x08F5, 0x08E8, 0x08E7, 0x08EA, 0x08E9, 0x08E0, 0x08DF, 0x08E6, 0x08E5, 0x090E,
+ 0x090D, 0x0916, 0x0915, 0x090A, 0x0909, 0x090C, 0x090B, 0x0900, 0x08FF, 0x0906,
+ 0x0905, 0x08FC, 0x08FB, 0x08FE, 0x08FD, 0x08D8, 0x08D7, 0x08DA, 0x08D9, 0x08D4,
+ 0x08D3, 0x08D6, 0x08D5, 0x08D0, 0x08CF, 0x08D2, 0x08D1, 0x08CC, 0x08CB, 0x08CE,
+ 0x08CD, 0x08C6, 0x08C5, 0x08DE, 0x08DD, 0x08BC, 0x08BB, 0x08C4, 0x08C3, 0x0914,
+ 0x08AD, 0x08AC, 0x08DC, 0x08DB, 0x0912, 0x0911, 0x08B1, 0x08B0, 0x08B3, 0x08B2,
+ 0x08AB, 0x08AE, 0x08A7, 0x1765, 0x10E3, 0x10E4, 0x10B9, 0x10D2, 0x10DF, 0x10E0,
+ 0x10E1, 0x10E2, 0x174E, 0x174F, 0x1750, 0x1751, 0x174A, 0x174B, 0x174C, 0x174D,
+ 0x1746, 0x1747, 0x1748, 0x1749, 0x1742, 0x1743, 0x1744, 0x10DC, 0x0E99, 0x0DE9,
+ 0x10DD, 0x10DE, 0x0CE3, 0x0CF4, 0x0CE5, 0x10D7, 0x0CE8, 0x0CEA, 0x0CEB, 0x0CEC,
+ 0x0D35, 0x0D30, 0x0D5F, 0x0D5E, 0x0DC2, 0x0DC0, 0x0DD0, 0x0DD4, 0x0E6E, 0x0E95,
+ 0x0EC1, 0x0DD5, 0x0E50, 0x0E6C, 0x0E6D, 0x0EC2, 0x0DF5, 0x0E7F, 0x0E81, 0x0DC5,
+ 0x10D8, 0x0DC6, 0x0DE8, 0x10D9, 0x0E13, 0x0E4F, 0x0E4A, 0x0E4B, 0x0E19, 0x0E2F,
+ 0x0E1C, 0x0E69, 0x0DE5, 0x0E80, 0x0DFA, 0x0DC7, 0x0DFB, 0x0DF3, 0x0E33, 0x0E35,
+ 0x10DA, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10CE, 0x10CF, 0x10D0, 0x10D1, 0x0B8B,
+ 0x0B78, 0x0B81, 0x0B85, 0x0B7E, 0x0B27, 0x0B3C, 0x0B51, 0x10BA, 0x10BB, 0x10BC,
+ 0x10BD, 0x10B5, 0x10B8, 0x10B1, 0x0B3F, 0x0B42, 0x0B45, 0x0B2D, 0x0B30, 0x0B33,
+ 0x0B36, 0x0B1E, 0x0B21, 0x0B24, 0x0B2A, 0x0B12, 0x0B15, 0x0B18, 0x0B1B, 0x0B6F,
+ 0x0B72, 0x0B75, 0x0B7B, 0x0B63, 0x0B57, 0x1799, 0x1782, 0x1783, 0x1784, 0x1785,
+ 0x177B, 0x177C, 0x1780, 0x1781, 0x1777, 0x1778, 0x1779, 0x177A, 0x1773, 0x1774,
+ 0x1775, 0x1794, 0x178C, 0x12A8, 0x12A9, 0x12A3, 0x12A4, 0x12A5, 0x12A6, 0x12A0,
+ 0x12A1, 0x12A2, 0x129C, 0x129D, 0x129E, 0x129F, 0x127D, 0x127E, 0x127F, 0x1279,
+ 0x127A, 0x127B, 0x127C, 0x1276, 0x1277, 0x1278, 0x1272, 0x1273, 0x1274, 0x1275,
+ 0x296B, 0x128B, 0x128C, 0x128D, 0x1287, 0x1288, 0x1289, 0x128A, 0x1284, 0x1285,
+ 0x1286, 0x1280, 0x297B, 0x1281, 0x1282, 0x1283, 0x11EB, 0x11FA, 0x1203, 0x1225,
+ 0x1189, 0x1192, 0x119B, 0x11CC, 0x299F, 0x1133, 0x1159, 0x116A, 0x1173, 0x2994,
+ 0x2995, 0x10F5, 0x110A, 0x2998, 0x111B, 0x1124, 0x299B, 0x121A, 0x2996, 0x121B,
+ 0x121C, 0x122E, 0x0D75, 0x0E27, 0x0E28, 0x0E3F, 0x0E40, 0x0DFF, 0x0E00, 0x0E21,
+ 0x0E03, 0x0E02, 0x0DDC, 0x0D6E, 0x0E3D, 0x0E51, 0x0E52, 0x0E70, 0x123E, 0x0E83,
+ 0x0D60, 0x0DD6, 0x126E, 0x0DD7, 0x1219, 0x022A, 0x0E82, 0x0E71, 0x0234, 0x0111,
+ 0x0112, 0x01F5, 0x0209, 0x0215, 0x021F, 0x0198, 0x01A2, 0x01C9, 0x01DF, 0x17AA,
+ 0x17AB, 0x17AC, 0x17AD, 0x17A6, 0x17A7, 0x17A8, 0x0DE7, 0x17A9, 0x17A2, 0x17A3,
+ 0x0DCB, 0x0DCA, 0x17A4, 0x0E49, 0x17A5, 0x179E, 0x179F, 0x17A0, 0x17A1, 0x0CA2,
+ 0x17B6, 0x17B7, 0x17B2, 0x17B3, 0x17B4, 0x17B5, 0x17AE, 0x17AF, 0x17B0, 0x17B1,
+ 0x16DB, 0x16A3, 0x16A4, 0x16DA, 0x022A, 0x0234, 0x01F5, 0x0209, 0x0215, 0x021F,
+ 0x0198, 0x01A2, 0x01C9, 0x01DF, 0x16D1, 0x16D2, 0x16D3, 0x16D4, 0x16CD, 0x16CE,
+ 0x16CF, 0x16D0, 0x16C9, 0x16CA, 0x16CB, 0x16CC, 0x16C5, 0x16C6, 0x16C7, 0x16C8,
+ 0x16D9, 0x16D5, 0x16D6, 0x16D7, 0x16D8, 0x16B1, 0x16B2, 0x16B3, 0x16B4, 0x16AD,
+ 0x16AE, 0x16AF, 0x16B0, 0x16A9, 0x16AA, 0x16AB, 0x16AC, 0x16A5, 0x16A6, 0x16A7,
+ 0x16A8, 0x16C1, 0x16C2, 0x16C3, 0x16C4, 0x16BD, 0x16BE, 0x2DC5, 0x2DC6, 0x2DBF,
+ 0x2DC0, 0x2DC1, 0x2DC2, 0x2DDB, 0x2DDC, 0x2DDD, 0x2DDE, 0x2DD7, 0x2DD8, 0x2DD9,
+ 0x2DDA, 0x2DD3, 0x2DD4, 0x2DD5, 0x2DD6, 0x2DCF, 0x2DD0, 0x2DD1, 0x2DD2, 0x2DAB,
+ 0x2DAC, 0x2DAD, 0x2DAE, 0x2DA7, 0x2DA8, 0x2DA9, 0x2DAA, 0x2DA3, 0x2DA4, 0x2DA5,
+ 0x2DA6, 0x2D9F, 0x0CFA, 0x0D37, 0x0F2B, 0x2DA0, 0x0DD1, 0x0E1A, 0x0DF6, 0x0E34,
+ 0x0FF2, 0x0F32, 0x2DA1, 0x0FF1, 0x2DA2, 0x2DBB, 0x2DBC, 0x2DB7, 0x2DB9, 0x2DBA,
+ 0x2DB3, 0x2DB4, 0x2DB5, 0x2DB6, 0x2DAF, 0x2DB0, 0x2D8B, 0x0E4C, 0x2D8C, 0x2D95,
+ 0x0E5A, 0x0E4E, 0x2D96, 0x0ED8, 0x0E31, 0x0E53, 0x2D8F, 0x0E5F, 0x2D90, 0x2D91,
+ 0x2D92, 0x0E5E, 0x2D6A, 0x2D6B, 0x2D6C, 0x0E23, 0x0EC8, 0x0D3C, 0x0E74, 0x2D6E,
+ 0x2D66, 0x0E22, 0x0DA2, 0x2D67, 0x2D68, 0x2D69, 0x2D62, 0x2D63, 0x0F5F, 0x2E45,
+ 0x0FC0, 0x2E46, 0x0E25, 0x2E3F, 0x0CA4, 0x2E40, 0x2E41, 0x2E42, 0x2E5B, 0x2E5C,
+ 0x2E5D, 0x2E5E, 0x2E57, 0x2E58, 0x2E59, 0x2E5A, 0x0ED9, 0x2E53, 0x2E54, 0x2E55,
+ 0x2E56, 0x2E4F, 0x2E50, 0x2E51, 0x2E52, 0x0E47, 0x2E2B, 0x2E2C, 0x2E2D, 0x2E2E,
+ 0x2E27, 0x2E28, 0x2E29, 0x2E2A, 0x2E23, 0x2E24, 0x2E25, 0x2E26, 0x0CF5, 0x2E1F,
+ 0x2E20, 0x2E21, 0x2E22, 0x2E3B, 0x2E3C, 0x2E3D, 0x2E3E, 0x2E37, 0x2E38, 0x0CF6,
+ 0x2E39, 0x2E3A, 0x2E33, 0x2E34, 0x0CF2, 0x2E35, 0x2E36, 0x2E2F, 0x2E30, 0x2E31,
+ 0x2E32, 0x2E0B, 0x2E0C, 0x2E0D, 0x2E0E, 0x2E07, 0x2E08, 0x2E09, 0x2E0A, 0x2E03,
+ 0x2E04, 0x2E05, 0x2E06, 0x2DFF, 0x2E00, 0x2E01, 0x2E02, 0x2E1B, 0x2E1C, 0x2E1D,
+ 0x2E1E, 0x2E17, 0x2E18, 0x2E19, 0x2E1A, 0x2E13, 0x2E14, 0x2E15, 0x2E16, 0x2E0F,
+ 0x2E10, 0x2E11, 0x2E12, 0x2DEB, 0x2DEC, 0x2DED, 0x2DEE, 0x2DE7, 0x2DE8, 0x2DE9,
+ 0x2DEA, 0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6, 0x2DDF, 0x2DE0, 0x2DE1, 0x2DE2, 0x2DFB,
+ 0x2DFC, 0x2DFD, 0x2DFE, 0x2DF7, 0x2DF8, 0x2DF9, 0x2DFA, 0x2DF3, 0x2DF4, 0x2DF5,
+ 0x2DF6, 0x2DEF, 0x2DF0, 0x2DF1, 0x2DF2, 0x1712, 0x1713, 0x1715, 0x1717, 0x173F,
+ 0x1740, 0x1741, 0x173B, 0x173C, 0x173D, 0x173E, 0x1737, 0x1738, 0x1739, 0x173A,
+ 0x1733, 0x1734, 0x1735, 0x1736, 0x2E6B, 0x2E6C, 0x2E6D, 0x2E6E, 0x2E67, 0x2E68,
+ 0x2E69, 0x0D36, 0x2E6A, 0x2E63, 0x2E64, 0x1718, 0x172D, 0x172E, 0x1727, 0x1728,
+ 0x0D33, 0x1729, 0x0F2E, 0x0483, 0x04A7, 0x172A, 0x0F2C, 0x0F29, 0x0F31, 0x0F1E,
+ 0x0F58, 0x0F4E, 0x0F20, 0x050C, 0x0F2F, 0x0F51, 0x0F4C, 0x0F52, 0x0FA1, 0x1723,
+ 0x0F4B, 0x1724, 0x0F7A, 0x0FA2, 0x1725, 0x1726, 0x1616, 0x1617, 0x1618, 0x0F2A,
+ 0x0F4A, 0x0FF6, 0x0F7F, 0x0457, 0x1619, 0x1612, 0x042B, 0x1613, 0x1614, 0x1615,
+ 0x160E, 0x160F, 0x0286, 0x1610, 0x0F76, 0x02AD, 0x0345, 0x02F8, 0x0392, 0x0370,
+ 0x0EE1, 0x0EE0, 0x0EC3, 0x0FF7, 0x0E6F, 0x03BC, 0x0411, 0x0F1C, 0x0F6B, 0x0F59,
+ 0x0F1A, 0x03F4, 0x1611, 0x0EBE, 0x0D34, 0x0D5D, 0x0F72, 0x0FA3, 0x15FB, 0x15FC,
+ 0x0E6A, 0x0FBF, 0x0FBE, 0x15FD, 0x0E6B, 0x0E72, 0x05A5, 0x0E65, 0x0E5C, 0x0E84,
+ 0x0E7E, 0x0E7A, 0x0537, 0x054F, 0x0567, 0x15FE, 0x15F7, 0x15F8, 0x15F9, 0x0659,
+ 0x15FA, 0x15F3, 0x15F4, 0x15F5, 0x15F6, 0x15EF, 0x15F0, 0x15F1, 0x0F26, 0x0F55,
+ 0x0CFB, 0x0F48, 0x0F22, 0x0F5C, 0x0F28, 0x0F84, 0x0F38, 0x0FA5, 0x0FA4, 0x0FE1,
+ 0x0F54, 0x0F9D, 0x0F75, 0x0F69, 0x05D6, 0x0618, 0x0FF0, 0x0FE6, 0x0FDF, 0x0FFB,
+ 0x0F37, 0x067E, 0x0690, 0x0F27, 0x06D0, 0x06B1, 0x0FED, 0x0F36, 0x0F25, 0x0F39,
+ 0x15F2, 0x160A, 0x160B, 0x160C, 0x160D, 0x1606, 0x1607, 0x1608, 0x1609, 0x1602,
+ 0x1603, 0x1604, 0x1605, 0x15FF, 0x1600, 0x1601, 0x022A, 0x0234, 0x01F5, 0x0209,
+ 0x0215, 0x021F, 0x0198, 0x01A2, 0x01C9, 0x01DF, 0x1636, 0x1637, 0x1638, 0x1639,
+ 0x1632, 0x1633, 0x1634, 0x1635, 0x162E, 0x162F, 0x1630, 0x1631, 0x162A, 0x162B,
+ 0x162C, 0x162D, 0x1646, 0x1647, 0x1648, 0x1642, 0x1643, 0x1644, 0x1645, 0x163E,
+ 0x163F, 0x1640, 0x1641, 0x163A, 0x163B, 0x163C, 0x163D, 0x166D, 0x166B, 0x164D,
+ 0x164E, 0x166C, 0x1667, 0x1668, 0x1669, 0x166A, 0x1626, 0x1627, 0x1628, 0x1629,
+ 0x1622, 0x1623, 0x1624, 0x1625, 0x161E, 0x161F, 0x1620, 0x1621, 0x161A, 0x161B,
+ 0x161C, 0x161D, 0x1655, 0x1656, 0x1657, 0x1652, 0x1653, 0x1654, 0x164F, 0x1650,
+ 0x1651, 0x1649, 0x164A, 0x164B, 0x164C, 0x1664, 0x1665, 0x1666, 0x1660, 0x1661,
+ 0x1662, 0x1663, 0x165C, 0x165D, 0x165E, 0x165F, 0x1658, 0x1659, 0x165A, 0x165B,
+ 0x1676, 0x1678, 0x16A2, 0x16A0, 0x16A1, 0x166E, 0x1693, 0x1694, 0x1695, 0x1696,
+ 0x1690, 0x1691, 0x1692, 0x168C, 0x168D, 0x168E, 0x168F, 0x1688, 0x1689, 0x168A,
+ 0x168B, 0x169F, 0x169D, 0x169E, 0x169A, 0x169B, 0x169C, 0x1697, 0x1698, 0x1699,
+ 0x1677, 0x1679, 0x1672, 0x1673, 0x1674, 0x1675, 0x166F, 0x1670, 0x1671, 0x1684,
+ 0x1685, 0x1686, 0x1687, 0x1680, 0x1681, 0x1682, 0x1683, 0x167C, 0x167D, 0x167E,
+ 0x167F, 0x167A, 0x167B, 0x0215, 0x021F, 0x022A, 0x0234, 0x01C9, 0x01DF, 0x01F5,
+ 0x0209, 0x011C, 0x011D, 0x0198, 0x01A2, 0x0118, 0x0119, 0x011A, 0x011B, 0x0114,
+ 0x0115, 0x0116, 0x0117, 0x021F, 0x022A, 0x0234, 0x0113, 0x01DF, 0x01F5, 0x0209,
+ 0x0215, 0x01A2, 0x01C9, 0x1835, 0x1836, 0x1837, 0x1838, 0x1831, 0x1832, 0x1833,
+ 0x1834, 0x182D, 0x182E, 0x182F, 0x1830, 0x1829, 0x182A, 0x182B, 0x182C, 0x183F,
+ 0x1840, 0x1841, 0x1842, 0x1839, 0x183A, 0x183B, 0x1814, 0x183E, 0x1810, 0x183D,
+ 0x1825, 0x1826, 0x1827, 0x1828, 0x1821, 0x1822, 0x1823, 0x1824, 0x181D, 0x181E,
+ 0x181F, 0x1820, 0x1819, 0x181A, 0x181B, 0x181C, 0x36D2, 0x36CE, 0x36CF, 0x36D0,
+ 0x36D1, 0x36CA, 0x36CB, 0x36CC, 0x36CD, 0x022A, 0x0234, 0x01F5, 0x0209, 0x0215,
+ 0x021F, 0x0198, 0x01A2, 0x01C9, 0x01DF, 0x36C6, 0x36C7, 0x36C8, 0x36C9, 0x36C2,
+ 0x36C3, 0x36C4, 0x36C5, 0x36BE, 0x36BF, 0x36C0, 0x36C1, 0x36BA, 0x36BB, 0x36BC,
+ 0x36BD, 0x1591, 0x1592, 0x1593, 0x1594, 0x158E, 0x158F, 0x1590, 0x158B, 0x1589,
+ 0x158A, 0x158C, 0x158D, 0x1585, 0x1586, 0x1587, 0x1588, 0x1571, 0x1572, 0x1573,
+ 0x1574, 0x156D, 0x156E, 0x156F, 0x1570, 0x1569, 0x156A, 0x156B, 0x156C, 0x1568,
+ 0x1581, 0x1582, 0x1583, 0x1584, 0x157D, 0x157E, 0x157F, 0x1580, 0x1579, 0x157A,
+ 0x157B, 0x157C, 0x1575, 0x1576, 0x1577, 0x1578, 0x15B1, 0x15B2, 0x15B3, 0x15B4,
+ 0x15AD, 0x15AE, 0x15AF, 0x15B0, 0x15A9, 0x15AA, 0x15AB, 0x15AC, 0x15A5, 0x15A6,
+ 0x15A7, 0x15A8, 0x15B5, 0x15B6, 0x15B7, 0x15B8, 0x01E5, 0x1598, 0x1E0D, 0x1E0E,
+ 0x1E0F, 0x0225, 0x021B, 0x0225, 0x01D0, 0x01E5, 0x01FB, 0x002C, 0x01BB, 0x01BC,
+ 0x01D1, 0x1DEC, 0x1E05, 0x1E06, 0x1E07, 0x1E08, 0x1E01, 0x1E02, 0x1E03, 0x1E04,
+ 0x1DFD, 0x1DFE, 0x1DFF, 0x1E00, 0x1DF9, 0x1DFA, 0x1DFB, 0x1DFC, 0x012E, 0x012F,
+ 0x0130, 0x0131, 0x022A, 0x0234, 0x012C, 0x012D, 0x01F5, 0x0209, 0x0215, 0x021F,
+ 0x01A2, 0x01C9, 0x01DF, 0x0136, 0x0132, 0x0133, 0x0134, 0x2A12, 0x2A18, 0x0135,
+ 0x15B9, 0x15EB, 0x2A1D, 0x2A22, 0x2A1C, 0x15EC, 0x2A0D, 0x2A1E, 0x2A0E, 0x15ED,
+ 0x15EE, 0x022A, 0x29EB, 0x29E4, 0x29E5, 0x0234, 0x15BA, 0x01F5, 0x0209, 0x0215,
+ 0x29E8, 0x021F, 0x0198, 0x29EA, 0x29E9, 0x01A2, 0x29F4, 0x01C9, 0x29ED, 0x29EC,
+ 0x29F1, 0x01DF, 0x15E4, 0x15E5, 0x29FC, 0x15E6, 0x29EE, 0x15E7, 0x15E0, 0x15E1,
+ 0x15E2, 0x15E3, 0x15DC, 0x15DD, 0x2A27, 0x15DE, 0x15DF, 0x15D8, 0x15D9, 0x15DA,
+ 0x29F3, 0x01B6, 0x01B7, 0x01B8, 0x019E, 0x01B4, 0x15E8, 0x15E9, 0x15EA, 0x0230,
+ 0x01BA, 0x01BB, 0x01BC, 0x15BB, 0x15D4, 0x15D5, 0x15D6, 0x15D7, 0x15D0, 0x29F0,
+ 0x01F5, 0x29F2, 0x15D1, 0x15D2, 0x15D3, 0x15CC, 0x15CD, 0x15CE, 0x15CF, 0x15C8,
+ 0x15C9, 0x15CA, 0x15CB, 0x0070, 0x0071, 0x0072, 0x0073, 0x0234, 0x006D, 0x006E,
+ 0x006F, 0x0209, 0x0215, 0x021F, 0x022A, 0x01A2, 0x01C9, 0x01DF, 0x01F5, 0x0080,
+ 0x0081, 0x0082, 0x007C, 0x007D, 0x007E, 0x007F, 0x0078, 0x0079, 0x007A, 0x007B,
+ 0x0074, 0x0075, 0x0076, 0x0077, 0x020D, 0x0219, 0x0223, 0x022E, 0x01A6, 0x01CD,
+ 0x01E3, 0x01F9, 0x0021, 0x0022, 0x0023, 0x0025, 0x001D, 0x001E, 0x001F, 0x0020,
+ 0x01AE, 0x01AF, 0x01B0, 0x01CE, 0x01AA, 0x01AB, 0x01AC, 0x01AD, 0x0238, 0x01A7,
+ 0x01A8, 0x01A9, 0x259E, 0x259A, 0x259B, 0x259C, 0x259D, 0x2596, 0x2597, 0x2598,
+ 0x2599, 0x2582, 0x2583, 0x2584, 0x2585, 0x257E, 0x257F, 0x2580, 0x2581, 0x257A,
+ 0x257B, 0x257C, 0x257D, 0x2576, 0x2577, 0x2578, 0x2579, 0x2592, 0x2593, 0x2594,
+ 0x2595, 0x258E, 0x258F, 0x2590, 0x2591, 0x258A, 0x258B, 0x258C, 0x258D, 0x2586,
+ 0x2587, 0x2588, 0x2589, 0x2562, 0x2563, 0x2564, 0x2565, 0x255E, 0x255F, 0x2560,
+ 0x2561, 0x255A, 0x255B, 0x255C, 0x255D, 0x2556, 0x2557, 0x2558, 0x2559, 0x2572,
+ 0x2573, 0x2574, 0x2575, 0x256E, 0x256F, 0x2570, 0x2571, 0x256A, 0x256B, 0x256C,
+ 0x256D, 0x2566, 0x2567, 0x2568, 0x2569, 0x2548, 0x2549, 0x254C, 0x254E, 0x2540,
+ 0x2542, 0x2544, 0x2545, 0x2538, 0x253A, 0x253C, 0x253E, 0x2530, 0x2532, 0x2534,
+ 0x2535, 0x0086, 0x0087, 0x0088, 0x0089, 0x01A2, 0x0209, 0x2550, 0x2552, 0x2554,
+ 0x2508, 0x250A, 0x250C, 0x250E, 0x2500, 0x2502, 0x2503, 0x2504, 0x24F8, 0x24FA,
+ 0x24FC, 0x24FE, 0x24F0, 0x24F1, 0x24F4, 0x24F6, 0x2527, 0x252A, 0x252B, 0x252C,
+ 0x2520, 0x2522, 0x2524, 0x2526, 0x2518, 0x251A, 0x251C, 0x251E, 0x2510, 0x2511,
+ 0x2514, 0x2516, 0x254A, 0x254B, 0x254D, 0x254F, 0x2541, 0x2543, 0x2546, 0x2547,
+ 0x2539, 0x253B, 0x253D, 0x253F, 0x2531, 0x2533, 0x2536, 0x2537, 0x2551, 0x2553,
+ 0x2555, 0x2509, 0x250B, 0x250D, 0x250F, 0x2501, 0x2505, 0x2506, 0x2507, 0x24F9,
+ 0x24FB, 0x24FD, 0x24FF, 0x24F2, 0x24F3, 0x24F5, 0x24F7, 0x2529, 0x252D, 0x252E,
+ 0x252F, 0x2521, 0x2523, 0x2525, 0x2528, 0x2519, 0x251B, 0x251D, 0x251F, 0x2512,
+ 0x2513, 0x2515, 0x2517, 0x0232, 0x023B, 0x0206, 0x0211, 0x021D, 0x0227, 0x019F,
+ 0x395D, 0x395E, 0x395F, 0x3960, 0x3959, 0x395A, 0x395B, 0x395C, 0x3955, 0x3956,
+ 0x3957, 0x3958, 0x3951, 0x3952, 0x3953, 0x3954, 0x396D, 0x01A2, 0x00F8, 0x3969,
+ 0x396A, 0x396B, 0x396C, 0x3965, 0x3966, 0x3967, 0x3968, 0x3961, 0x3962, 0x3963,
+ 0x3964, 0x011E, 0x011F, 0x0120, 0x0121, 0x01A2, 0x01C9, 0x01DF, 0x01F5, 0x0233,
+ 0x023C, 0x0207, 0x0212, 0x021E, 0x0228, 0x01A0, 0x01BE, 0x01DC, 0x01F1, 0x185E,
+ 0x185F, 0x1860, 0x1861, 0x185A, 0x185B, 0x185C, 0x185D, 0x1856, 0x1857, 0x1858,
+ 0x1859, 0x1852, 0x1853, 0x1854, 0x02CF, 0x02F9, 0x0484, 0x03FA, 0x0699, 0x069A,
+ 0x069B, 0x0664, 0x0665, 0x0666, 0x0667, 0x03F5, 0x02C5, 0x02E7, 0x047D, 0x03E1,
+ 0x0691, 0x0692, 0x0693, 0x065A, 0x065B, 0x065C, 0x065D, 0x03DC, 0x03DE, 0x03E0,
+ 0x184E, 0x1850, 0x040E, 0x184B, 0x184C, 0x184D, 0x0300, 0x184A, 0x1844, 0x1845,
+ 0x1846, 0x01C5, 0x0213, 0x01C7, 0x01DE, 0x01F3, 0x01C6, 0x02D0, 0x032A, 0x06DB,
+ 0x0425, 0x0276, 0x06DB, 0x0886, 0x0819, 0x03E2, 0x3A65, 0x3A66, 0x3A7B, 0x3A74,
+ 0x3A77, 0x3A70, 0x3A71, 0x3A73, 0x3A6C, 0x3A6E, 0x0578, 0x053D, 0x0554, 0x0578,
+ 0x04AB, 0x03FB, 0x03FB, 0x045C, 0x044C, 0x397A, 0x397B, 0x397C, 0x397D, 0x3976,
+ 0x3977, 0x3978, 0x3979, 0x3972, 0x3973, 0x3974, 0x3975, 0x396E, 0x396F, 0x3970,
+ 0x3971, 0x398A, 0x01A2, 0x00F9, 0x00FA, 0x3986, 0x3987, 0x3988, 0x3989, 0x3982,
+ 0x3983, 0x3984, 0x3985, 0x397E, 0x397F, 0x3980, 0x3981, 0x3A44, 0x3A45, 0x3A46,
+ 0x3A47, 0x3A40, 0x3A41, 0x3A42, 0x3A43, 0x3A3C, 0x3A3D, 0x3A3E, 0x3A3F, 0x3A38,
+ 0x3A39, 0x3A3A, 0x3A3B, 0x010A, 0x010B, 0x010C, 0x010D, 0x01A2, 0x01C9, 0x01DF,
+ 0x01F5, 0x3A48, 0x3A49, 0x3A4A, 0x3A2E, 0x3A2F, 0x3A30, 0x3A31, 0x3A2A, 0x3A2B,
+ 0x3A2C, 0x3A2D, 0x3A26, 0x3A27, 0x3A28, 0x3A29, 0x3A22, 0x3A23, 0x3A24, 0x3A25,
+ 0x0106, 0x0107, 0x0108, 0x01C9, 0x01DF, 0x006B, 0x0067, 0x3A35, 0x39B7, 0x39B8,
+ 0x39B9, 0x39BA, 0x39B3, 0x39B4, 0x39B5, 0x39B6, 0x39AF, 0x39B0, 0x39B1, 0x39B2,
+ 0x39AB, 0x39AC, 0x39AD, 0x05D2, 0x05E5, 0x05D5, 0x05B6, 0x05A3, 0x05E0, 0x05D0,
+ 0x05AF, 0x059F, 0x05B3, 0x0565, 0x0574, 0x0566, 0x056E, 0x0560, 0x0572, 0x0564,
+ 0x053A, 0x0535, 0x053B, 0x0536, 0x0500, 0x04D6, 0x04FF, 0x04D5, 0x03F3, 0x03DA,
+ 0x03EA, 0x03D2, 0x03B8, 0x03AC, 0x03BB, 0x03AF, 0x03BA, 0x03AE, 0x03B6, 0x03AA,
+ 0x0391, 0x0385, 0x03B7, 0x03AB, 0x0454, 0x0443, 0x0480, 0x0479, 0x0453, 0x0442,
+ 0x0455, 0x0444, 0x042A, 0x0421, 0x0452, 0x0441, 0x0426, 0x041D, 0x0429, 0x0420,
+ 0x02F5, 0x02E3, 0x02F7, 0x02E5, 0x02CD, 0x02C3, 0x02F2, 0x02E0, 0x02AB, 0x02A5,
+ 0x02AC, 0x02A6, 0x0285, 0x025A, 0x02AA, 0x02A4, 0x0339, 0x0327, 0x0321, 0x033C,
+ 0x0320, 0x02F3, 0x02E1, 0x02F6, 0x02E4, 0x0634, 0x0612, 0x0633, 0x0611, 0x0631,
+ 0x060F, 0x0632, 0x0610, 0x0636, 0x0614, 0x062D, 0x060B, 0x0507, 0x04DD, 0x0509,
+ 0x04DF, 0x0215, 0x021F, 0x022A, 0x0673, 0x04E0, 0x0501, 0x04D7, 0x03EF, 0x03D6,
+ 0x03F2, 0x03D9, 0x0332, 0x0316, 0x0342, 0x0326, 0x0331, 0x0317, 0x0506, 0x0249,
+ 0x0282, 0x067C, 0x0682, 0x088C, 0x0894, 0x088A, 0x0892, 0x086F, 0x087B, 0x3924,
+ 0x3925, 0x0848, 0x07CF, 0x0742, 0x3934, 0x3935, 0x392C, 0x392D, 0x392A, 0x3A04,
+ 0x3A06, 0x3A00, 0x07B4, 0x07AF, 0x07B7, 0x07A0, 0x0793, 0x07DB, 0x07DF, 0x07DD,
+ 0x07E1, 0x07DA, 0x07DE, 0x07DC, 0x07E0, 0x07C8, 0x07CC, 0x07CA, 0x07CE, 0x07C7,
+ 0x07CB, 0x07C9, 0x07CD, 0x074C, 0x0754, 0x0750, 0x0758, 0x074B, 0x0753, 0x074E,
+ 0x0756, 0x0731, 0x0739, 0x0735, 0x073D, 0x0730, 0x0738, 0x0733, 0x073B, 0x077C,
+ 0x00F2, 0x00F3, 0x0774, 0x0773, 0x0772, 0x0775, 0x0829, 0x0858, 0x085A, 0x0857,
+ 0x0856, 0x0824, 0x0825, 0x084A, 0x084E, 0x0849, 0x084F, 0x084D, 0x084C, 0x0899,
+ 0x39E5, 0x39E4, 0x39E7, 0x39DC, 0x46B5, 0x46DC, 0x39DE, 0x39D9, 0x39F5, 0x4751,
+ 0x39F4, 0x46BD, 0x473C, 0x46C3, 0x46BA, 0x4759, 0x39F6, 0x46D9, 0x0782, 0x39ED,
+ 0x39EF, 0x39E9, 0x39EA, 0x07E4, 0x07E6, 0x07E3, 0x07E2, 0x07D2, 0x07D6, 0x07D1,
+ 0x07D7, 0x07D5, 0x07D4, 0x0889, 0x0891, 0x088D, 0x0895, 0x088E, 0x0896, 0x088B,
+ 0x0893, 0x0870, 0x0878, 0x0874, 0x087C, 0x0875, 0x087D, 0x0872, 0x087A, 0x075F,
+ 0x07C6, 0x075D, 0x075E, 0x075C, 0x075B, 0x0741, 0x0745, 0x0746, 0x0744, 0x0747,
+ 0x0743, 0x0748, 0x074D, 0x0755, 0x0751, 0x0759, 0x0752, 0x075A, 0x074F, 0x0757,
+ 0x0732, 0x073A, 0x0736, 0x073E, 0x0737, 0x073F, 0x0734, 0x073C, 0x07AE, 0x20BE,
+ 0x20BF, 0x20C0, 0x20B9, 0x20BC, 0x20B5, 0x34F0, 0x0C3B, 0x0C3C, 0x0C3D, 0x0C3E,
+ 0x0C37, 0x0C38, 0x0C39, 0x0C32, 0x1C54, 0x1C55, 0x1C56, 0x022A, 0x00FD, 0x01C9,
+ 0x015F, 0x0179, 0x017A, 0x017B, 0x017C, 0x0175, 0x0176, 0x0177, 0x0178, 0x0170,
+ 0x0171, 0x0173, 0x016F, 0x014A, 0x014B, 0x014C, 0x014D, 0x0234, 0x0147, 0x0148,
+ 0x0149, 0x0209, 0x0215, 0x021F, 0x022A, 0x01A2, 0x01C9, 0x01DF, 0x1C4B, 0x1C4C,
+ 0x017D, 0x438F, 0x12FB, 0x12FC, 0x12FC, 0x4384, 0x4387, 0x438A, 0x438C, 0x437B,
+ 0x437E, 0x4380, 0x4382, 0x436F, 0x4370, 0x4372, 0x4373, 0x4368, 0x436A, 0x436C,
+ 0x436D, 0x4365, 0x435B, 0x435D, 0x435F, 0x438B, 0x438D, 0x4390, 0x4391, 0x4385,
+ 0x4386, 0x4388, 0x4389, 0x437D, 0x437F, 0x4381, 0x4383, 0x4375, 0x4377, 0x4379,
+ 0x437C, 0x3831, 0x3832, 0x3833, 0x3834, 0x382D, 0x382E, 0x382F, 0x3830, 0x3829,
+ 0x382A, 0x382B, 0x382C, 0x3825, 0x3826, 0x3827, 0x3828, 0x3841, 0x3842, 0x3843,
+ 0x3844, 0x383D, 0x383E, 0x383F, 0x3840, 0x3839, 0x383A, 0x383B, 0x383C, 0x3835,
+ 0x3836, 0x3837, 0x3838, 0x3811, 0x3812, 0x3813, 0x3814, 0x380D, 0x380E, 0x380F,
+ 0x3810, 0x3809, 0x380A, 0x380B, 0x380C, 0x3805, 0x3806, 0x3807, 0x3808, 0x3821,
+ 0x3822, 0x3823, 0x381D, 0x381E, 0x381F, 0x3818, 0x37F1, 0x37F2, 0x37F3, 0x37F4,
+ 0x37ED, 0x37EE, 0x37EF, 0x37F0, 0x37E9, 0x37EA, 0x37EB, 0x37EC, 0x37E5, 0x37E6,
+ 0x37E7, 0x3804, 0x37FD, 0x37FE, 0x3800, 0x37F9, 0x37FA, 0x37FB, 0x37FC, 0x37F5,
+ 0x37F6, 0x37F7, 0x37D4, 0x37C8, 0x37E1, 0x37E2, 0x37E3, 0x37E4, 0x37DD, 0x37DE,
+ 0x37DF, 0x37E0, 0x37D9, 0x37DA, 0x37DB, 0x37DC, 0x37D5, 0x37D6, 0x37D7, 0x37D8,
+ 0x38B1, 0x38B2, 0x38B3, 0x38B4, 0x38AD, 0x38AE, 0x38AF, 0x38B0, 0x38A9, 0x38AA,
+ 0x38AB, 0x38AC, 0x38A5, 0x38A6, 0x38A7, 0x38A8, 0x38C1, 0x38C2, 0x38C3, 0x38B8,
+ 0x3891, 0x3892, 0x3893, 0x3894, 0x388D, 0x388E, 0x388F, 0x3890, 0x3889, 0x388A,
+ 0x388B, 0x388C, 0x3885, 0x3886, 0x3887, 0x3868, 0x3881, 0x3882, 0x3883, 0x3884,
+ 0x387D, 0x387E, 0x387F, 0x3880, 0x3879, 0x387A, 0x387B, 0x387C, 0x3875, 0x3876,
+ 0x3877, 0x3878, 0x3851, 0x3852, 0x3853, 0x3854, 0x384D, 0x384E, 0x384F, 0x3850,
+ 0x3849, 0x384A, 0x384B, 0x384C, 0x3845, 0x3846, 0x3847, 0x3848, 0x3861, 0x3862,
+ 0x3863, 0x3864, 0x385D, 0x385E, 0x385F, 0x3860, 0x3859, 0x385A, 0x385B, 0x385C,
+ 0x3855, 0x3856, 0x3857, 0x3858, 0x3916, 0x3917, 0x3918, 0x3919, 0x3912, 0x3913,
+ 0x3914, 0x3915, 0x3908, 0x3909, 0x390A, 0x390B, 0x3904, 0x3905, 0x3906, 0x3907,
+ 0x3900, 0x3901, 0x3902, 0x3903, 0x38FC, 0x38FD, 0x38FE, 0x069D, 0x06E0, 0x0296,
+ 0x0544, 0x0586, 0x05BF, 0x05C8, 0x042F, 0x04B5, 0x02B6, 0x390F, 0x38F1, 0x38F2,
+ 0x38F3, 0x38EF, 0x38E8, 0x38F9, 0x38FA, 0x38FB, 0x38F5, 0x38F6, 0x38F7, 0x38F8,
+ 0x38D1, 0x38D2, 0x38D3, 0x38D4, 0x38CD, 0x38CE, 0x38CF, 0x38D0, 0x38C9, 0x38CA,
+ 0x38CB, 0x38CC, 0x38C5, 0x38C6, 0x38C7, 0x38D8, 0x1F85, 0x1F90, 0x1F91, 0x1F92,
+ 0x1F8C, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F66, 0x1F67, 0x1F68, 0x1F69, 0x1F62,
+ 0x1F63, 0x1F64, 0x1F65, 0x1F5E, 0x1F5F, 0x1F60, 0x1F61, 0x1F7A, 0x1F7B, 0x1F7C,
+ 0x1F7D, 0x1F76, 0x1F77, 0x1F78, 0x1F79, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F6E,
+ 0x1F6F, 0x1F70, 0x1F71, 0x1D15, 0x1D16, 0x1D17, 0x1D18, 0x1D11, 0x1D12, 0x1D13,
+ 0x1D14, 0x1D0D, 0x1D0E, 0x1D0F, 0x1D10, 0x1D09, 0x1D0A, 0x1D0B, 0x1D0C, 0x1D1D,
+ 0x1D1E, 0x1D1F, 0x1D19, 0x1D1A, 0x1D1B, 0x1D1C, 0x35A1, 0x35A2, 0x35A3, 0x35A4,
+ 0x359D, 0x359E, 0x359F, 0x35A0, 0x3599, 0x359A, 0x359B, 0x359C, 0x3595, 0x3596,
+ 0x3597, 0x3598, 0x35B1, 0x35B3, 0x35B4, 0x35AD, 0x357F, 0x3581, 0x3583, 0x3575,
+ 0x3577, 0x3579, 0x357B, 0x356D, 0x356F, 0x3571, 0x3573, 0x3565, 0x3567, 0x3569,
+ 0x356B, 0x3591, 0x3592, 0x3593, 0x358E, 0x358F, 0x3588, 0x353D, 0x353F, 0x3541,
+ 0x3537, 0x3539, 0x357C, 0x355D, 0x355F, 0x3561, 0x3563, 0x3555, 0x3557, 0x3559,
+ 0x355B, 0x354D, 0x354F, 0x3551, 0x3553, 0x3545, 0x3547, 0x3549, 0x354B, 0x354E,
+ 0x3550, 0x3552, 0x3554, 0x3546, 0x3548, 0x354A, 0x354C, 0x353E, 0x3540, 0x3542,
+ 0x3544, 0x3536, 0x3538, 0x353A, 0x353C, 0x356E, 0x3570, 0x3572, 0x356C, 0x3564,
+ 0x3556, 0x3558, 0x355A, 0x355C, 0x219D, 0x219F, 0x21A1, 0x2197, 0x2199, 0x1FF3,
+ 0x1FF4, 0x1FF5, 0x1FEE, 0x21AB, 0x21AE, 0x21B0, 0x21B2, 0x21B4, 0x21A6, 0x21A8,
+ 0x21AA, 0x21AC, 0x219E, 0x21A0, 0x21A2, 0x1FC7, 0x1FC9, 0x21B8, 0x1FE1, 0x1FE3,
+ 0x218E, 0x2190, 0x2188, 0x2180, 0x2182, 0x364C, 0x364D, 0x364F, 0x3649, 0x364B,
+ 0x3646, 0x3647, 0x3641, 0x1D3A, 0x1D3B, 0x1D3C, 0x1D36, 0x1D37, 0x1D37, 0x1D32,
+ 0x0DBD, 0x0E64, 0x0E46, 0x0FE5, 0x0ED1, 0x0F16, 0x0FBD, 0x0D57, 0x0C9E, 0x0CA8,
+ 0x36AD, 0x36A6, 0x36A7, 0x1809, 0x180A, 0x180B, 0x1800, 0x1802, 0x1804, 0x1805,
+ 0x17FC, 0x3689, 0x366A, 0x366B, 0x366C, 0x366D, 0x3666, 0x3667, 0x3668, 0x2038,
+ 0x203B, 0x2088, 0x208B, 0x203E, 0x208A, 0x208D, 0x2078, 0x207A, 0x0EBA, 0x0D9E,
+ 0x022A, 0x0234, 0x01F5, 0x0209, 0x0215, 0x021F, 0x0198, 0x01A2, 0x01C9, 0x01DF,
+ 0x2476, 0x2477, 0x2478, 0x2479, 0x2472, 0x2473, 0x2474, 0x2475, 0x246E, 0x246F,
+ 0x2470, 0x2471, 0x246A, 0x246B, 0x246C, 0x246D, 0x247E, 0x247F, 0x247A, 0x247B,
+ 0x247C, 0x247D, 0x2456, 0x2457, 0x2458, 0x2459, 0x2452, 0x2453, 0x2454, 0x2455,
+ 0x244E, 0x244F, 0x2450, 0x2451, 0x244A, 0x244B, 0x244C, 0x244D, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0x2462, 0x2463, 0x2464, 0x2465, 0x245E, 0x245F, 0x2460, 0x2461,
+ 0x245A, 0x245B, 0x245C, 0x245D, 0x20A1, 0x20AA, 0x2062, 0x2063, 0x20A8, 0x20A9,
+ 0x209C, 0x209E, 0x2061, 0x20A3, 0x2446, 0x2447, 0x2448, 0x2449, 0x2442, 0x0291,
+ 0x2443, 0x2444, 0x2445, 0x0346, 0x0372, 0x0395, 0x243E, 0x243F, 0x2440, 0x2441,
+ 0x243A, 0x243B, 0x243C, 0x243D, 0x2094, 0x2096, 0x2097, 0x2099, 0x203A, 0x2081,
+ 0x204B, 0x206E, 0x2030, 0x06BE, 0x06DB, 0x0267, 0x02A8, 0x02C6, 0x02EF, 0x032A,
+ 0x036D, 0x0389, 0x03B2, 0x03E2, 0x040E, 0x0424, 0x044C, 0x047E, 0x049C, 0x04E6,
+ 0x0538, 0x0551, 0x2032, 0x05AC, 0x05DD, 0x061A, 0x065F, 0x067F, 0x0694, 0x06B2,
+ 0x06D2, 0x0291, 0x02AE, 0x02D0, 0x0300, 0x0346, 0x0372, 0x0395, 0x03BD, 0x03FB,
+ 0x0412, 0x042D, 0x045C, 0x0485, 0x04AB, 0x0510, 0x053D, 0x0554, 0x0578, 0x05BC,
+ 0x05E9, 0x063C, 0x0669, 0x0688, 0x069C, 0x202C, 0x06DB, 0x0267, 0x02A8, 0x02C6,
+ 0x02EF, 0x032A, 0x202D, 0x0389, 0x03B2, 0x03E2, 0x040E, 0x202E, 0x202F, 0x205F,
+ 0x2060, 0x2095, 0x2098, 0x209B, 0x20A5, 0x2057, 0x204C, 0x20A2, 0x20A4, 0x20A6,
+ 0x20A7, 0x209A, 0x209D, 0x209F, 0x20A0, 0x02D0, 0x0300, 0x1E61, 0x1E62, 0x1E5D,
+ 0x1E5E, 0x1E5F, 0x1E60, 0x1E59, 0x1E5A, 0x1E5B, 0x1E5C, 0x1E55, 0x1E56, 0x1E57,
+ 0x1E58, 0x1E67, 0x1E63, 0x1E64, 0x1E65, 0x1E66, 0x0215, 0x021F, 0x022A, 0x0234,
+ 0x01C9, 0x01DF, 0x01F5, 0x0209, 0x0198, 0x01A2, 0x1E51, 0x1E46, 0x01DF, 0x00E9,
+ 0x00EA, 0x00EB, 0x00EC, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E1, 0x00E2, 0x00E3,
+ 0x00E4, 0x34D8, 0x34D9, 0x34DA, 0x34DB, 0x34D4, 0x34D5, 0x34D6, 0x34D7, 0x34D0,
+ 0x34D1, 0x34D2, 0x34D3, 0x34CC, 0x34CD, 0x34CE, 0x1CB4, 0x1CB5, 0x1CB6, 0x1CAD,
+ 0x1CAF, 0x1CB0, 0x1CB1, 0x1CA9, 0x1CAA, 0x1CAB, 0x1CAC, 0x1CA5, 0x1CA7, 0x1CA8,
+ 0x1CC3, 0x34BA, 0x34AF, 0x34C8, 0x34C9, 0x34CA, 0x34CB, 0x34C4, 0x34C5, 0x34C6,
+ 0x34C7, 0x34C0, 0x34C1, 0x34C2, 0x34C3, 0x34BC, 0x34BD, 0x34BE, 0x34BF, 0x349B,
+ 0x349C, 0x349D, 0x349E, 0x3497, 0x3498, 0x3499, 0x349A, 0x3493, 0x3494, 0x3495,
+ 0x3496, 0x348F, 0x3490, 0x3491, 0x3492, 0x34AB, 0x1F5C, 0x34A8, 0x34A9, 0x34A2,
+ 0x0B07, 0x0B08, 0x0B09, 0x0B05, 0x0AFE, 0x1F30, 0x1F35, 0x1F3A, 0x1F3F, 0x1F1C,
+ 0x1F2B, 0x1F08, 0x0F3B, 0x1F51, 0x1F52, 0x1F53, 0x1F4C, 0x0F5D, 0x1F48, 0x1EF9,
+ 0x1EE5, 0x1EEA, 0x1EEF, 0x1ECC, 0x1ED1, 0x1ED6, 0x0F88, 0x1EDB, 0x1EB8, 0x3526,
+ 0x3527, 0x2421, 0x2422, 0x2423, 0x241C, 0x241D, 0x241E, 0x241F, 0x2418, 0x2419,
+ 0x241A, 0x241B, 0x2414, 0x2415, 0x2416, 0x2417, 0x23F0, 0x23F1, 0x23F2, 0x23F3,
+ 0x0C81, 0x23EC, 0x23ED, 0x23EE, 0x23EF, 0x23E8, 0x23E9, 0x23EA, 0x23EB, 0x23E4,
+ 0x23E5, 0x23E6, 0x23E7, 0x2400, 0x23F9, 0x23FA, 0x23FB, 0x23F4, 0x23D1, 0x23D2,
+ 0x23D3, 0x23CC, 0x23CD, 0x23CE, 0x23CF, 0x23C8, 0x23CB, 0x23C4, 0x23C5, 0x3AA2,
+ 0x3ABB, 0x3AB9, 0x3AB2, 0x3A8D, 0x3A8E, 0x3A8F, 0x3A89, 0x3A8A, 0x3A8B, 0x24CE,
+ 0x24C4, 0x24DD, 0x24DE, 0x24DF, 0x24D7, 0x24D9, 0x24DA, 0x24DB, 0x24D3, 0x24C5,
+ 0x24D4, 0x24D6, 0x24CF, 0x24D0, 0x24D1, 0x24D2, 0x24A4, 0x24A5, 0x24A6, 0x24A8,
+ 0x24A2, 0x24A3, 0x24E1, 0x24E3, 0x249D, 0x249E, 0x249F, 0x24A0, 0x249A, 0x249B,
+ 0x249C, 0x24E5, 0x24B6, 0x24B9, 0x24E8, 0x248E, 0x2487, 0x3743, 0x373F, 0x371C,
+ 0x371D, 0x371E, 0x371A, 0x248F, 0x372B, 0x1D07, 0x1CFD, 0x3723, 0x36FE, 0x36FF,
+ 0x3700, 0x36FA, 0x36FB, 0x36FC, 0x36FD, 0x36F6, 0x36F7, 0x36F8, 0x36F2, 0x36F3,
+ 0x36F4, 0x3704, 0x37B6, 0x37B7, 0x37B8, 0x37B9, 0x37B2, 0x37B3, 0x37B4, 0x37B5,
+ 0x37AE, 0x37AF, 0x37B0, 0x37AB, 0x37AC, 0x1CE2, 0x1CE3, 0x1CE4, 0x1CDD, 0x1CD9,
+ 0x37BD, 0x3796, 0x3797, 0x3798, 0x3799, 0x3792, 0x3793, 0x3794, 0x3795, 0x378E,
+ 0x378F, 0x3790, 0x378B, 0x378C, 0x37A6, 0x379D, 0x3776, 0x3777, 0x3778, 0x3779,
+ 0x3772, 0x3773, 0x3774, 0x3775, 0x376E, 0x376F, 0x3770, 0x376B, 0x376C, 0x376D,
+ 0x3786, 0x3787, 0x3788, 0x3783, 0x3784, 0x377D, 0x3756, 0x3757, 0x3758, 0x3753,
+ 0x3754, 0x374D, 0x3766, 0x3767, 0x3768, 0x3769, 0x3762, 0x3763, 0x3764, 0x3765,
+ 0x375E, 0x375F, 0x3760, 0x3761, 0x375A, 0x375B, 0x375C, 0x00CE, 0x00CF, 0x00D0,
+ 0x00D1, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00C2,
+ 0x00C3, 0x00C4, 0x1E3E, 0x1E3F, 0x1E40, 0x1E39, 0x1E3B, 0x1E3C, 0x1E35, 0x0209,
+ 0x00B7, 0x00B8, 0x00B9, 0x0209, 0x0209, 0x00B4, 0x00B5, 0x00B6, 0x00B0, 0x00B1,
+ 0x00B2, 0x2229, 0x222A, 0x222B, 0x2224, 0x2225, 0x2226, 0x2227, 0x2220, 0x2221,
+ 0x2222, 0x2223, 0x221C, 0x2231, 0x2232, 0x2233, 0x4849, 0x222D, 0x222E, 0x222F,
+ 0x2208, 0x2219, 0x4885, 0x02AE, 0x0291, 0x0300, 0x02D0, 0x0372, 0x0346, 0x03BD,
+ 0x0395, 0x0412, 0x03FB, 0x045C, 0x042D, 0x04AB, 0x0485, 0x053D, 0x0510, 0x0578,
+ 0x0554, 0x05E9, 0x05BC, 0x0669, 0x063C, 0x069C, 0x0688, 0x06DB, 0x06BE, 0x02A8,
+ 0x0267, 0x02EF, 0x02C6, 0x036D, 0x032A, 0x03B2, 0x0389, 0x040E, 0x03E2, 0x044C,
+ 0x0424, 0x049C, 0x047E, 0x0538, 0x04E6, 0x056A, 0x0551, 0x05DD, 0x05AC, 0x065F,
+ 0x061A, 0x0694, 0x067F, 0x06D2, 0x06B2, 0x02AE, 0x0291, 0x0300, 0x02D0, 0x0372,
+ 0x0346, 0x03BD, 0x0395, 0x0412, 0x03FB, 0x045C, 0x042D, 0x04AB, 0x0485, 0x053D,
+ 0x0510, 0x0578, 0x0554, 0x05E9, 0x05BC, 0x0669, 0x063C, 0x069C, 0x0688, 0x06DB,
+ 0x06BE, 0x02A8, 0x0267, 0x02EF, 0x02C6, 0x036D, 0x032A, 0x0865, 0x0389, 0x040E,
+ 0x03E2, 0x044C, 0x0424, 0x049C, 0x047E, 0x0538, 0x04E6, 0x056A, 0x0551, 0x05DD,
+ 0x05AC, 0x065F, 0x061A, 0x0694, 0x067F, 0x06D2, 0x06B2, 0x02AE, 0x0291, 0x0300,
+ 0x02D0, 0x0372, 0x0346, 0x03BD, 0x0395, 0x0412, 0x03FB, 0x045C, 0x042D, 0x04AB,
+ 0x0485, 0x053D, 0x0510, 0x0578, 0x0554, 0x05E9, 0x05BC, 0x0669, 0x063C, 0x069C,
+ 0x0688, 0x221A, 0x221B, 0x2214, 0x2215, 0x2216, 0x2217, 0x2210, 0x2211, 0x2212,
+ 0x2213, 0x220C, 0x220D, 0x220E, 0x220F, 0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21E4,
+ 0x21E5, 0x21E6, 0x21E7, 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21DC, 0x21DD, 0x21DE,
+ 0x21DF, 0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21F4, 0x21F5, 0x21F6, 0x21F7, 0x21F0,
+ 0x21F1, 0x21F2, 0x21F3, 0x21EC, 0x21ED, 0x21EE, 0x21EF, 0x21C8, 0x21C9, 0x21CA,
+ 0x21CB, 0x21C4, 0x21C5, 0x21C6, 0x21C7, 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21BD,
+ 0x21BE, 0x21BF, 0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21D4, 0x21D5, 0x21D6, 0x21D7,
+ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x022B, 0x21CC, 0x21CD, 0x21CE, 0x21CF, 0x22A8,
+ 0x22A9, 0x22AA, 0x22AB, 0x22A4, 0x22A5, 0x22A6, 0x22A7, 0x22A0, 0x22A1, 0x22A2,
+ 0x22A3, 0x229C, 0x229D, 0x229E, 0x229F, 0x22B8, 0x22B9, 0x0578, 0x0554, 0x05E9,
+ 0x05BC, 0x0669, 0x063C, 0x069C, 0x0688, 0x06DB, 0x06BE, 0x02A8, 0x0267, 0x02EF,
+ 0x02C6, 0x036D, 0x032A, 0x03B2, 0x0389, 0x22BA, 0x22BB, 0x044C, 0x0424, 0x049C,
+ 0x047E, 0x0538, 0x04E6, 0x056A, 0x0551, 0x05DD, 0x05AC, 0x065F, 0x061A, 0x22B4,
+ 0x22B5, 0x22B6, 0x22B1, 0x22B2, 0x0FCE, 0x0FCC, 0x22B3, 0x22AC, 0x22AD, 0x0FC7,
+ 0x22AE, 0x22AF, 0x2288, 0x0FD6, 0x0FD5, 0x2289, 0x228A, 0x228B, 0x042D, 0x2284,
+ 0x2285, 0x100D, 0x100C, 0x100A, 0x0FDD, 0x2286, 0x2287, 0x0C84, 0x1006, 0x1005,
+ 0x2280, 0x0C7E, 0x0C8A, 0x0C93, 0x0C86, 0x0C92, 0x2281, 0x0C94, 0x2282, 0x0C97,
+ 0x2283, 0x0C95, 0x0C88, 0x1004, 0x0C79, 0x0C87, 0x1003, 0x227C, 0x227D, 0x227E,
+ 0x227F, 0x0412, 0x2298, 0x2299, 0x229A, 0x229B, 0x2294, 0x2295, 0x2296, 0x2297,
+ 0x2290, 0x03FB, 0x2291, 0x2292, 0x2D1B, 0x2293, 0x228C, 0x228D, 0x228E, 0x2D31,
+ 0x2D37, 0x07BF, 0x07F4, 0x0FCA, 0x228F, 0x0865, 0x0869, 0x0885, 0x07FA, 0x2268,
+ 0x2262, 0x100B, 0x2279, 0x0FC3, 0x227A, 0x227B, 0x2274, 0x2275, 0x2276, 0x2277,
+ 0x2270, 0x2271, 0x2272, 0x2273, 0x226C, 0x226D, 0x0769, };
+
diff --git a/vendor/nunicode/src/libnu/gen/_ducet_switch.c b/vendor/nunicode/src/libnu/gen/_ducet_switch.c
new file mode 100644
index 0000000000..005ac1f259
--- /dev/null
+++ b/vendor/nunicode/src/libnu/gen/_ducet_switch.c
@@ -0,0 +1,1216 @@
+/* Automatically generated file (contractions-toc), 1490539886
+ *
+ * Tag : _nu_ducet
+ * Contractions : 820
+ */
+
+#include <stdint.h>
+
+#include <libnu/udb.h>
+
+const size_t _NU_DUCET_CONTRACTIONS = 820; /* contractions included in switch */
+const size_t _NU_DUCET_CODEPOINTS = 20027; /* complementary codepoints number */
+
+#define state_00AAB9 -838
+#define state_000438 -826
+#define state_0019B5 -749
+#define state_001B09 -745
+#define state_0019B7 -744
+#define state_0019BA -737
+#define state_00006C -712
+#define state_0019B6 -686
+#define state_00064A -684
+#define state_000648 -674
+#define state_00AABB -667
+#define state_000418 -500
+#define state_001B07 -482
+#define state_001B05 -454
+#define state_00AABC -394
+#define state_000627 -391
+#define state_000B92 -381
+#define state_00004C -343
+#define state_001B0D -252
+#define state_001025 -217
+#define state_000E40 -198
+#define state_000E41 -197
+#define state_000E42 -196
+#define state_000E43 -195
+#define state_000E44 -194
+#define state_00AAB5 -171
+#define state_00AAB6 -161
+#define state_000EC1 -114
+#define state_000EC0 -113
+#define state_000EC3 -112
+#define state_000EC2 -111
+#define state_000EC4 -109
+#define state_001B0B -59
+#define state_001B11 -24
+
+const int16_t _NU_DUCET_ROOTS_G[] = {
+ 0, -34, 0, 0, -33, -32, -31, -30, -29, -28, 2, -26,
+ -15, 0, 0, 3, 0, 0, -14, -13, -12, 8, 1, 8,
+ -10, 0, -7, -6, 5, 20, 4, -4, -2, 0, };
+
+const size_t _NU_DUCET_ROOTS_G_SIZE = sizeof(_NU_DUCET_ROOTS_G) / sizeof(*_NU_DUCET_ROOTS_G);
+
+/* codepoints */
+const uint32_t _NU_DUCET_ROOTS_VALUES_C[] = {
+ 0x00004C, 0x001B0D, 0x000648, 0x000EC0, 0x00064A, 0x000E44, 0x001B0B, 0x000EC1,
+ 0x000EC3, 0x001B05, 0x000E41, 0x000E43, 0x00006C, 0x000627, 0x0019B5, 0x001025,
+ 0x001B07, 0x00AAB9, 0x000E40, 0x0019B7, 0x000E42, 0x00AABC, 0x001B09, 0x0019BA,
+ 0x000EC2, 0x0019B6, 0x000B92, 0x000418, 0x00AABB, 0x000438, 0x00AAB5, 0x00AAB6,
+ 0x001B11, 0x000EC4, };
+
+/* indexes */
+const uint16_t _NU_DUCET_ROOTS_VALUES_I[] = {
+ 0x0157, 0x00FC, 0x02A2, 0x0071, 0x02AC, 0x00C2, 0x003B, 0x0072, 0x0070, 0x01C6,
+ 0x00C5, 0x00C3, 0x02C8, 0x0187, 0x02ED, 0x00D9, 0x01E2, 0x0346, 0x00C6, 0x02E8,
+ 0x00C4, 0x018A, 0x02E9, 0x02E1, 0x006F, 0x02AE, 0x017D, 0x01F4, 0x029B, 0x033A,
+ 0x00AB, 0x00A1, 0x0018, 0x006D, };
+
+/* MPH lookup for root codepoints + binary search on balanced tree
+ * for intermediate states */
+int32_t _nu_ducet_weight_switch(uint32_t u, int32_t *w, void *context) {
+ (void)(context);
+
+ if (w == 0) { /* first entry, root states */
+ uint32_t state = nu_udb_lookup_value(u, _NU_DUCET_ROOTS_G, _NU_DUCET_ROOTS_G_SIZE,
+ _NU_DUCET_ROOTS_VALUES_C, _NU_DUCET_ROOTS_VALUES_I);
+
+ if (state != 0) {
+ return -state; /* VALUES_I store negated (positive) states */
+ }
+ }
+
+ if (w != 0) { /* re-entry, intermediate states */
+ int32_t weight = *w;
+ *w = 0;
+
+ if (weight == state_00004C) {
+ switch (u) {
+ case 0x000387: return 0x000456;
+ case 0x0000B7: return 0x000456;
+ }
+
+ *w = 1;
+ return 0x00044D;
+ }
+ else if (weight < state_00004C) {
+ if (weight == state_00064A) {
+ switch (u) {
+ case 0x000654: return 0x000C71;
+ }
+
+ *w = 1;
+ return 0x000FE3;
+ }
+ else if (weight < state_00064A) {
+ if (weight == state_0019B7) {
+ switch (u) {
+ case 0x0019A2: return 0x001F15;
+ case 0x001999: return 0x001EE8;
+ case 0x001981: return 0x001E70;
+ case 0x00198E: return 0x001EB1;
+ case 0x001988: return 0x001E93;
+ case 0x001994: return 0x001ECF;
+ case 0x0019A6: return 0x001F29;
+ case 0x00198A: return 0x001E9D;
+ case 0x001984: return 0x001E7F;
+ case 0x00199D: return 0x001EFC;
+ case 0x001991: return 0x001EC0;
+ case 0x0019A3: return 0x001F1A;
+ case 0x001980: return 0x001E6B;
+ case 0x00198D: return 0x001EAC;
+ case 0x001995: return 0x001ED4;
+ case 0x0019A7: return 0x001F2E;
+ case 0x00199A: return 0x001EED;
+ case 0x0019AA: return 0x001F3D;
+ case 0x00199E: return 0x001F01;
+ case 0x001992: return 0x001EC5;
+ case 0x001987: return 0x001E8E;
+ case 0x001996: return 0x001ED9;
+ case 0x0019A0: return 0x001F0B;
+ case 0x00199B: return 0x001EF2;
+ case 0x001983: return 0x001E7A;
+ case 0x0019AB: return 0x001F42;
+ case 0x0019A4: return 0x001F1F;
+ case 0x00199F: return 0x001F06;
+ case 0x001993: return 0x001ECA;
+ case 0x00198C: return 0x001EA7;
+ case 0x001986: return 0x001E89;
+ case 0x0019A8: return 0x001F33;
+ case 0x001997: return 0x001EDE;
+ case 0x0019A1: return 0x001F10;
+ case 0x00199C: return 0x001EF7;
+ case 0x001998: return 0x001EE3;
+ case 0x001982: return 0x001E75;
+ case 0x00198F: return 0x001EB6;
+ case 0x001989: return 0x001E98;
+ case 0x0019A5: return 0x001F24;
+ case 0x00198B: return 0x001EA2;
+ case 0x001985: return 0x001E84;
+ case 0x0019A9: return 0x001F38;
+ case 0x001990: return 0x001EBB;
+ }
+
+ *w = 1;
+ return 0x001F4B;
+ }
+ else if (weight < state_0019B7) {
+ if (weight == state_0019B5) {
+ switch (u) {
+ case 0x0019A8: return 0x001F31;
+ case 0x00199F: return 0x001F04;
+ case 0x001993: return 0x001EC8;
+ case 0x0019AA: return 0x001F3B;
+ case 0x0019A7: return 0x001F2C;
+ case 0x001982: return 0x001E73;
+ case 0x00198F: return 0x001EB4;
+ case 0x001997: return 0x001EDC;
+ case 0x00199C: return 0x001EF5;
+ case 0x0019A0: return 0x001F09;
+ case 0x00198B: return 0x001EA0;
+ case 0x0019A9: return 0x001F36;
+ case 0x001990: return 0x001EB9;
+ case 0x0019A4: return 0x001F1D;
+ case 0x001985: return 0x001E82;
+ case 0x001994: return 0x001ECD;
+ case 0x0019AB: return 0x001F40;
+ case 0x001981: return 0x001E6E;
+ case 0x0019A1: return 0x001F0E;
+ case 0x00198E: return 0x001EAF;
+ case 0x001998: return 0x001EE1;
+ case 0x00199D: return 0x001EFA;
+ case 0x001991: return 0x001EBE;
+ case 0x0019A5: return 0x001F22;
+ case 0x00198A: return 0x001E9B;
+ case 0x001984: return 0x001E7D;
+ case 0x001995: return 0x001ED2;
+ case 0x001989: return 0x001E96;
+ case 0x00199A: return 0x001EEB;
+ case 0x001980: return 0x001E69;
+ case 0x00198D: return 0x001EAA;
+ case 0x001999: return 0x001EE6;
+ case 0x00199E: return 0x001EFF;
+ case 0x0019A2: return 0x001F13;
+ case 0x001987: return 0x001E8C;
+ case 0x001992: return 0x001EC3;
+ case 0x001988: return 0x001E91;
+ case 0x0019A6: return 0x001F27;
+ case 0x001983: return 0x001E78;
+ case 0x001996: return 0x001ED7;
+ case 0x00199B: return 0x001EF0;
+ case 0x0019A3: return 0x001F18;
+ case 0x00198C: return 0x001EA5;
+ case 0x001986: return 0x001E87;
+ }
+
+ *w = 1;
+ return 0x001F49;
+ }
+ else if (weight < state_0019B5) {
+ if (weight == state_000438) {
+ switch (u) {
+ case 0x000306: return 0x000987;
+ }
+
+ *w = 1;
+ return 0x000977;
+ }
+ else if (weight < state_000438) {
+ if (weight == state_00AAB9) {
+ switch (u) {
+ case 0x00AA92: return 0x001AE6;
+ case 0x00AAA5: return 0x001B58;
+ case 0x00AAAC: return 0x001B82;
+ case 0x00AA8F: return 0x001AD4;
+ case 0x00AA82: return 0x001A86;
+ case 0x00AA9C: return 0x001B22;
+ case 0x00AAA1: return 0x001B40;
+ case 0x00AA97: return 0x001B04;
+ case 0x00AAAD: return 0x001B88;
+ case 0x00AA86: return 0x001A9E;
+ case 0x00AA93: return 0x001AEC;
+ case 0x00AA9D: return 0x001B28;
+ case 0x00AA8A: return 0x001AB6;
+ case 0x00AAA6: return 0x001B5E;
+ case 0x00AA94: return 0x001AF2;
+ case 0x00AA8E: return 0x001ACE;
+ case 0x00AAAE: return 0x001B8E;
+ case 0x00AA81: return 0x001A80;
+ case 0x00AAA2: return 0x001B46;
+ case 0x00AA90: return 0x001ADA;
+ case 0x00AA9E: return 0x001B2E;
+ case 0x00AAAA: return 0x001B76;
+ case 0x00AA85: return 0x001A98;
+ case 0x00AA9A: return 0x001B16;
+ case 0x00AAA7: return 0x001B64;
+ case 0x00AA95: return 0x001AF8;
+ case 0x00AA89: return 0x001AB0;
+ case 0x00AA8D: return 0x001AC8;
+ case 0x00AA80: return 0x001A7A;
+ case 0x00AA98: return 0x001B0A;
+ case 0x00AAA3: return 0x001B4C;
+ case 0x00AA91: return 0x001AE0;
+ case 0x00AAA8: return 0x001B6A;
+ case 0x00AAAF: return 0x001B94;
+ case 0x00AA84: return 0x001A92;
+ case 0x00AA8C: return 0x001AC2;
+ case 0x00AA9F: return 0x001B34;
+ case 0x00AAA4: return 0x001B52;
+ case 0x00AAAB: return 0x001B7C;
+ case 0x00AA88: return 0x001AAA;
+ case 0x00AA83: return 0x001A8C;
+ case 0x00AA99: return 0x001B10;
+ case 0x00AA9B: return 0x001B1C;
+ case 0x00AAA0: return 0x001B3A;
+ case 0x00AA96: return 0x001AFE;
+ case 0x00AAA9: return 0x001B70;
+ case 0x00AA87: return 0x001AA4;
+ case 0x00AA8B: return 0x001ABC;
+ }
+
+ *w = 1;
+ return 0x001B9A;
+ }
+ }
+ }
+ else { /* weight > state_0019B5 */
+ if (weight == state_001B09) {
+ switch (u) {
+ case 0x001B35: return 0x001FCC;
+ }
+
+ *w = 1;
+ return 0x001FCB;
+ }
+ }
+ }
+ else { /* weight > state_0019B7 */
+ if (weight == state_00006C) {
+ switch (u) {
+ case 0x0000B7: return 0x000445;
+ case 0x000387: return 0x000445;
+ }
+
+ *w = 1;
+ return 0x00043C;
+ }
+ else if (weight < state_00006C) {
+ if (weight == state_0019BA) {
+ switch (u) {
+ case 0x00198F: return 0x001EB7;
+ case 0x0019A2: return 0x001F16;
+ case 0x001995: return 0x001ED5;
+ case 0x00199C: return 0x001EF8;
+ case 0x001980: return 0x001E6C;
+ case 0x001991: return 0x001EC1;
+ case 0x0019A7: return 0x001F2F;
+ case 0x001984: return 0x001E80;
+ case 0x00199D: return 0x001EFD;
+ case 0x00198A: return 0x001E9E;
+ case 0x0019A3: return 0x001F1B;
+ case 0x001983: return 0x001E7B;
+ case 0x00198E: return 0x001EB2;
+ case 0x001996: return 0x001EDA;
+ case 0x0019A4: return 0x001F20;
+ case 0x001987: return 0x001E8F;
+ case 0x00199E: return 0x001F02;
+ case 0x001992: return 0x001EC6;
+ case 0x0019A0: return 0x001F0C;
+ case 0x00199A: return 0x001EEE;
+ case 0x001982: return 0x001E76;
+ case 0x00198D: return 0x001EAD;
+ case 0x0019AA: return 0x001F3E;
+ case 0x001997: return 0x001EDF;
+ case 0x0019A5: return 0x001F25;
+ case 0x001986: return 0x001E8A;
+ case 0x0019A8: return 0x001F34;
+ case 0x001989: return 0x001E99;
+ case 0x001993: return 0x001ECB;
+ case 0x00198C: return 0x001EA8;
+ case 0x0019A1: return 0x001F11;
+ case 0x001998: return 0x001EE4;
+ case 0x00199F: return 0x001F07;
+ case 0x001994: return 0x001ED0;
+ case 0x00199B: return 0x001EF3;
+ case 0x001981: return 0x001E71;
+ case 0x0019A9: return 0x001F39;
+ case 0x0019AB: return 0x001F43;
+ case 0x001988: return 0x001E94;
+ case 0x001990: return 0x001EBC;
+ case 0x00198B: return 0x001EA3;
+ case 0x0019A6: return 0x001F2A;
+ case 0x001999: return 0x001EE9;
+ case 0x001985: return 0x001E85;
+ }
+
+ *w = 1;
+ return 0x001F4E;
+ }
+ }
+ else { /* weight > state_00006C */
+ if (weight == state_0019B6) {
+ switch (u) {
+ case 0x001995: return 0x001ED3;
+ case 0x0019A3: return 0x001F19;
+ case 0x00199A: return 0x001EEC;
+ case 0x001980: return 0x001E6A;
+ case 0x00198D: return 0x001EAB;
+ case 0x001989: return 0x001E97;
+ case 0x0019AA: return 0x001F3C;
+ case 0x0019A7: return 0x001F2D;
+ case 0x00199E: return 0x001F00;
+ case 0x001990: return 0x001EBA;
+ case 0x001985: return 0x001E83;
+ case 0x001994: return 0x001ECE;
+ case 0x0019A2: return 0x001F14;
+ case 0x001981: return 0x001E6F;
+ case 0x00198E: return 0x001EB0;
+ case 0x0019A6: return 0x001F28;
+ case 0x00199D: return 0x001EFB;
+ case 0x00198A: return 0x001E9C;
+ case 0x001986: return 0x001E88;
+ case 0x001993: return 0x001EC9;
+ case 0x0019A1: return 0x001F0F;
+ case 0x001982: return 0x001E74;
+ case 0x00198F: return 0x001EB5;
+ case 0x001997: return 0x001EDD;
+ case 0x0019A5: return 0x001F23;
+ case 0x00199C: return 0x001EF6;
+ case 0x00198B: return 0x001EA1;
+ case 0x001987: return 0x001E8D;
+ case 0x0019A9: return 0x001F37;
+ case 0x001992: return 0x001EC4;
+ case 0x0019A0: return 0x001F0A;
+ case 0x001999: return 0x001EE7;
+ case 0x001983: return 0x001E79;
+ case 0x001996: return 0x001ED8;
+ case 0x0019A4: return 0x001F1E;
+ case 0x00199B: return 0x001EF1;
+ case 0x00198C: return 0x001EA6;
+ case 0x001988: return 0x001E92;
+ case 0x0019AB: return 0x001F41;
+ case 0x0019A8: return 0x001F32;
+ case 0x00199F: return 0x001F05;
+ case 0x001991: return 0x001EBF;
+ case 0x001998: return 0x001EE2;
+ case 0x001984: return 0x001E7E;
+ }
+
+ *w = 1;
+ return 0x001F4A;
+ }
+ }
+ }
+ }
+ else { /* weight > state_00064A */
+ if (weight == state_001B05) {
+ switch (u) {
+ case 0x001B35: return 0x001FC8;
+ }
+
+ *w = 1;
+ return 0x001FC7;
+ }
+ else if (weight < state_001B05) {
+ if (weight == state_000418) {
+ switch (u) {
+ case 0x000306: return 0x000988;
+ }
+
+ *w = 1;
+ return 0x00097B;
+ }
+ else if (weight < state_000418) {
+ if (weight == state_00AABB) {
+ switch (u) {
+ case 0x00AAA0: return 0x001B3B;
+ case 0x00AA8D: return 0x001AC9;
+ case 0x00AA81: return 0x001A81;
+ case 0x00AA99: return 0x001B11;
+ case 0x00AA90: return 0x001ADB;
+ case 0x00AAAF: return 0x001B95;
+ case 0x00AA9D: return 0x001B29;
+ case 0x00AA85: return 0x001A99;
+ case 0x00AA8A: return 0x001AB7;
+ case 0x00AAAB: return 0x001B7D;
+ case 0x00AA89: return 0x001AB1;
+ case 0x00AAA7: return 0x001B65;
+ case 0x00AA8E: return 0x001ACF;
+ case 0x00AA82: return 0x001A87;
+ case 0x00AA98: return 0x001B0B;
+ case 0x00AA97: return 0x001B05;
+ case 0x00AAAE: return 0x001B8F;
+ case 0x00AAA3: return 0x001B4D;
+ case 0x00AA86: return 0x001A9F;
+ case 0x00AA8B: return 0x001ABD;
+ case 0x00AA93: return 0x001AED;
+ case 0x00AAAA: return 0x001B77;
+ case 0x00AAA6: return 0x001B5F;
+ case 0x00AA8F: return 0x001AD5;
+ case 0x00AA83: return 0x001A8D;
+ case 0x00AA9C: return 0x001B23;
+ case 0x00AA96: return 0x001AFF;
+ case 0x00AAAD: return 0x001B89;
+ case 0x00AAA2: return 0x001B47;
+ case 0x00AA87: return 0x001AA5;
+ case 0x00AAA9: return 0x001B71;
+ case 0x00AA8C: return 0x001AC3;
+ case 0x00AA92: return 0x001AE7;
+ case 0x00AA9F: return 0x001B35;
+ case 0x00AAA5: return 0x001B59;
+ case 0x00AA9B: return 0x001B1D;
+ case 0x00AA95: return 0x001AF9;
+ case 0x00AAA1: return 0x001B41;
+ case 0x00AA80: return 0x001A7B;
+ case 0x00AAA8: return 0x001B6B;
+ case 0x00AA91: return 0x001AE1;
+ case 0x00AA9E: return 0x001B2F;
+ case 0x00AA84: return 0x001A93;
+ case 0x00AAA4: return 0x001B53;
+ case 0x00AAAC: return 0x001B83;
+ case 0x00AA9A: return 0x001B17;
+ case 0x00AA94: return 0x001AF3;
+ case 0x00AA88: return 0x001AAB;
+ }
+
+ *w = 1;
+ return 0x001B9C;
+ }
+ else if (weight < state_00AABB) {
+ if (weight == state_000648) {
+ switch (u) {
+ case 0x000654: return 0x000C68;
+ }
+
+ *w = 1;
+ return 0x000FBB;
+ }
+ }
+ }
+ else { /* weight > state_000418 */
+ if (weight == state_001B07) {
+ switch (u) {
+ case 0x001B35: return 0x001FCA;
+ }
+
+ *w = 1;
+ return 0x001FC9;
+ }
+ }
+ }
+ else { /* weight > state_001B05 */
+ if (weight == state_000627) {
+ switch (u) {
+ case 0x000653: return 0x000C5E;
+ case 0x000655: return 0x000C6B;
+ case 0x000654: return 0x000C61;
+ }
+
+ *w = 1;
+ return 0x000C9B;
+ }
+ else if (weight < state_000627) {
+ if (weight == state_00AABC) {
+ switch (u) {
+ case 0x00AA95: return 0x001AFA;
+ case 0x00AAA1: return 0x001B42;
+ case 0x00AA84: return 0x001A94;
+ case 0x00AA98: return 0x001B0C;
+ case 0x00AA91: return 0x001AE2;
+ case 0x00AAAC: return 0x001B84;
+ case 0x00AA9E: return 0x001B30;
+ case 0x00AA88: return 0x001AAC;
+ case 0x00AAA6: return 0x001B60;
+ case 0x00AA8D: return 0x001ACA;
+ case 0x00AA9A: return 0x001B18;
+ case 0x00AA96: return 0x001B00;
+ case 0x00AAA2: return 0x001B48;
+ case 0x00AA83: return 0x001A8E;
+ case 0x00AA99: return 0x001B12;
+ case 0x00AA92: return 0x001AE8;
+ case 0x00AAAD: return 0x001B8A;
+ case 0x00AA9F: return 0x001B36;
+ case 0x00AA87: return 0x001AA6;
+ case 0x00AAA7: return 0x001B66;
+ case 0x00AA8C: return 0x001AC4;
+ case 0x00AA9B: return 0x001B1E;
+ case 0x00AA97: return 0x001B06;
+ case 0x00AAA3: return 0x001B4E;
+ case 0x00AA82: return 0x001A88;
+ case 0x00AA93: return 0x001AEE;
+ case 0x00AAAE: return 0x001B90;
+ case 0x00AA86: return 0x001AA0;
+ case 0x00AAA8: return 0x001B6C;
+ case 0x00AA8B: return 0x001ABE;
+ case 0x00AAAA: return 0x001B78;
+ case 0x00AA9C: return 0x001B24;
+ case 0x00AAA4: return 0x001B54;
+ case 0x00AA8F: return 0x001AD6;
+ case 0x00AA81: return 0x001A82;
+ case 0x00AA94: return 0x001AF4;
+ case 0x00AAAF: return 0x001B96;
+ case 0x00AAA0: return 0x001B3C;
+ case 0x00AA85: return 0x001A9A;
+ case 0x00AAA9: return 0x001B72;
+ case 0x00AA8A: return 0x001AB8;
+ case 0x00AA90: return 0x001ADC;
+ case 0x00AAAB: return 0x001B7E;
+ case 0x00AA9D: return 0x001B2A;
+ case 0x00AA89: return 0x001AB2;
+ case 0x00AAA5: return 0x001B5A;
+ case 0x00AA8E: return 0x001AD0;
+ case 0x00AA80: return 0x001A7C;
+ }
+
+ *w = 1;
+ return 0x001B9D;
+ }
+ }
+ else { /* weight > state_000627 */
+ if (weight == state_000B92) {
+ switch (u) {
+ case 0x000BD7: return 0x0013E2;
+ }
+
+ *w = 1;
+ return 0x0013E0;
+ }
+ }
+ }
+ }
+ }
+ else { /* weight > state_00004C */
+ if (weight == state_00AAB6) {
+ switch (u) {
+ case 0x00AA9D: return 0x001B27;
+ case 0x00AA87: return 0x001AA3;
+ case 0x00AA8A: return 0x001AB5;
+ case 0x00AAA9: return 0x001B6F;
+ case 0x00AAAD: return 0x001B87;
+ case 0x00AA92: return 0x001AE5;
+ case 0x00AAA0: return 0x001B39;
+ case 0x00AA99: return 0x001B0F;
+ case 0x00AA83: return 0x001A8B;
+ case 0x00AA96: return 0x001AFD;
+ case 0x00AA8F: return 0x001AD3;
+ case 0x00AAA4: return 0x001B51;
+ case 0x00AA9C: return 0x001B21;
+ case 0x00AA88: return 0x001AA9;
+ case 0x00AA8B: return 0x001ABB;
+ case 0x00AAA8: return 0x001B69;
+ case 0x00AAAC: return 0x001B81;
+ case 0x00AA91: return 0x001ADF;
+ case 0x00AA98: return 0x001B09;
+ case 0x00AA84: return 0x001A91;
+ case 0x00AA95: return 0x001AF7;
+ case 0x00AAA3: return 0x001B4B;
+ case 0x00AA80: return 0x001A79;
+ case 0x00AA9B: return 0x001B1B;
+ case 0x00AA89: return 0x001AAF;
+ case 0x00AA8C: return 0x001AC1;
+ case 0x00AAA7: return 0x001B63;
+ case 0x00AAAB: return 0x001B7B;
+ case 0x00AA90: return 0x001AD9;
+ case 0x00AA9F: return 0x001B33;
+ case 0x00AA85: return 0x001A97;
+ case 0x00AAAF: return 0x001B93;
+ case 0x00AA94: return 0x001AF1;
+ case 0x00AAA2: return 0x001B45;
+ case 0x00AA81: return 0x001A7F;
+ case 0x00AA9A: return 0x001B15;
+ case 0x00AA8D: return 0x001AC7;
+ case 0x00AAA6: return 0x001B5D;
+ case 0x00AAAA: return 0x001B75;
+ case 0x00AA9E: return 0x001B2D;
+ case 0x00AA86: return 0x001A9D;
+ case 0x00AAAE: return 0x001B8D;
+ case 0x00AA93: return 0x001AEB;
+ case 0x00AAA1: return 0x001B3F;
+ case 0x00AA82: return 0x001A85;
+ case 0x00AA97: return 0x001B03;
+ case 0x00AA8E: return 0x001ACD;
+ case 0x00AAA5: return 0x001B57;
+ }
+
+ *w = 1;
+ return 0x001B99;
+ }
+ else if (weight < state_00AAB6) {
+ if (weight == state_000E42) {
+ switch (u) {
+ case 0x000E1C: return 0x00193A;
+ case 0x000E16: return 0x001916;
+ case 0x000E24: return 0x00196A;
+ case 0x000E07: return 0x0018BC;
+ case 0x000E0C: return 0x0018DA;
+ case 0x000E12: return 0x0018FE;
+ case 0x000E1F: return 0x00194C;
+ case 0x000E2D: return 0x0019A0;
+ case 0x000E21: return 0x001958;
+ case 0x000E1B: return 0x001934;
+ case 0x000E15: return 0x001910;
+ case 0x000E25: return 0x001970;
+ case 0x000E2A: return 0x00198E;
+ case 0x000E23: return 0x001964;
+ case 0x000E11: return 0x0018F8;
+ case 0x000E1E: return 0x001946;
+ case 0x000E2E: return 0x0019A6;
+ case 0x000E04: return 0x0018AA;
+ case 0x000E1A: return 0x00192E;
+ case 0x000E14: return 0x00190A;
+ case 0x000E08: return 0x0018C2;
+ case 0x000E0D: return 0x0018E0;
+ case 0x000E01: return 0x001898;
+ case 0x000E19: return 0x001928;
+ case 0x000E28: return 0x001982;
+ case 0x000E10: return 0x0018F2;
+ case 0x000E26: return 0x001976;
+ case 0x000E1D: return 0x001940;
+ case 0x000E2B: return 0x001994;
+ case 0x000E05: return 0x0018B0;
+ case 0x000E0A: return 0x0018CE;
+ case 0x000E09: return 0x0018C8;
+ case 0x000E0E: return 0x0018E6;
+ case 0x000E02: return 0x00189E;
+ case 0x000E18: return 0x001922;
+ case 0x000E17: return 0x00191C;
+ case 0x000E27: return 0x00197C;
+ case 0x000E2C: return 0x00199A;
+ case 0x000E06: return 0x0018B6;
+ case 0x000E0B: return 0x0018D4;
+ case 0x000E13: return 0x001904;
+ case 0x000E29: return 0x001988;
+ case 0x000E20: return 0x001952;
+ case 0x000E22: return 0x00195E;
+ case 0x000E0F: return 0x0018EC;
+ case 0x000E03: return 0x0018A4;
+ }
+
+ *w = 1;
+ return 0x0019AF;
+ }
+ else if (weight < state_000E42) {
+ if (weight == state_000E40) {
+ switch (u) {
+ case 0x000E04: return 0x0018A8;
+ case 0x000E27: return 0x00197A;
+ case 0x000E11: return 0x0018F6;
+ case 0x000E2C: return 0x001998;
+ case 0x000E1E: return 0x001944;
+ case 0x000E18: return 0x001920;
+ case 0x000E0D: return 0x0018DE;
+ case 0x000E01: return 0x001896;
+ case 0x000E1A: return 0x00192C;
+ case 0x000E14: return 0x001908;
+ case 0x000E05: return 0x0018AE;
+ case 0x000E0A: return 0x0018CC;
+ case 0x000E20: return 0x001950;
+ case 0x000E10: return 0x0018F0;
+ case 0x000E29: return 0x001986;
+ case 0x000E1D: return 0x00193E;
+ case 0x000E0E: return 0x0018E4;
+ case 0x000E24: return 0x001968;
+ case 0x000E17: return 0x00191A;
+ case 0x000E02: return 0x00189C;
+ case 0x000E2D: return 0x00199E;
+ case 0x000E21: return 0x001956;
+ case 0x000E13: return 0x001902;
+ case 0x000E22: return 0x00195C;
+ case 0x000E06: return 0x0018B4;
+ case 0x000E0B: return 0x0018D2;
+ case 0x000E25: return 0x00196E;
+ case 0x000E2A: return 0x00198C;
+ case 0x000E1C: return 0x001938;
+ case 0x000E16: return 0x001914;
+ case 0x000E0F: return 0x0018EA;
+ case 0x000E03: return 0x0018A2;
+ case 0x000E2E: return 0x0019A4;
+ case 0x000E08: return 0x0018C0;
+ case 0x000E12: return 0x0018FC;
+ case 0x000E1F: return 0x00194A;
+ case 0x000E07: return 0x0018BA;
+ case 0x000E0C: return 0x0018D8;
+ case 0x000E26: return 0x001974;
+ case 0x000E2B: return 0x001992;
+ case 0x000E1B: return 0x001932;
+ case 0x000E19: return 0x001926;
+ case 0x000E23: return 0x001962;
+ case 0x000E28: return 0x001980;
+ case 0x000E09: return 0x0018C6;
+ case 0x000E15: return 0x00190E;
+ }
+
+ *w = 1;
+ return 0x0019AD;
+ }
+ else if (weight < state_000E40) {
+ if (weight == state_001025) {
+ switch (u) {
+ case 0x00102E: return 0x001DE0;
+ }
+
+ *w = 1;
+ return 0x001DDF;
+ }
+ else if (weight < state_001025) {
+ if (weight == state_001B0D) {
+ switch (u) {
+ case 0x001B35: return 0x001FD0;
+ }
+
+ *w = 1;
+ return 0x001FCF;
+ }
+ }
+ }
+ else { /* weight > state_000E40 */
+ if (weight == state_000E41) {
+ switch (u) {
+ case 0x000E2C: return 0x001999;
+ case 0x000E26: return 0x001975;
+ case 0x000E14: return 0x001909;
+ case 0x000E01: return 0x001897;
+ case 0x000E0E: return 0x0018E5;
+ case 0x000E08: return 0x0018C1;
+ case 0x000E1D: return 0x00193F;
+ case 0x000E11: return 0x0018F7;
+ case 0x000E0A: return 0x0018CD;
+ case 0x000E04: return 0x0018A9;
+ case 0x000E29: return 0x001987;
+ case 0x000E2B: return 0x001993;
+ case 0x000E25: return 0x00196F;
+ case 0x000E15: return 0x00190F;
+ case 0x000E1A: return 0x00192D;
+ case 0x000E0D: return 0x0018DF;
+ case 0x000E21: return 0x001957;
+ case 0x000E2E: return 0x0019A5;
+ case 0x000E1E: return 0x001945;
+ case 0x000E23: return 0x001963;
+ case 0x000E07: return 0x0018BB;
+ case 0x000E2A: return 0x00198D;
+ case 0x000E24: return 0x001969;
+ case 0x000E12: return 0x0018FD;
+ case 0x000E03: return 0x0018A3;
+ case 0x000E20: return 0x001951;
+ case 0x000E16: return 0x001915;
+ case 0x000E28: return 0x001981;
+ case 0x000E2D: return 0x00199F;
+ case 0x000E1B: return 0x001933;
+ case 0x000E0C: return 0x0018D9;
+ case 0x000E06: return 0x0018B5;
+ case 0x000E1F: return 0x00194B;
+ case 0x000E13: return 0x001903;
+ case 0x000E18: return 0x001921;
+ case 0x000E02: return 0x00189D;
+ case 0x000E0F: return 0x0018EB;
+ case 0x000E27: return 0x00197B;
+ case 0x000E17: return 0x00191B;
+ case 0x000E1C: return 0x001939;
+ case 0x000E0B: return 0x0018D3;
+ case 0x000E09: return 0x0018C7;
+ case 0x000E22: return 0x00195D;
+ case 0x000E10: return 0x0018F1;
+ case 0x000E19: return 0x001927;
+ case 0x000E05: return 0x0018AF;
+ }
+
+ *w = 1;
+ return 0x0019AE;
+ }
+ }
+ }
+ else { /* weight > state_000E42 */
+ if (weight == state_000E44) {
+ switch (u) {
+ case 0x000E1E: return 0x001948;
+ case 0x000E10: return 0x0018F4;
+ case 0x000E08: return 0x0018C4;
+ case 0x000E01: return 0x00189A;
+ case 0x000E28: return 0x001984;
+ case 0x000E0E: return 0x0018E8;
+ case 0x000E14: return 0x00190C;
+ case 0x000E2B: return 0x001996;
+ case 0x000E27: return 0x00197E;
+ case 0x000E29: return 0x00198A;
+ case 0x000E0A: return 0x0018D0;
+ case 0x000E18: return 0x001924;
+ case 0x000E22: return 0x001960;
+ case 0x000E1D: return 0x001942;
+ case 0x000E13: return 0x001906;
+ case 0x000E09: return 0x0018CA;
+ case 0x000E06: return 0x0018B8;
+ case 0x000E17: return 0x00191E;
+ case 0x000E1C: return 0x00193C;
+ case 0x000E2C: return 0x00199C;
+ case 0x000E02: return 0x0018A0;
+ case 0x000E0F: return 0x0018EE;
+ case 0x000E12: return 0x001900;
+ case 0x000E24: return 0x00196C;
+ case 0x000E0B: return 0x0018D6;
+ case 0x000E07: return 0x0018BE;
+ case 0x000E16: return 0x001918;
+ case 0x000E20: return 0x001954;
+ case 0x000E23: return 0x001966;
+ case 0x000E1B: return 0x001936;
+ case 0x000E2D: return 0x0019A2;
+ case 0x000E03: return 0x0018A6;
+ case 0x000E1F: return 0x00194E;
+ case 0x000E25: return 0x001972;
+ case 0x000E0C: return 0x0018DC;
+ case 0x000E04: return 0x0018AC;
+ case 0x000E11: return 0x0018FA;
+ case 0x000E21: return 0x00195A;
+ case 0x000E2E: return 0x0019A8;
+ case 0x000E0D: return 0x0018E2;
+ case 0x000E15: return 0x001912;
+ case 0x000E1A: return 0x001930;
+ case 0x000E2A: return 0x001990;
+ case 0x000E26: return 0x001978;
+ case 0x000E05: return 0x0018B2;
+ case 0x000E19: return 0x00192A;
+ }
+
+ *w = 1;
+ return 0x0019B1;
+ }
+ else if (weight < state_000E44) {
+ if (weight == state_000E43) {
+ switch (u) {
+ case 0x000E02: return 0x00189F;
+ case 0x000E22: return 0x00195F;
+ case 0x000E13: return 0x001905;
+ case 0x000E25: return 0x001971;
+ case 0x000E2A: return 0x00198F;
+ case 0x000E06: return 0x0018B7;
+ case 0x000E0B: return 0x0018D5;
+ case 0x000E28: return 0x001983;
+ case 0x000E1C: return 0x00193B;
+ case 0x000E2E: return 0x0019A7;
+ case 0x000E20: return 0x001953;
+ case 0x000E0F: return 0x0018ED;
+ case 0x000E01: return 0x001899;
+ case 0x000E14: return 0x00190B;
+ case 0x000E24: return 0x00196B;
+ case 0x000E05: return 0x0018B1;
+ case 0x000E0A: return 0x0018CF;
+ case 0x000E10: return 0x0018F3;
+ case 0x000E1D: return 0x001941;
+ case 0x000E2D: return 0x0019A1;
+ case 0x000E09: return 0x0018C9;
+ case 0x000E0E: return 0x0018E7;
+ case 0x000E15: return 0x001911;
+ case 0x000E27: return 0x00197D;
+ case 0x000E2C: return 0x00199B;
+ case 0x000E04: return 0x0018AB;
+ case 0x000E18: return 0x001923;
+ case 0x000E11: return 0x0018F9;
+ case 0x000E1E: return 0x001947;
+ case 0x000E08: return 0x0018C3;
+ case 0x000E23: return 0x001965;
+ case 0x000E0D: return 0x0018E1;
+ case 0x000E1A: return 0x00192F;
+ case 0x000E16: return 0x001917;
+ case 0x000E26: return 0x001977;
+ case 0x000E2B: return 0x001995;
+ case 0x000E03: return 0x0018A5;
+ case 0x000E19: return 0x001929;
+ case 0x000E29: return 0x001989;
+ case 0x000E12: return 0x0018FF;
+ case 0x000E1F: return 0x00194D;
+ case 0x000E07: return 0x0018BD;
+ case 0x000E0C: return 0x0018DB;
+ case 0x000E1B: return 0x001935;
+ case 0x000E17: return 0x00191D;
+ case 0x000E21: return 0x001959;
+ }
+
+ *w = 1;
+ return 0x0019B0;
+ }
+ }
+ else { /* weight > state_000E44 */
+ if (weight == state_00AAB5) {
+ switch (u) {
+ case 0x00AAA8: return 0x001B68;
+ case 0x00AA9F: return 0x001B32;
+ case 0x00AA93: return 0x001AEA;
+ case 0x00AAAA: return 0x001B74;
+ case 0x00AAA7: return 0x001B62;
+ case 0x00AA82: return 0x001A84;
+ case 0x00AA8F: return 0x001AD2;
+ case 0x00AA97: return 0x001B02;
+ case 0x00AAAE: return 0x001B8C;
+ case 0x00AA9C: return 0x001B20;
+ case 0x00AAA0: return 0x001B38;
+ case 0x00AA8B: return 0x001ABA;
+ case 0x00AAA9: return 0x001B6E;
+ case 0x00AA90: return 0x001AD8;
+ case 0x00AAA4: return 0x001B50;
+ case 0x00AA85: return 0x001A96;
+ case 0x00AA94: return 0x001AF0;
+ case 0x00AAAB: return 0x001B7A;
+ case 0x00AA81: return 0x001A7E;
+ case 0x00AAA1: return 0x001B3E;
+ case 0x00AA8E: return 0x001ACC;
+ case 0x00AA98: return 0x001B08;
+ case 0x00AAAF: return 0x001B92;
+ case 0x00AA9D: return 0x001B26;
+ case 0x00AA91: return 0x001ADE;
+ case 0x00AAA5: return 0x001B56;
+ case 0x00AA8A: return 0x001AB4;
+ case 0x00AA84: return 0x001A90;
+ case 0x00AA95: return 0x001AF6;
+ case 0x00AA89: return 0x001AAE;
+ case 0x00AAAC: return 0x001B80;
+ case 0x00AA9A: return 0x001B14;
+ case 0x00AA80: return 0x001A78;
+ case 0x00AA8D: return 0x001AC6;
+ case 0x00AA99: return 0x001B0E;
+ case 0x00AA9E: return 0x001B2C;
+ case 0x00AAA2: return 0x001B44;
+ case 0x00AA87: return 0x001AA2;
+ case 0x00AA92: return 0x001AE4;
+ case 0x00AA88: return 0x001AA8;
+ case 0x00AAA6: return 0x001B5C;
+ case 0x00AA83: return 0x001A8A;
+ case 0x00AA96: return 0x001AFC;
+ case 0x00AAAD: return 0x001B86;
+ case 0x00AA9B: return 0x001B1A;
+ case 0x00AAA3: return 0x001B4A;
+ case 0x00AA8C: return 0x001AC0;
+ case 0x00AA86: return 0x001A9C;
+ }
+
+ *w = 1;
+ return 0x001B98;
+ }
+ }
+ }
+ }
+ else { /* weight > state_00AAB6 */
+ if (weight == state_000EC2) {
+ switch (u) {
+ case 0x000E82: return 0x0019C2;
+ case 0x000E9B: return 0x001A16;
+ case 0x000EDD: return 0x001A5E;
+ case 0x000EAD: return 0x001A64;
+ case 0x000E9F: return 0x001A2E;
+ case 0x000EAA: return 0x0019DA;
+ case 0x000E81: return 0x0019BC;
+ case 0x000E9C: return 0x001A1C;
+ case 0x000E94: return 0x0019F2;
+ case 0x000EDC: return 0x001A58;
+ case 0x000EAE: return 0x001A6A;
+ case 0x000EA1: return 0x001A34;
+ case 0x000E84: return 0x0019C8;
+ case 0x000EA5: return 0x001A46;
+ case 0x000EAB: return 0x001A52;
+ case 0x000E95: return 0x0019F8;
+ case 0x000EA2: return 0x001A3A;
+ case 0x000E99: return 0x001A0A;
+ case 0x000E8A: return 0x0019E0;
+ case 0x000EDF: return 0x0019E6;
+ case 0x000E88: return 0x0019D4;
+ case 0x000E9D: return 0x001A22;
+ case 0x000E87: return 0x0019CE;
+ case 0x000E96: return 0x0019FE;
+ case 0x000E8D: return 0x0019EC;
+ case 0x000E9A: return 0x001A10;
+ case 0x000EA3: return 0x001A40;
+ case 0x000EDE: return 0x0019B6;
+ case 0x000E9E: return 0x001A28;
+ case 0x000EA7: return 0x001A4C;
+ case 0x000E97: return 0x001A04;
+ }
+
+ *w = 1;
+ return 0x001A74;
+ }
+ else if (weight < state_000EC2) {
+ if (weight == state_000EC0) {
+ switch (u) {
+ case 0x000E84: return 0x0019C6;
+ case 0x000E9D: return 0x001A20;
+ case 0x000E8A: return 0x0019DE;
+ case 0x000EAB: return 0x001A50;
+ case 0x000E88: return 0x0019D2;
+ case 0x000E99: return 0x001A08;
+ case 0x000E96: return 0x0019FC;
+ case 0x000EA2: return 0x001A38;
+ case 0x000E87: return 0x0019CC;
+ case 0x000E9E: return 0x001A26;
+ case 0x000EDE: return 0x0019B4;
+ case 0x000E9A: return 0x001A0E;
+ case 0x000EA7: return 0x001A4A;
+ case 0x000E82: return 0x0019C0;
+ case 0x000E8D: return 0x0019EA;
+ case 0x000E97: return 0x001A02;
+ case 0x000EA3: return 0x001A3E;
+ case 0x000EAD: return 0x001A62;
+ case 0x000EDD: return 0x001A5C;
+ case 0x000E9F: return 0x001A2C;
+ case 0x000E94: return 0x0019F0;
+ case 0x000E9B: return 0x001A14;
+ case 0x000EAE: return 0x001A68;
+ case 0x000E81: return 0x0019BA;
+ case 0x000EAA: return 0x0019D8;
+ case 0x000EA5: return 0x001A44;
+ case 0x000EDC: return 0x001A56;
+ case 0x000E95: return 0x0019F6;
+ case 0x000E9C: return 0x001A1A;
+ case 0x000EA1: return 0x001A32;
+ case 0x000EDF: return 0x0019E4;
+ }
+
+ *w = 1;
+ return 0x001A72;
+ }
+ else if (weight < state_000EC0) {
+ if (weight == state_000EC1) {
+ switch (u) {
+ case 0x000EAD: return 0x001A63;
+ case 0x000E97: return 0x001A03;
+ case 0x000EA1: return 0x001A33;
+ case 0x000E9C: return 0x001A1B;
+ case 0x000E82: return 0x0019C1;
+ case 0x000EDE: return 0x0019B5;
+ case 0x000EA5: return 0x001A45;
+ case 0x000E87: return 0x0019CD;
+ case 0x000E96: return 0x0019FD;
+ case 0x000E9B: return 0x001A15;
+ case 0x000E99: return 0x001A09;
+ case 0x000E88: return 0x0019D3;
+ case 0x000EAB: return 0x001A51;
+ case 0x000E9F: return 0x001A2D;
+ case 0x000E84: return 0x0019C7;
+ case 0x000EDF: return 0x0019E5;
+ case 0x000EA3: return 0x001A3F;
+ case 0x000E8D: return 0x0019EB;
+ case 0x000E95: return 0x0019F7;
+ case 0x000EDC: return 0x001A57;
+ case 0x000EA7: return 0x001A4B;
+ case 0x000E9A: return 0x001A0F;
+ case 0x000EAA: return 0x0019D9;
+ case 0x000E9E: return 0x001A27;
+ case 0x000EA2: return 0x001A39;
+ case 0x000E81: return 0x0019BB;
+ case 0x000EAE: return 0x001A69;
+ case 0x000E94: return 0x0019F1;
+ case 0x000E8A: return 0x0019DF;
+ case 0x000EDD: return 0x001A5D;
+ case 0x000E9D: return 0x001A21;
+ }
+
+ *w = 1;
+ return 0x001A73;
+ }
+ }
+ else { /* weight > state_000EC0 */
+ if (weight == state_000EC3) {
+ switch (u) {
+ case 0x000E96: return 0x0019FF;
+ case 0x000EAE: return 0x001A6B;
+ case 0x000E9C: return 0x001A1D;
+ case 0x000EA1: return 0x001A35;
+ case 0x000EDE: return 0x0019B7;
+ case 0x000EA5: return 0x001A47;
+ case 0x000E84: return 0x0019C9;
+ case 0x000E95: return 0x0019F9;
+ case 0x000EAD: return 0x001A65;
+ case 0x000E9B: return 0x001A17;
+ case 0x000E99: return 0x001A0B;
+ case 0x000EDF: return 0x0019E7;
+ case 0x000E9F: return 0x001A2F;
+ case 0x000E94: return 0x0019F3;
+ case 0x000E88: return 0x0019D5;
+ case 0x000EDC: return 0x001A59;
+ case 0x000E81: return 0x0019BD;
+ case 0x000E9A: return 0x001A11;
+ case 0x000E8D: return 0x0019ED;
+ case 0x000E9E: return 0x001A29;
+ case 0x000EA3: return 0x001A41;
+ case 0x000EA7: return 0x001A4D;
+ case 0x000EAB: return 0x001A53;
+ case 0x000E82: return 0x0019C3;
+ case 0x000E97: return 0x001A05;
+ case 0x000E9D: return 0x001A23;
+ case 0x000EA2: return 0x001A3B;
+ case 0x000E87: return 0x0019CF;
+ case 0x000E8A: return 0x0019E1;
+ case 0x000EDD: return 0x001A5F;
+ case 0x000EAA: return 0x0019DB;
+ }
+
+ *w = 1;
+ return 0x001A75;
+ }
+ }
+ }
+ else { /* weight > state_000EC2 */
+ if (weight == state_001B0B) {
+ switch (u) {
+ case 0x001B35: return 0x001FCE;
+ }
+
+ *w = 1;
+ return 0x001FCD;
+ }
+ else if (weight < state_001B0B) {
+ if (weight == state_000EC4) {
+ switch (u) {
+ case 0x000EDD: return 0x001A60;
+ case 0x000E9F: return 0x001A30;
+ case 0x000EAA: return 0x0019DC;
+ case 0x000EA7: return 0x001A4E;
+ case 0x000E82: return 0x0019C4;
+ case 0x000E97: return 0x001A06;
+ case 0x000EDC: return 0x001A5A;
+ case 0x000EAE: return 0x001A6C;
+ case 0x000E9C: return 0x001A1E;
+ case 0x000E94: return 0x0019F4;
+ case 0x000EAB: return 0x001A54;
+ case 0x000E81: return 0x0019BE;
+ case 0x000EA1: return 0x001A36;
+ case 0x000EDF: return 0x0019E8;
+ case 0x000E9D: return 0x001A24;
+ case 0x000EA5: return 0x001A48;
+ case 0x000E8A: return 0x0019E2;
+ case 0x000E84: return 0x0019CA;
+ case 0x000E95: return 0x0019FA;
+ case 0x000E9A: return 0x001A12;
+ case 0x000E8D: return 0x0019EE;
+ case 0x000E99: return 0x001A0C;
+ case 0x000E9E: return 0x001A2A;
+ case 0x000EA2: return 0x001A3C;
+ case 0x000E87: return 0x0019D0;
+ case 0x000EDE: return 0x0019B8;
+ case 0x000E88: return 0x0019D6;
+ case 0x000E96: return 0x001A00;
+ case 0x000EAD: return 0x001A66;
+ case 0x000E9B: return 0x001A18;
+ case 0x000EA3: return 0x001A42;
+ }
+
+ *w = 1;
+ return 0x001A76;
+ }
+ }
+ else { /* weight > state_001B0B */
+ if (weight == state_001B11) {
+ switch (u) {
+ case 0x001B35: return 0x001FD4;
+ }
+
+ *w = 1;
+ return 0x001FD3;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/vendor/nunicode/src/libnu/gen/_tolower.c b/vendor/nunicode/src/libnu/gen/_tolower.c
new file mode 100644
index 0000000000..0e267f5386
--- /dev/null
+++ b/vendor/nunicode/src/libnu/gen/_tolower.c
@@ -0,0 +1,846 @@
+/* Automatically generated file (mph.py), 1490539881
+ *
+ * Tag : NU_TOLOWER
+ * Prime : 01000193,
+ * G size : 1304,
+ * Combined length : 5006,
+ * Encoding : UTF-8
+ */
+
+#include <stdint.h>
+
+const int16_t NU_TOLOWER_G[] = {
+ 0, 1, 0, 1, -1279, 1, 0, 1, 1, 0, 1, -1277,
+ 1, -1271, 1, -1269, 1, 0, 1, 0, -1267, 0, 1, 0,
+ 1, 1, 1, 1, 0, 1, -1265, 1, 0, -1256, 0, -1254,
+ -1238, -1236, -1220, 1, -1194, 1, 0, 1, -1160, -1153, -1147, -1143,
+ 0, 1, -1135, -1133, -1131, 1, 0, 1, 1, 1, 5, 1,
+ 1, 1, 9, 1, -1129, 3, -1117, 2, -1116, 1, -1115, 1,
+ -1112, 1, -1111, 1, -1110, 1, -1108, 1, -1106, 1, -1103, 1,
+ -1101, 1, -1090, 1, 0, 1, 0, 5, 0, 32, 0, 32,
+ 0, 1, 0, 1, 0, 1, 0, 1, -1052, 1, -1049, 1,
+ -1019, 1, -1016, 1, -1013, 3, -1012, 4, -1010, 1, -1007, 1,
+ -1005, -1000, -999, -998, -997, -996, -995, -994, 0, 3, 0, 2,
+ 0, 1, 0, 2, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 4, 0, 1, 0, 5,
+ 0, 1, 0, 4, -992, 1, -991, 4, -990, 1, -989, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, -985, -984, -982, 1, 0, -981, -980, -979,
+ 0, 1, 0, 1, 0, 1, 0, 1, -978, 2, -977, 1,
+ -976, 1, -975, 1, -974, 1, -973, 1, -972, 2, -971, 1,
+ -970, 3, -969, 2, -968, 1, -966, 1, -964, 1, -963, 1,
+ -962, 2, -961, 1, 0, -949, 0, -904, 0, -902, 0, -900,
+ 0, -898, 0, -896, 0, -894, 0, -893, 0, -892, 0, -891,
+ 0, -890, 0, -889, 0, -888, 0, -887, 0, -881, 0, -879,
+ 0, -878, 0, -877, 0, -876, 0, -875, -874, 1, -873, 1,
+ 0, 1, -872, 1, -871, 2, -870, 14, 0, 24, -869, 24,
+ -866, 1, -865, 1, -864, 1, -863, 4, 14, 1, 25, 1,
+ 29, 1, 49, 1, -862, 2, -861, 1, -860, 2, -859, 2,
+ 0, -858, 0, -856, 0, -854, 0, -853, 0, 0, 0, 0,
+ 0, 0, 0, 0, -852, -849, -848, -847, -846, -845, 0, 0,
+ 1, -844, -843, -842, -841, -840, -839, -838, -837, -836, -834, -832,
+ -831, -830, -828, -826, -824, -822, -821, -820, -819, -818, -817, -816,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -815, -814, -813, -812, -811, -810, -809, -808,
+ -807, -804, -798, -797, -796, -795, -793, -790, -788, -785, -783, -782,
+ -778, -777, -776, -775, 9, 42, 45, 46, 76, 76, 94, 97,
+ -774, 104, 125, 126, -773, -772, -770, -768, 185, 186, 191, -767,
+ 197, 208, 224, 236, 5, 6, 56, 56, 60, 60, 71, 81,
+ -766, -765, -764, -763, -762, -761, -760, -759, 31, 74, 80, 85,
+ 88, 92, 92, 92, -758, -757, -756, -754, -753, -752, -751, -750,
+ 0, 0, 0, 0, 0, 0, 0, 0, -749, -748, -747, 0,
+ -746, -745, -744, -743, 1, 1, 1, 4, 2, -742, 16, 18,
+ 0, -741, 0, 0, 0, -740, -739, 0, 0, -738, -737, -734,
+ -731, -730, 0, -728, 0, 0, 0, 0, 0, -725, 0, 0,
+ -724, -723, 0, 0, 0, 0, 0, 0, -722, 0, -721, -720,
+ -719, -718, -717, -716, -715, -714, -713, -712, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -711, 0, -710,
+ 0, -709, 0, -708, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -707, 0, 0, 0, -706, -705, -704, -703,
+ 1, -702, -701, 1, -700, 1, 1, -699, 1, 1, 1, -698,
+ 0, -697, 0, -696, 0, -695, 0, -694, 0, -693, 0, -692,
+ 0, -691, 0, -690, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -689, -688, -687, -686,
+ -685, -684, -683, -682, -681, 3, -680, 2, -679, 2, -678, -677,
+ -676, -675, -674, -673, 1, -672, -671, -670, -669, -668, -667, -666,
+ -665, -664, -663, -662, -661, -660, -659, -658, -657, -656, -655, -654,
+ -653, 8, -652, 8, -651, 40, -650, -649, -648, 4, -647, 64,
+ -646, 72, -645, 72, -644, 56, -643, 56, -642, 65, -641, 65,
+ 8, -640, -639, -638, 0, 0, 8, -637, -636, -635, -634, -633,
+ 0, -632, 0, -631, -630, -629, -628, -627, -626, -625, -624, -623,
+ -622, 64, -621, 64, -620, 64, -619, 64, -618, -617, 0, -616,
+ 0, -615, -614, -613, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -612, 0, -611,
+ 0, -610, 0, -609, 0, -608, 0, -607, 0, -606, 0, -605,
+ 0, -604, 0, -603, 0, -602, 0, -601, 0, -600, 0, -599,
+ 0, -598, 0, -597, 0, 1, 0, -596, 0, -595, 0, -594,
+ -593, 1, 0, -591, 0, 1, -589, -587, 0, 2, 0, -585,
+ 0, 4, 0, 14, 0, 19, 0, 20, 0, 16, 0, 17,
+ 0, -584, 0, -583, 0, -582, 0, -581, 0, -580, 0, -578,
+ 0, -571, 0, -569, -568, -567, -566, -565, 0, 4, -563, 4,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, -562, 0, -561, 0, 0, -560, -559, 0,
+ 0, -558, 0, -557, 0, -556, 0, -554, 0, -553, 0, -552,
+ 0, -551, 0, -550, 0, -549, 0, -548, 0, -546, 0, -544,
+ 0, -543, 0, -542, 0, 0, 0, 0, 0, -541, 0, -540,
+ 0, -539, 0, -538, 0, -537, 0, -536, 0, -535, 0, -534,
+ -533, -532, -531, -530, -529, -528, -527, -526, -525, -524, -523, -522,
+ -521, -520, -519, -518, -517, -516, -515, -514, -513, -511, -509, -507,
+ -505, -503, -501, -499, -498, -497, -495, -493, 0, 32, -491, 32,
+ 0, -489, 0, -487, 0, -485, 0, -484, 0, -481, 0, -479,
+ -478, 40, -477, 40, -476, 41, -474, 41, -472, 33, -471, 33,
+ -470, 51, -468, 53, 0, -466, 0, -464, 0, -463, 0, -462,
+ 0, -461, 0, -459, 0, -457, 0, -456, 0, -455, 0, -453,
+ 0, -452, 0, -451, 0, -450, 0, -449, 0, -447, 0, -444,
+ 0, 34, 0, 33, 0, 33, 0, 79, 0, 92, 0, 92,
+ 0, 126, 0, 167, -439, 4, -438, 4, -437, 8, -436, 8,
+ -432, 26, -428, 38, -421, 40, -419, 40, 47, 8, 73, 423,
+ 73, 76, 89, 105, 132, 241, 305, 306, 317, 318, 324, 324,
+ 244, 9, 459, 8, -416, 142, -415, 44, -412, -410, 0, -409,
+ 0, -405, -403, -395, 1, 64, 9, 65, 1, 64, 4, 64,
+ -393, 81, 128, 65, -390, 81, -389, 80, 1, 64, 1, 64,
+ 145, 76, 159, 83, 213, 84, 379, 87, 377, 107, 377, 109,
+ -388, -387, -386, -385, 0, 0, 0, -383, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 64, 2, 64, -375, 80, -371, 64,
+ -369, 80, -359, 80, 0, -357, -355, 80, -353, 14, -343, 32,
+ 0, -339, 0, 37, -335, 112, -330, 197, -327, 193, -320, 200,
+ -315, 174, 288, 34, 0, 0, -308, -303, 236, 201, 358, -285,
+ 544, 1, -254, 2, 544, 33, 548, 32, 32, 32, 32, 32,
+ 0, 17, -252, -250, 14, 1, 0, 17, 4, 1, 37, 6,
+ 9, 2, -232, 8, 21, 40, 32, -231, 39, 40, 41, -230,
+ -228, 86, -226, 1, -152, 227, -143, 6, };
+
+const size_t NU_TOLOWER_G_SIZE = sizeof(NU_TOLOWER_G) / sizeof(*NU_TOLOWER_G);
+
+/* codepoints */
+const uint32_t NU_TOLOWER_VALUES_C[] = {
+ 0x01E908, 0x001E92, 0x001E90, 0x01E90A, 0x000533, 0x001E94, 0x00054A, 0x000548,
+ 0x01E912, 0x00054C, 0x00004D, 0x000055, 0x00050C, 0x00054E, 0x00050E, 0x001E9E,
+ 0x000520, 0x001EA2, 0x01E91A, 0x000522, 0x001EA0, 0x001EA4, 0x000508, 0x001EA6,
+ 0x000512, 0x000510, 0x000056, 0x000057, 0x001E8C, 0x00004C, 0x001E8E, 0x000516,
+ 0x01E90C, 0x001EB0, 0x000532, 0x001EB2, 0x000059, 0x001EB4, 0x000058, 0x001EB6,
+ 0x000541, 0x001EB8, 0x000543, 0x001EBA, 0x000518, 0x001EBC, 0x00051A, 0x001EBE,
+ 0x001EC4, 0x001EC0, 0x00005A, 0x001EC2, 0x01E91B, 0x000054, 0x01E910, 0x001EC6,
+ 0x001ECC, 0x000555, 0x000553, 0x001ECA, 0x01E914, 0x001EC8, 0x01E916, 0x001ECE,
+ 0x000551, 0x001ED2, 0x001ED0, 0x000514, 0x01E91D, 0x000534, 0x001ED4, 0x001ED6,
+ 0x00051E, 0x001ED8, 0x01041B, 0x001EDA, 0x00004A, 0x001EDC, 0x00004B, 0x001EDE,
+ 0x01E919, 0x001EE0, 0x01E91E, 0x001EE2, 0x000535, 0x001EE4, 0x01E91F, 0x001EE6,
+ 0x00FF28, 0x001EE8, 0x000053, 0x00FF2A, 0x00FF2C, 0x00FF2D, 0x00FF2E, 0x00FF2F,
+ 0x000531, 0x01E920, 0x000536, 0x001EF2, 0x001EF0, 0x001EF4, 0x000537, 0x001EF6,
+ 0x01041A, 0x001EF8, 0x00FF38, 0x001EFA, 0x010419, 0x001EFC, 0x010418, 0x001EFE,
+ 0x000048, 0x000049, 0x00004E, 0x00004F, 0x010423, 0x01E91C, 0x00FF24, 0x00FF26,
+ 0x000052, 0x0118A2, 0x0118A0, 0x01041D, 0x000051, 0x0118A4, 0x000050, 0x0118A6,
+ 0x01E90E, 0x0118A8, 0x000047, 0x0118AA, 0x0118AE, 0x0118AC, 0x00054B, 0x01E903,
+ 0x0118B2, 0x0118B0, 0x01041E, 0x01041F, 0x001F39, 0x0118B4, 0x001F2D, 0x0118B6,
+ 0x000526, 0x0118B8, 0x00FF32, 0x0118BA, 0x0118BE, 0x0118BC, 0x000046, 0x001F2F,
+ 0x001F08, 0x001F28, 0x001F2C, 0x001F0A, 0x001F0C, 0x001F0D, 0x001F0E, 0x001F0F,
+ 0x010422, 0x01E921, 0x010402, 0x00051C, 0x001F3C, 0x000045, 0x001F3F, 0x00053B,
+ 0x000044, 0x010421, 0x001F18, 0x001F3A, 0x001F3E, 0x010420, 0x001F38, 0x001F3B,
+ 0x010424, 0x010425, 0x010426, 0x00053A, 0x010401, 0x01041C, 0x010400, 0x010427,
+ 0x001F49, 0x001F48, 0x001F4B, 0x001F4A, 0x0104B5, 0x001F4C, 0x000547, 0x001FBB,
+ 0x0000C4, 0x0000C0, 0x000545, 0x0000C2, 0x0000DC, 0x0000CB, 0x0000DE, 0x0000C6,
+ 0x001F59, 0x0000C8, 0x001F5B, 0x0000CA, 0x001F5D, 0x0000CC, 0x001F5F, 0x0000CE,
+ 0x0000C9, 0x0000D0, 0x0000CF, 0x0000D2, 0x001F6D, 0x0000D4, 0x0000D8, 0x0000D6,
+ 0x0000DA, 0x001F68, 0x001F6B, 0x001F6A, 0x001F69, 0x001F6C, 0x001F6F, 0x001F6E,
+ 0x0104B1, 0x001F29, 0x0104B7, 0x001F2B, 0x00FF3A, 0x0004AC, 0x0004A8, 0x001F3D,
+ 0x01040A, 0x0104B0, 0x01040B, 0x0104B2, 0x001F2A, 0x0104B4, 0x010409, 0x0104B6,
+ 0x0104BA, 0x0104B8, 0x001F8A, 0x01E902, 0x0104BE, 0x0104B3, 0x0104BC, 0x000191,
+ 0x000042, 0x0004B8, 0x000043, 0x000181, 0x0000CD, 0x00FF25, 0x000041, 0x01E90B,
+ 0x001FBC, 0x000100, 0x01040F, 0x000102, 0x001F9C, 0x000104, 0x001F9E, 0x000106,
+ 0x001FD8, 0x000108, 0x001FDA, 0x00010A, 0x001F98, 0x00010C, 0x001F9A, 0x00010E,
+ 0x001FA9, 0x000110, 0x0024BB, 0x000112, 0x001F8B, 0x000114, 0x01040E, 0x000116,
+ 0x01040C, 0x001FAD, 0x001FAB, 0x00011A, 0x000190, 0x000118, 0x001FAF, 0x00FF23,
+ 0x001FB8, 0x000122, 0x000120, 0x001FBA, 0x001F1A, 0x01040D, 0x000124, 0x000126,
+ 0x001FF8, 0x000128, 0x001FFA, 0x00012A, 0x001FFC, 0x00012C, 0x001F1C, 0x00012E,
+ 0x001F89, 0x000132, 0x001F8E, 0x001F1D, 0x000130, 0x000134, 0x001F8F, 0x000136,
+ 0x001FE8, 0x001FEC, 0x001F1B, 0x00FF22, 0x00011C, 0x001F2E, 0x00011E, 0x00FF35,
+ 0x0010B0, 0x0010B1, 0x0010B6, 0x0010B7, 0x001F8D, 0x00FF30, 0x00FF37, 0x00FF36,
+ 0x001FD9, 0x00FF31, 0x001FDB, 0x00014A, 0x00FF34, 0x00014C, 0x00FF33, 0x00014E,
+ 0x000154, 0x000150, 0x000496, 0x000152, 0x001FEA, 0x001F8C, 0x001FE9, 0x000156,
+ 0x00015C, 0x001FA8, 0x001FAA, 0x00015A, 0x001FAC, 0x000158, 0x001FAE, 0x00015E,
+ 0x001FEB, 0x000160, 0x002C2D, 0x000162, 0x002C2E, 0x000164, 0x002C29, 0x000166,
+ 0x00016A, 0x000168, 0x001FFB, 0x001FF9, 0x0010B2, 0x00016C, 0x0010B3, 0x00016E,
+ 0x002C2B, 0x000170, 0x002C25, 0x000172, 0x0010A3, 0x000174, 0x002C27, 0x000176,
+ 0x0010C1, 0x000178, 0x0010C3, 0x0010C2, 0x0010C0, 0x0010C7, 0x001FCC, 0x000193,
+ 0x001FC8, 0x001FC9, 0x001FCA, 0x001FCB, 0x002C1D, 0x002C1F, 0x00018F, 0x000186,
+ 0x002C1B, 0x000187, 0x00052C, 0x00018A, 0x00018E, 0x0010C5, 0x0010C4, 0x00018B,
+ 0x0001B7, 0x0001B1, 0x002CED, 0x000182, 0x00052E, 0x000184, 0x000194, 0x000196,
+ 0x000528, 0x00052A, 0x0001B2, 0x002CEB, 0x0001B5, 0x0010B4, 0x01E90D, 0x01E90F,
+ 0x0010A2, 0x0001A0, 0x01E915, 0x0001A2, 0x01E917, 0x0001A4, 0x0001B3, 0x0001A6,
+ 0x0001A9, 0x0010A1, 0x0010B5, 0x01E911, 0x000189, 0x0010A0, 0x0001AF, 0x01E913,
+ 0x0010A4, 0x0010A5, 0x0010A6, 0x001F9D, 0x001F9F, 0x001F99, 0x001F9B, 0x0010A7,
+ 0x000198, 0x0001B8, 0x0001BC, 0x002CAC, 0x00019C, 0x00019D, 0x002CAE, 0x00019F,
+ 0x002CA8, 0x002CAA, 0x002CA4, 0x002CA6, 0x002CA0, 0x0001C4, 0x002CA2, 0x002CBC,
+ 0x002CBE, 0x0001C8, 0x002CB8, 0x0001CA, 0x002CBA, 0x002CB4, 0x002CB6, 0x002CB0,
+ 0x0001D1, 0x002CB2, 0x0001D3, 0x010CAD, 0x0001D5, 0x010CAF, 0x010CA9, 0x010CAB,
+ 0x0001D9, 0x010CA5, 0x0001DB, 0x010CA7, 0x010CA1, 0x010CA3, 0x002C9C, 0x0001DE,
+ 0x002C9E, 0x0001E2, 0x0001E0, 0x002C98, 0x002C9A, 0x0001E4, 0x002C94, 0x0001E6,
+ 0x002C96, 0x0001E8, 0x010CB1, 0x0001EA, 0x010C8C, 0x0001EC, 0x010C8D, 0x0001EE,
+ 0x010C8E, 0x010C8F, 0x010C88, 0x0001F2, 0x010C89, 0x0001F4, 0x010C8A, 0x0001F6,
+ 0x010C8B, 0x0001F8, 0x010C84, 0x0001FA, 0x010C85, 0x0001FC, 0x010C86, 0x0001FE,
+ 0x010C87, 0x010C80, 0x010C81, 0x010C82, 0x010C83, 0x010C9C, 0x010C9D, 0x010C9E,
+ 0x010C9F, 0x010C98, 0x010C99, 0x010C9A, 0x010C9B, 0x010C94, 0x010C95, 0x010C96,
+ 0x010C97, 0x010C90, 0x010C91, 0x010C92, 0x010C93, 0x00A68C, 0x00A68E, 0x00A688,
+ 0x00A68A, 0x00A684, 0x00A686, 0x00A680, 0x00A682, 0x00A698, 0x00A69A, 0x00A694,
+ 0x000222, 0x00A696, 0x000226, 0x00A690, 0x00A692, 0x00A76C, 0x00A76E, 0x00A768,
+ 0x00A76A, 0x00A764, 0x000224, 0x00A766, 0x00A760, 0x00A762, 0x00A77D, 0x00A77E,
+ 0x00A779, 0x00A77B, 0x000245, 0x000232, 0x00A740, 0x000241, 0x00A742, 0x000243,
+ 0x00A75C, 0x00022A, 0x00A75E, 0x00023A, 0x000228, 0x00022C, 0x00022E, 0x00023E,
+ 0x000244, 0x00A758, 0x000246, 0x00A75A, 0x00A754, 0x00A756, 0x00A750, 0x00A752,
+ 0x000220, 0x000248, 0x00A73C, 0x00024A, 0x00023D, 0x00024C, 0x00A738, 0x00024E,
+ 0x00023B, 0x00A734, 0x00A736, 0x000230, 0x00020C, 0x00020E, 0x000208, 0x00020A,
+ 0x000204, 0x000206, 0x000200, 0x000202, 0x00021C, 0x00021E, 0x000218, 0x00021A,
+ 0x000214, 0x000216, 0x000210, 0x000212, 0x00A7AC, 0x00A7AD, 0x00A7AE, 0x00A7A8,
+ 0x00A7AA, 0x00A7AB, 0x0013ED, 0x0013EF, 0x0013E9, 0x0013EB, 0x0013E4, 0x0013E5,
+ 0x0013E6, 0x0013E7, 0x0013E0, 0x0013E1, 0x0013E2, 0x0013E3, 0x00A7B4, 0x00A7B6,
+ 0x00A7B0, 0x00A7B1, 0x00A7B2, 0x00A7B3, 0x0013F4, 0x0013F0, 0x0013F1, 0x0013F2,
+ 0x0013CD, 0x0013CF, 0x0013C9, 0x0013CB, 0x0013C5, 0x0013C7, 0x0013C1, 0x0013C3,
+ 0x0013DC, 0x0013DD, 0x0013DF, 0x0013D9, 0x0013DB, 0x0013D4, 0x0013D5, 0x0013D6,
+ 0x0013D7, 0x0013D0, 0x0013D1, 0x0013D2, 0x0013D3, 0x0013AC, 0x0013AD, 0x0013AE,
+ 0x0013AF, 0x0013A8, 0x0013A9, 0x0013AA, 0x0013AB, 0x0013A4, 0x0013A5, 0x0013A6,
+ 0x0013A0, 0x0013A1, 0x0013A2, 0x0013A3, 0x0013BC, 0x0013BD, 0x0013BF, 0x0013B9,
+ 0x0013BB, 0x0013B4, 0x0013B5, 0x0013B6, 0x0013B7, 0x0013B0, 0x0013B1, 0x0013B2,
+ 0x0013B3, 0x0003EC, 0x0003EE, 0x0003E8, 0x0003EA, 0x0003E4, 0x0003E6, 0x0003E0,
+ 0x0003E2, 0x00216C, 0x002168, 0x00216B, 0x002165, 0x002166, 0x002160, 0x002161,
+ 0x002162, 0x002163, 0x0003CF, 0x0003DC, 0x0003DE, 0x0003D8, 0x0003DA, 0x0003A8,
+ 0x0003A9, 0x0003AA, 0x0003AB, 0x0003A4, 0x0003A5, 0x0003A6, 0x0003A7, 0x0003A0,
+ 0x0003A1, 0x0003A3, 0x00212A, 0x00212B, 0x002126, 0x002164, 0x002167, 0x00038C,
+ 0x002169, 0x00038E, 0x00038F, 0x00216A, 0x00216D, 0x000388, 0x00216F, 0x00216E,
+ 0x000389, 0x00038A, 0x0010CD, 0x000386, 0x002132, 0x00039E, 0x000394, 0x000395,
+ 0x000396, 0x000397, 0x000391, 0x000392, 0x000393, 0x0010AC, 0x0010AD, 0x0010AE,
+ 0x0010AF, 0x0010A8, 0x002183, 0x0010A9, 0x0010AA, 0x0010AB, 0x0010BC, 0x0010BD,
+ 0x0010BE, 0x0010BF, 0x0010B8, 0x0010B9, 0x0010BA, 0x0010BB, 0x010408, 0x010404,
+ 0x00A640, 0x010405, 0x00A642, 0x010406, 0x010407, 0x010403, 0x010414, 0x010415,
+ 0x010416, 0x010417, 0x00A646, 0x00A65A, 0x00A65C, 0x010410, 0x010411, 0x00A65E,
+ 0x010412, 0x00A650, 0x00A652, 0x010413, 0x00A654, 0x0024CC, 0x00A656, 0x00A644,
+ 0x0024CD, 0x00A658, 0x0024CE, 0x0024CF, 0x0024C8, 0x0024C9, 0x00A64A, 0x00A648,
+ 0x00A660, 0x00A64C, 0x00A662, 0x0024CA, 0x00A664, 0x00A64E, 0x0024CB, 0x0024C4,
+ 0x0024C5, 0x0024C6, 0x0024C7, 0x0024C0, 0x0024C1, 0x0024C2, 0x0024C3, 0x0104CC,
+ 0x0104CD, 0x0104CE, 0x0104CF, 0x0104C8, 0x0104C9, 0x0104CA, 0x00A666, 0x0104CB,
+ 0x00A668, 0x0104C4, 0x00A66A, 0x0104C5, 0x00A66C, 0x0104C6, 0x0104C7, 0x0104C0,
+ 0x002C01, 0x0104C1, 0x002C03, 0x0104C2, 0x0104C3, 0x0024BC, 0x0024BD, 0x0024BE,
+ 0x0024BF, 0x0024B8, 0x0024B9, 0x0024BA, 0x0024B6, 0x0024B7, 0x0104D0, 0x0104D1,
+ 0x0104D2, 0x002C15, 0x002C13, 0x0104D3, 0x001E6C, 0x001E6E, 0x002C17, 0x001E68,
+ 0x002C11, 0x001E6A, 0x0104BD, 0x0104BF, 0x0104B9, 0x0104BB, 0x0000C5, 0x0000C7,
+ 0x0000C1, 0x0000C3, 0x002C23, 0x002C21, 0x0000DD, 0x0000D9, 0x0000DB, 0x0000D5,
+ 0x0000D1, 0x0000D3, 0x001E5C, 0x001E5E, 0x001E58, 0x001E5A, 0x001E54, 0x00FF27,
+ 0x001E56, 0x000372, 0x000370, 0x00FF2B, 0x000376, 0x00FF29, 0x001E50, 0x001E52,
+ 0x001E2C, 0x001E2E, 0x001E28, 0x001E2A, 0x001E24, 0x001E26, 0x00037F, 0x001E20,
+ 0x002C00, 0x001E22, 0x002C02, 0x001E3C, 0x002C6D, 0x001E3E, 0x002C6E, 0x001E38,
+ 0x002C6F, 0x002C69, 0x002C06, 0x002C1A, 0x002C1C, 0x00039D, 0x00039C, 0x002C1E,
+ 0x002C70, 0x002C10, 0x002C12, 0x002C72, 0x002C14, 0x002C75, 0x002C16, 0x002C04,
+ 0x000399, 0x002C18, 0x00039B, 0x00039A, 0x000398, 0x00039F, 0x002C0A, 0x002C08,
+ 0x002C20, 0x002C0C, 0x002C22, 0x002C62, 0x002C24, 0x002C0E, 0x002C60, 0x002C63,
+ 0x010CA0, 0x010CA8, 0x010CA2, 0x010CAA, 0x002C64, 0x010CA4, 0x002C67, 0x010CA6,
+ 0x010CB0, 0x002C7F, 0x010CB2, 0x001F0B, 0x001E3A, 0x001F09, 0x002C26, 0x000197,
+ 0x002C28, 0x010CAC, 0x002C2A, 0x002CDC, 0x002C2C, 0x010CAE, 0x002C6B, 0x002C7E,
+ 0x0118AD, 0x0118AF, 0x0118A9, 0x0118AB, 0x002CD8, 0x0118A5, 0x002CDA, 0x0118A7,
+ 0x0118A1, 0x0118A3, 0x0118BD, 0x0118BF, 0x0118B9, 0x0118BB, 0x0118B5, 0x0118B7,
+ 0x0118B1, 0x0118B3, 0x001EEC, 0x00017D, 0x001EEE, 0x000179, 0x002C07, 0x001EEA,
+ 0x00017B, 0x002C19, 0x002C05, 0x002CD4, 0x000145, 0x000147, 0x000141, 0x000143,
+ 0x002CDE, 0x001EAC, 0x00013D, 0x001EAE, 0x00013F, 0x001EA8, 0x000139, 0x001EAA,
+ 0x002C80, 0x002C88, 0x002C82, 0x002C8A, 0x00013B, 0x002C84, 0x00042D, 0x002C86,
+ 0x002C90, 0x00042F, 0x002C92, 0x000429, 0x00042B, 0x0003F4, 0x0003F7, 0x000425,
+ 0x0003F9, 0x002C8C, 0x000427, 0x0003FA, 0x0003FD, 0x002C8E, 0x0003FF, 0x0003FE,
+ 0x00053E, 0x000400, 0x00053F, 0x000402, 0x002CC0, 0x000404, 0x002CC2, 0x000406,
+ 0x000539, 0x000408, 0x000538, 0x00040A, 0x002CC4, 0x00040C, 0x002CC6, 0x00040E,
+ 0x002CCA, 0x000410, 0x000413, 0x000412, 0x000411, 0x000414, 0x000417, 0x000416,
+ 0x000421, 0x00041A, 0x000418, 0x000423, 0x000415, 0x00041C, 0x002C0B, 0x00041E,
+ 0x00A722, 0x000420, 0x00A726, 0x000422, 0x002CCC, 0x000424, 0x002CCE, 0x000426,
+ 0x002CE0, 0x00042A, 0x00A724, 0x002CE2, 0x000428, 0x00042C, 0x002CC8, 0x00042E,
+ 0x002CD2, 0x002CD0, 0x000549, 0x00A732, 0x00054D, 0x0004D6, 0x00054F, 0x002CD6,
+ 0x0013C0, 0x00A72A, 0x002CF2, 0x00A73A, 0x00A728, 0x00A72C, 0x00A72E, 0x00A73E,
+ 0x00A744, 0x00040D, 0x00A746, 0x00048A, 0x0013C4, 0x0013CC, 0x0013C6, 0x0013CE,
+ 0x01E901, 0x00A748, 0x01E900, 0x00A74A, 0x00040F, 0x00A74C, 0x000409, 0x00A74E,
+ 0x01E906, 0x00040B, 0x01E907, 0x000405, 0x00049C, 0x000407, 0x000401, 0x000403,
+ 0x01E904, 0x01E905, 0x00041D, 0x00041F, 0x000419, 0x000498, 0x0013A7, 0x00049E,
+ 0x0013E8, 0x000460, 0x0013EA, 0x000462, 0x0013EC, 0x000464, 0x0013EE, 0x000466,
+ 0x00041B, 0x000468, 0x0001F7, 0x00046A, 0x0004E8, 0x00046C, 0x0001F1, 0x00046E,
+ 0x000474, 0x0013BA, 0x0013B8, 0x000472, 0x0013BE, 0x000470, 0x0004E4, 0x000476,
+ 0x00053C, 0x00053D, 0x0001CD, 0x00047A, 0x000478, 0x00047C, 0x0013C2, 0x00047E,
+ 0x0004E6, 0x00FF39, 0x0004AA, 0x00A78B, 0x0004D2, 0x00A78D, 0x0004AE, 0x0001CF,
+ 0x0013D8, 0x001E00, 0x0013DA, 0x001E02, 0x001E06, 0x001E04, 0x00048C, 0x00048E,
+ 0x0004B0, 0x001E0A, 0x001E08, 0x0004B2, 0x0004B4, 0x001E0C, 0x0004B6, 0x001E0E,
+ 0x00A790, 0x001E10, 0x00A792, 0x001E12, 0x000492, 0x001E14, 0x00A79A, 0x001E16,
+ 0x001E1A, 0x001E18, 0x000480, 0x0004A2, 0x0004A6, 0x001E1C, 0x0004A0, 0x001E1E,
+ 0x0013C8, 0x0001CB, 0x0013CA, 0x0004BA, 0x0004A4, 0x0004BC, 0x0013DE, 0x00FF21,
+ 0x000490, 0x000494, 0x002C09, 0x0013F3, 0x002C0D, 0x0013F5, 0x002C0F, 0x001F88,
+ 0x00A780, 0x001E30, 0x00A782, 0x001E32, 0x001E36, 0x001E34, 0x00A796, 0x0004BE,
+ 0x0004C1, 0x001F19, 0x0004C3, 0x0001C5, 0x0004C5, 0x00A784, 0x0004C7, 0x00A786,
+ 0x0004C9, 0x001E40, 0x0004CB, 0x001E42, 0x0004CD, 0x001E44, 0x001E48, 0x001E46,
+ 0x001E4A, 0x0004D0, 0x0004D4, 0x0004FE, 0x00A79C, 0x0001C7, 0x00A79E, 0x01E918,
+ 0x00A798, 0x0004D8, 0x01E909, 0x0004DA, 0x001E4C, 0x0004DC, 0x001E4E, 0x0004DE,
+ 0x00A7A0, 0x0004E0, 0x00A7A2, 0x0004E2, 0x00A7A4, 0x0004F8, 0x00A7A6, 0x0004FA,
+ 0x001E62, 0x001E60, 0x00049A, 0x0004EA, 0x001E66, 0x0004EC, 0x001E64, 0x0004EE,
+ 0x001F4D, 0x0004F0, 0x0001D7, 0x0004F2, 0x0001AC, 0x0004F4, 0x0001AE, 0x0004F6,
+ 0x001E74, 0x001E70, 0x001FB9, 0x001E72, 0x0004C0, 0x0004FC, 0x0001A7, 0x001E76,
+ 0x000540, 0x001E78, 0x000542, 0x001E7A, 0x000500, 0x001E7C, 0x000502, 0x001E7E,
+ 0x000524, 0x001E80, 0x000546, 0x001E82, 0x000504, 0x001E84, 0x000506, 0x001E86,
+ 0x00050A, 0x000550, 0x000552, 0x001E8A, 0x000554, 0x001E88, 0x000556, 0x000544,
+};
+
+/* indexes */
+const uint16_t NU_TOLOWER_VALUES_I[] = {
+ 0x0BC6, 0x0C3E, 0x0B9A, 0x0BD0, 0x04FB, 0x0C4C, 0x0540, 0x053A, 0x0BF8, 0x0546,
+ 0x0019, 0x0029, 0x04BF, 0x054C, 0x04C2, 0x0C50, 0x04DD, 0x0C57, 0x0C20, 0x04E0,
+ 0x0C53, 0x0C5B, 0x04B9, 0x0C5F, 0x04C8, 0x04C5, 0x002B, 0x002D, 0x0B92, 0x0017,
+ 0x0B96, 0x04CE, 0x0BDA, 0x0C73, 0x04F8, 0x0C77, 0x0031, 0x0C7B, 0x002F, 0x0C7F,
+ 0x0525, 0x0C83, 0x052B, 0x0C87, 0x04D1, 0x0C8B, 0x04D4, 0x0C8F, 0x0C9B, 0x0C93,
+ 0x0033, 0x0C97, 0x0C25, 0x0027, 0x0BEE, 0x0C9F, 0x0CAB, 0x0561, 0x055B, 0x0CA7,
+ 0x0C02, 0x0CA3, 0x0C0C, 0x0CAF, 0x0555, 0x0CB7, 0x0CB3, 0x04CB, 0x0C2F, 0x04FE,
+ 0x0CBB, 0x0CBF, 0x04DA, 0x0CC3, 0x05EE, 0x0CC7, 0x0013, 0x0CCB, 0x0015, 0x0CCF,
+ 0x0C1B, 0x0CD3, 0x0C34, 0x0CD7, 0x0501, 0x0CDB, 0x0C39, 0x0CDF, 0x12D2, 0x0CE3,
+ 0x0025, 0x12DA, 0x12E2, 0x12E6, 0x12EA, 0x12EE, 0x04F5, 0x0C42, 0x0504, 0x0CF7,
+ 0x0CF3, 0x0CFB, 0x0507, 0x0CFF, 0x05E9, 0x0D03, 0x1312, 0x0D07, 0x05E4, 0x0D0B,
+ 0x05DF, 0x0D0F, 0x000F, 0x0011, 0x001B, 0x001D, 0x0616, 0x0C2A, 0x12C2, 0x12CA,
+ 0x0023, 0x088C, 0x0882, 0x05F8, 0x0021, 0x0896, 0x001F, 0x08A0, 0x0BE4, 0x08AA,
+ 0x000D, 0x08B4, 0x08C8, 0x08BE, 0x0543, 0x0BAD, 0x08DC, 0x08D2, 0x05FD, 0x0602,
+ 0x0D6F, 0x08E6, 0x0D5F, 0x08F0, 0x04E6, 0x08FA, 0x12FA, 0x0904, 0x0918, 0x090E,
+ 0x000B, 0x0D67, 0x0D13, 0x0D4B, 0x0D5B, 0x0D1B, 0x0D23, 0x0D27, 0x0D2B, 0x0D2F,
+ 0x0611, 0x0C47, 0x0571, 0x04D7, 0x0D7B, 0x0009, 0x0D87, 0x0513, 0x0007, 0x060C,
+ 0x0D33, 0x0D73, 0x0D83, 0x0607, 0x0D6B, 0x0D77, 0x061B, 0x0620, 0x0625, 0x0510,
+ 0x056C, 0x05F3, 0x0567, 0x062A, 0x0D8F, 0x0D8B, 0x0D97, 0x0D93, 0x0648, 0x0D9B,
+ 0x0537, 0x0E3F, 0x0041, 0x0035, 0x0531, 0x003B, 0x0086, 0x0056, 0x008C, 0x0047,
+ 0x0DA3, 0x004D, 0x0DA7, 0x0053, 0x0DAB, 0x0059, 0x0DAF, 0x005F, 0x0050, 0x0065,
+ 0x0062, 0x006B, 0x0DC7, 0x0071, 0x007A, 0x0077, 0x0080, 0x0DB3, 0x0DBF, 0x0DBB,
+ 0x0DB7, 0x0DC3, 0x0DCF, 0x0DCB, 0x0634, 0x0D4F, 0x0652, 0x0D57, 0x131A, 0x042F,
+ 0x0429, 0x0D7F, 0x0599, 0x062F, 0x059E, 0x0639, 0x0D53, 0x0643, 0x0594, 0x064D,
+ 0x0661, 0x0657, 0x132A, 0x0BA8, 0x0675, 0x063E, 0x066B, 0x016C, 0x0003, 0x0441,
+ 0x0005, 0x014B, 0x005C, 0x12C6, 0x0001, 0x0BD5, 0x1382, 0x008F, 0x05B2, 0x0092,
+ 0x1352, 0x0095, 0x135A, 0x0098, 0x0E5B, 0x009B, 0x0E63, 0x009E, 0x1342, 0x00A1,
+ 0x134A, 0x00A4, 0x1366, 0x00A7, 0x0EF7, 0x00AA, 0x132E, 0x00AD, 0x05AD, 0x00B0,
+ 0x05A3, 0x1376, 0x136E, 0x00B6, 0x0169, 0x00B3, 0x137E, 0x12BE, 0x0E33, 0x00C2,
+ 0x00BF, 0x0E3B, 0x0D3B, 0x05A8, 0x00C5, 0x00C8, 0x0E7F, 0x00CB, 0x0E87, 0x00CE,
+ 0x138A, 0x00D1, 0x0D43, 0x00D4, 0x1326, 0x00D9, 0x133A, 0x0D47, 0x131E, 0x00DC,
+ 0x133E, 0x00DF, 0x0E6B, 0x0E7B, 0x0D3F, 0x12BA, 0x00B9, 0x0D63, 0x00BC, 0x1306,
+ 0x0723, 0x0727, 0x073B, 0x073F, 0x1336, 0x12F2, 0x130E, 0x130A, 0x0E5F, 0x12F6,
+ 0x0E67, 0x00FA, 0x1302, 0x00FD, 0x12FE, 0x0100, 0x0109, 0x0103, 0x040E, 0x0106,
+ 0x0E73, 0x1332, 0x0E6F, 0x010C, 0x0115, 0x1362, 0x136A, 0x0112, 0x1372, 0x010F,
+ 0x137A, 0x0118, 0x0E77, 0x011B, 0x0FFF, 0x011E, 0x1003, 0x0121, 0x0FEF, 0x0124,
+ 0x012A, 0x0127, 0x0E8B, 0x0E83, 0x072B, 0x012D, 0x072F, 0x0130, 0x0FF7, 0x0133,
+ 0x0FDF, 0x0136, 0x06EF, 0x0139, 0x0FE7, 0x013C, 0x0767, 0x013F, 0x076F, 0x076B,
+ 0x0763, 0x077B, 0x1386, 0x016F, 0x0E47, 0x0E4B, 0x0E4F, 0x0E53, 0x0FBF, 0x0FC7,
+ 0x0166, 0x0154, 0x0FB7, 0x0157, 0x04EF, 0x015D, 0x0163, 0x0777, 0x0773, 0x0160,
+ 0x01AE, 0x01A2, 0x1107, 0x014E, 0x04F2, 0x0151, 0x0172, 0x0175, 0x04E9, 0x04EC,
+ 0x01A5, 0x1103, 0x01AB, 0x0733, 0x0BDF, 0x0BE9, 0x06EB, 0x0187, 0x0C07, 0x018A,
+ 0x0C11, 0x018D, 0x01A8, 0x0190, 0x0196, 0x06E7, 0x0737, 0x0BF3, 0x015A, 0x06E3,
+ 0x019F, 0x0BFD, 0x06F3, 0x06F7, 0x06FB, 0x1356, 0x135E, 0x1346, 0x134E, 0x06FF,
+ 0x017B, 0x01B1, 0x01B4, 0x1093, 0x017E, 0x0181, 0x1097, 0x0184, 0x108B, 0x108F,
+ 0x1083, 0x1087, 0x107B, 0x01B7, 0x107F, 0x10B3, 0x10B7, 0x01C0, 0x10AB, 0x01C3,
+ 0x10AF, 0x10A3, 0x10A7, 0x109B, 0x01CF, 0x109F, 0x01D2, 0x0860, 0x01D5, 0x086A,
+ 0x084C, 0x0856, 0x01DB, 0x0838, 0x01DE, 0x0842, 0x0824, 0x082E, 0x1073, 0x01E1,
+ 0x1077, 0x01E7, 0x01E4, 0x106B, 0x106F, 0x01EA, 0x1063, 0x01ED, 0x1067, 0x01F0,
+ 0x0874, 0x01F3, 0x07BB, 0x01F6, 0x07C0, 0x01F9, 0x07C5, 0x07CA, 0x07A7, 0x01FF,
+ 0x07AC, 0x0202, 0x07B1, 0x0205, 0x07B6, 0x020B, 0x0793, 0x020E, 0x0798, 0x0211,
+ 0x079D, 0x0214, 0x07A2, 0x077F, 0x0784, 0x0789, 0x078E, 0x080B, 0x0810, 0x0815,
+ 0x081A, 0x07F7, 0x07FC, 0x0801, 0x0806, 0x07E3, 0x07E8, 0x07ED, 0x07F2, 0x07CF,
+ 0x07D4, 0x07D9, 0x07DE, 0x1183, 0x1187, 0x117B, 0x117F, 0x1173, 0x1177, 0x116B,
+ 0x116F, 0x119B, 0x119F, 0x1193, 0x024A, 0x1197, 0x0250, 0x118B, 0x118F, 0x1233,
+ 0x1237, 0x122B, 0x122F, 0x1223, 0x024D, 0x1227, 0x121B, 0x121F, 0x1243, 0x1247,
+ 0x123B, 0x123F, 0x027C, 0x0262, 0x11DB, 0x0273, 0x11DF, 0x0276, 0x1213, 0x0256,
+ 0x1217, 0x0265, 0x0253, 0x0259, 0x025C, 0x026F, 0x0279, 0x120B, 0x027F, 0x120F,
+ 0x1203, 0x1207, 0x11FB, 0x11FF, 0x0247, 0x0282, 0x11D3, 0x0285, 0x026C, 0x0288,
+ 0x11CB, 0x028B, 0x0269, 0x11C3, 0x11C7, 0x025F, 0x0229, 0x022C, 0x0223, 0x0226,
+ 0x021D, 0x0220, 0x0217, 0x021A, 0x0241, 0x0244, 0x023B, 0x023E, 0x0235, 0x0238,
+ 0x022F, 0x0232, 0x1298, 0x129B, 0x129E, 0x128E, 0x1292, 0x1295, 0x0A56, 0x0A5E,
+ 0x0A46, 0x0A4E, 0x0A32, 0x0A36, 0x0A3A, 0x0A3E, 0x0A22, 0x0A26, 0x0A2A, 0x0A2E,
+ 0x12AE, 0x12B2, 0x12A1, 0x12A4, 0x12A7, 0x12AA, 0x0A72, 0x0A62, 0x0A66, 0x0A6A,
+ 0x09D6, 0x09DE, 0x09C6, 0x09CE, 0x09B6, 0x09BE, 0x09A6, 0x09AE, 0x0A12, 0x0A16,
+ 0x0A1E, 0x0A06, 0x0A0E, 0x09F2, 0x09F6, 0x09FA, 0x09FE, 0x09E2, 0x09E6, 0x09EA,
+ 0x09EE, 0x0952, 0x0956, 0x095A, 0x095E, 0x0942, 0x0946, 0x094A, 0x094E, 0x0932,
+ 0x0936, 0x093A, 0x0922, 0x0926, 0x092A, 0x092E, 0x0992, 0x0996, 0x099E, 0x0986,
+ 0x098E, 0x0972, 0x0976, 0x097A, 0x097E, 0x0962, 0x0966, 0x096A, 0x096E, 0x031E,
+ 0x0321, 0x0318, 0x031B, 0x0312, 0x0315, 0x030C, 0x030F, 0x0ECF, 0x0EBF, 0x0ECB,
+ 0x0EB3, 0x0EB7, 0x0E9F, 0x0EA3, 0x0EA7, 0x0EAB, 0x02FD, 0x0306, 0x0309, 0x0300,
+ 0x0303, 0x02F1, 0x02F4, 0x02F7, 0x02FA, 0x02E5, 0x02E8, 0x02EB, 0x02EE, 0x02DC,
+ 0x02DF, 0x02E2, 0x0E96, 0x0E98, 0x0E93, 0x0EAF, 0x0EBB, 0x02A6, 0x0EC3, 0x02A9,
+ 0x02AC, 0x0EC7, 0x0ED3, 0x029D, 0x0EDB, 0x0ED7, 0x02A0, 0x02A3, 0x087E, 0x029A,
+ 0x0E9B, 0x02D6, 0x02B8, 0x02BB, 0x02BE, 0x02C1, 0x02AF, 0x02B2, 0x02B5, 0x0713,
+ 0x0717, 0x071B, 0x071F, 0x0703, 0x0EDF, 0x0707, 0x070B, 0x070F, 0x0753, 0x0757,
+ 0x075B, 0x075F, 0x0743, 0x0747, 0x074B, 0x074F, 0x058F, 0x057B, 0x110F, 0x0580,
+ 0x1113, 0x0585, 0x058A, 0x0576, 0x05CB, 0x05D0, 0x05D5, 0x05DA, 0x111B, 0x1143,
+ 0x1147, 0x05B7, 0x05BC, 0x114B, 0x05C1, 0x112F, 0x1133, 0x05C6, 0x1137, 0x0F3B,
+ 0x113B, 0x1117, 0x0F3F, 0x113F, 0x0F43, 0x0F47, 0x0F2B, 0x0F2F, 0x1123, 0x111F,
+ 0x114F, 0x1127, 0x1153, 0x0F33, 0x1157, 0x112B, 0x0F37, 0x0F1B, 0x0F1F, 0x0F23,
+ 0x0F27, 0x0F0B, 0x0F0F, 0x0F13, 0x0F17, 0x06BB, 0x06C0, 0x06C5, 0x06CA, 0x06A7,
+ 0x06AC, 0x06B1, 0x115B, 0x06B6, 0x115F, 0x0693, 0x1163, 0x0698, 0x1167, 0x069D,
+ 0x06A2, 0x067F, 0x0F4F, 0x0684, 0x0F57, 0x0689, 0x068E, 0x0EFB, 0x0EFF, 0x0F03,
+ 0x0F07, 0x0EEB, 0x0EEF, 0x0EF3, 0x0EE3, 0x0EE7, 0x06CF, 0x06D4, 0x06D9, 0x0F9F,
+ 0x0F97, 0x06DE, 0x0B52, 0x0B56, 0x0FA7, 0x0B4A, 0x0F8F, 0x0B4E, 0x0670, 0x067A,
+ 0x065C, 0x0666, 0x0044, 0x004A, 0x0038, 0x003E, 0x0FD7, 0x0FCF, 0x0089, 0x007D,
+ 0x0083, 0x0074, 0x0068, 0x006E, 0x0B32, 0x0B36, 0x0B2A, 0x0B2E, 0x0B22, 0x12CE,
+ 0x0B26, 0x0291, 0x028E, 0x12DE, 0x0294, 0x12D6, 0x0B1A, 0x0B1E, 0x0AD2, 0x0AD6,
+ 0x0ACA, 0x0ACE, 0x0AC2, 0x0AC6, 0x0297, 0x0ABA, 0x0F4B, 0x0ABE, 0x0F53, 0x0AF2,
+ 0x1021, 0x0AF6, 0x1024, 0x0AEA, 0x1027, 0x1019, 0x0F63, 0x0FB3, 0x0FBB, 0x02D3,
+ 0x02D0, 0x0FC3, 0x102A, 0x0F8B, 0x0F93, 0x102D, 0x0F9B, 0x1031, 0x0FA3, 0x0F5B,
+ 0x02C7, 0x0FAB, 0x02CD, 0x02CA, 0x02C4, 0x02D9, 0x0F73, 0x0F6B, 0x0FCB, 0x0F7B,
+ 0x0FD3, 0x100B, 0x0FDB, 0x0F83, 0x1007, 0x100E, 0x081F, 0x0847, 0x0829, 0x0851,
+ 0x1012, 0x0833, 0x1015, 0x083D, 0x086F, 0x1038, 0x0879, 0x0D1F, 0x0AEE, 0x0D17,
+ 0x0FE3, 0x0178, 0x0FEB, 0x085B, 0x0FF3, 0x10F3, 0x0FFB, 0x0865, 0x101D, 0x1035,
+ 0x08C3, 0x08CD, 0x08AF, 0x08B9, 0x10EB, 0x089B, 0x10EF, 0x08A5, 0x0887, 0x0891,
+ 0x0913, 0x091D, 0x08FF, 0x0909, 0x08EB, 0x08F5, 0x08D7, 0x08E1, 0x0CEB, 0x0148,
+ 0x0CEF, 0x0142, 0x0F67, 0x0CE7, 0x0145, 0x0FAF, 0x0F5F, 0x10E3, 0x00F4, 0x00F7,
+ 0x00EE, 0x00F1, 0x10F7, 0x0C6B, 0x00E8, 0x0C6F, 0x00EB, 0x0C63, 0x00E2, 0x0C67,
+ 0x103B, 0x104B, 0x103F, 0x104F, 0x00E5, 0x1043, 0x03C0, 0x1047, 0x105B, 0x03C6,
+ 0x105F, 0x03B4, 0x03BA, 0x0324, 0x0327, 0x03A8, 0x032A, 0x1053, 0x03AE, 0x032D,
+ 0x0330, 0x1057, 0x0336, 0x0333, 0x051C, 0x0339, 0x051F, 0x033F, 0x10BB, 0x0345,
+ 0x10BF, 0x034B, 0x050D, 0x0351, 0x050A, 0x0357, 0x10C3, 0x035D, 0x10C7, 0x0363,
+ 0x10CF, 0x0369, 0x0372, 0x036F, 0x036C, 0x0375, 0x037E, 0x037B, 0x039C, 0x0387,
+ 0x0381, 0x03A2, 0x0378, 0x038D, 0x0F77, 0x0393, 0x11A3, 0x0399, 0x11AB, 0x039F,
+ 0x10D3, 0x03A5, 0x10D7, 0x03AB, 0x10FB, 0x03B7, 0x11A7, 0x10FF, 0x03B1, 0x03BD,
+ 0x10CB, 0x03C3, 0x10DF, 0x10DB, 0x053D, 0x11BF, 0x0549, 0x046E, 0x054F, 0x10E7,
+ 0x09A2, 0x11B3, 0x110B, 0x11CF, 0x11AF, 0x11B7, 0x11BB, 0x11D7, 0x11E3, 0x0360,
+ 0x11E7, 0x03FC, 0x09B2, 0x09D2, 0x09BA, 0x09DA, 0x0BA3, 0x11EB, 0x0B9E, 0x11EF,
+ 0x0366, 0x11F3, 0x0354, 0x11F7, 0x0BBC, 0x035A, 0x0BC1, 0x0348, 0x0417, 0x034E,
+ 0x033C, 0x0342, 0x0BB2, 0x0BB7, 0x0390, 0x0396, 0x0384, 0x0411, 0x093E, 0x041A,
+ 0x0A42, 0x03C9, 0x0A4A, 0x03CC, 0x0A52, 0x03CF, 0x0A5A, 0x03D2, 0x038A, 0x03D5,
+ 0x0208, 0x03D8, 0x0489, 0x03DB, 0x01FC, 0x03DE, 0x03E7, 0x098A, 0x0982, 0x03E4,
+ 0x099A, 0x03E1, 0x0483, 0x03EA, 0x0516, 0x0519, 0x01C9, 0x03F0, 0x03ED, 0x03F3,
+ 0x09AA, 0x03F6, 0x0486, 0x1316, 0x042C, 0x125B, 0x0468, 0x125F, 0x0432, 0x01CC,
+ 0x0A02, 0x0A7A, 0x0A0A, 0x0A7E, 0x0A86, 0x0A82, 0x03FF, 0x0402, 0x0435, 0x0A8E,
+ 0x0A8A, 0x0438, 0x043B, 0x0A92, 0x043E, 0x0A96, 0x1262, 0x0A9A, 0x1266, 0x0A9E,
+ 0x0408, 0x0AA2, 0x1272, 0x0AA6, 0x0AAE, 0x0AAA, 0x03F9, 0x0420, 0x0426, 0x0AB2,
+ 0x041D, 0x0AB6, 0x09C2, 0x01C6, 0x09CA, 0x0444, 0x0423, 0x0447, 0x0A1A, 0x12B6,
+ 0x0405, 0x040B, 0x0F6F, 0x0A6E, 0x0F7F, 0x0A76, 0x0F87, 0x1322, 0x124B, 0x0ADA,
+ 0x124F, 0x0ADE, 0x0AE6, 0x0AE2, 0x126A, 0x044A, 0x0450, 0x0D37, 0x0453, 0x01BA,
+ 0x0456, 0x1253, 0x0459, 0x1257, 0x045C, 0x0AFA, 0x045F, 0x0AFE, 0x0462, 0x0B02,
+ 0x0B0A, 0x0B06, 0x0B0E, 0x0465, 0x046B, 0x04AA, 0x1276, 0x01BD, 0x127A, 0x0C16,
+ 0x126E, 0x0471, 0x0BCB, 0x0474, 0x0B12, 0x0477, 0x0B16, 0x047A, 0x127E, 0x047D,
+ 0x1282, 0x0480, 0x1286, 0x04A1, 0x128A, 0x04A4, 0x0B3E, 0x0B3A, 0x0414, 0x048C,
+ 0x0B46, 0x048F, 0x0B42, 0x0492, 0x0D9F, 0x0495, 0x01D8, 0x0498, 0x0199, 0x049B,
+ 0x019C, 0x049E, 0x0B62, 0x0B5A, 0x0E37, 0x0B5E, 0x044D, 0x04A7, 0x0193, 0x0B66,
+ 0x0522, 0x0B6A, 0x0528, 0x0B6E, 0x04AD, 0x0B72, 0x04B0, 0x0B76, 0x04E3, 0x0B7A,
+ 0x0534, 0x0B7E, 0x04B3, 0x0B82, 0x04B6, 0x0B86, 0x04BC, 0x0552, 0x0558, 0x0B8E,
+ 0x055E, 0x0B8A, 0x0564, 0x052E, };
+
+const uint8_t NU_TOLOWER_COMBINED[] = {
+ 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66,
+ 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, 0x00, 0x6C,
+ 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72,
+ 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78,
+ 0x00, 0x79, 0x00, 0x7A, 0x00, 0xC3, 0xA0, 0x00, 0xC3, 0xA1, 0x00, 0xC3,
+ 0xA2, 0x00, 0xC3, 0xA3, 0x00, 0xC3, 0xA4, 0x00, 0xC3, 0xA5, 0x00, 0xC3,
+ 0xA6, 0x00, 0xC3, 0xA7, 0x00, 0xC3, 0xA8, 0x00, 0xC3, 0xA9, 0x00, 0xC3,
+ 0xAA, 0x00, 0xC3, 0xAB, 0x00, 0xC3, 0xAC, 0x00, 0xC3, 0xAD, 0x00, 0xC3,
+ 0xAE, 0x00, 0xC3, 0xAF, 0x00, 0xC3, 0xB0, 0x00, 0xC3, 0xB1, 0x00, 0xC3,
+ 0xB2, 0x00, 0xC3, 0xB3, 0x00, 0xC3, 0xB4, 0x00, 0xC3, 0xB5, 0x00, 0xC3,
+ 0xB6, 0x00, 0xC3, 0xB8, 0x00, 0xC3, 0xB9, 0x00, 0xC3, 0xBA, 0x00, 0xC3,
+ 0xBB, 0x00, 0xC3, 0xBC, 0x00, 0xC3, 0xBD, 0x00, 0xC3, 0xBE, 0x00, 0xC4,
+ 0x81, 0x00, 0xC4, 0x83, 0x00, 0xC4, 0x85, 0x00, 0xC4, 0x87, 0x00, 0xC4,
+ 0x89, 0x00, 0xC4, 0x8B, 0x00, 0xC4, 0x8D, 0x00, 0xC4, 0x8F, 0x00, 0xC4,
+ 0x91, 0x00, 0xC4, 0x93, 0x00, 0xC4, 0x95, 0x00, 0xC4, 0x97, 0x00, 0xC4,
+ 0x99, 0x00, 0xC4, 0x9B, 0x00, 0xC4, 0x9D, 0x00, 0xC4, 0x9F, 0x00, 0xC4,
+ 0xA1, 0x00, 0xC4, 0xA3, 0x00, 0xC4, 0xA5, 0x00, 0xC4, 0xA7, 0x00, 0xC4,
+ 0xA9, 0x00, 0xC4, 0xAB, 0x00, 0xC4, 0xAD, 0x00, 0xC4, 0xAF, 0x00, 0x69,
+ 0x00, 0xC4, 0xB3, 0x00, 0xC4, 0xB5, 0x00, 0xC4, 0xB7, 0x00, 0xC4, 0xBA,
+ 0x00, 0xC4, 0xBC, 0x00, 0xC4, 0xBE, 0x00, 0xC5, 0x80, 0x00, 0xC5, 0x82,
+ 0x00, 0xC5, 0x84, 0x00, 0xC5, 0x86, 0x00, 0xC5, 0x88, 0x00, 0xC5, 0x8B,
+ 0x00, 0xC5, 0x8D, 0x00, 0xC5, 0x8F, 0x00, 0xC5, 0x91, 0x00, 0xC5, 0x93,
+ 0x00, 0xC5, 0x95, 0x00, 0xC5, 0x97, 0x00, 0xC5, 0x99, 0x00, 0xC5, 0x9B,
+ 0x00, 0xC5, 0x9D, 0x00, 0xC5, 0x9F, 0x00, 0xC5, 0xA1, 0x00, 0xC5, 0xA3,
+ 0x00, 0xC5, 0xA5, 0x00, 0xC5, 0xA7, 0x00, 0xC5, 0xA9, 0x00, 0xC5, 0xAB,
+ 0x00, 0xC5, 0xAD, 0x00, 0xC5, 0xAF, 0x00, 0xC5, 0xB1, 0x00, 0xC5, 0xB3,
+ 0x00, 0xC5, 0xB5, 0x00, 0xC5, 0xB7, 0x00, 0xC3, 0xBF, 0x00, 0xC5, 0xBA,
+ 0x00, 0xC5, 0xBC, 0x00, 0xC5, 0xBE, 0x00, 0xC9, 0x93, 0x00, 0xC6, 0x83,
+ 0x00, 0xC6, 0x85, 0x00, 0xC9, 0x94, 0x00, 0xC6, 0x88, 0x00, 0xC9, 0x96,
+ 0x00, 0xC9, 0x97, 0x00, 0xC6, 0x8C, 0x00, 0xC7, 0x9D, 0x00, 0xC9, 0x99,
+ 0x00, 0xC9, 0x9B, 0x00, 0xC6, 0x92, 0x00, 0xC9, 0xA0, 0x00, 0xC9, 0xA3,
+ 0x00, 0xC9, 0xA9, 0x00, 0xC9, 0xA8, 0x00, 0xC6, 0x99, 0x00, 0xC9, 0xAF,
+ 0x00, 0xC9, 0xB2, 0x00, 0xC9, 0xB5, 0x00, 0xC6, 0xA1, 0x00, 0xC6, 0xA3,
+ 0x00, 0xC6, 0xA5, 0x00, 0xCA, 0x80, 0x00, 0xC6, 0xA8, 0x00, 0xCA, 0x83,
+ 0x00, 0xC6, 0xAD, 0x00, 0xCA, 0x88, 0x00, 0xC6, 0xB0, 0x00, 0xCA, 0x8A,
+ 0x00, 0xCA, 0x8B, 0x00, 0xC6, 0xB4, 0x00, 0xC6, 0xB6, 0x00, 0xCA, 0x92,
+ 0x00, 0xC6, 0xB9, 0x00, 0xC6, 0xBD, 0x00, 0xC7, 0x86, 0x00, 0xC7, 0x86,
+ 0x00, 0xC7, 0x89, 0x00, 0xC7, 0x89, 0x00, 0xC7, 0x8C, 0x00, 0xC7, 0x8C,
+ 0x00, 0xC7, 0x8E, 0x00, 0xC7, 0x90, 0x00, 0xC7, 0x92, 0x00, 0xC7, 0x94,
+ 0x00, 0xC7, 0x96, 0x00, 0xC7, 0x98, 0x00, 0xC7, 0x9A, 0x00, 0xC7, 0x9C,
+ 0x00, 0xC7, 0x9F, 0x00, 0xC7, 0xA1, 0x00, 0xC7, 0xA3, 0x00, 0xC7, 0xA5,
+ 0x00, 0xC7, 0xA7, 0x00, 0xC7, 0xA9, 0x00, 0xC7, 0xAB, 0x00, 0xC7, 0xAD,
+ 0x00, 0xC7, 0xAF, 0x00, 0xC7, 0xB3, 0x00, 0xC7, 0xB3, 0x00, 0xC7, 0xB5,
+ 0x00, 0xC6, 0x95, 0x00, 0xC6, 0xBF, 0x00, 0xC7, 0xB9, 0x00, 0xC7, 0xBB,
+ 0x00, 0xC7, 0xBD, 0x00, 0xC7, 0xBF, 0x00, 0xC8, 0x81, 0x00, 0xC8, 0x83,
+ 0x00, 0xC8, 0x85, 0x00, 0xC8, 0x87, 0x00, 0xC8, 0x89, 0x00, 0xC8, 0x8B,
+ 0x00, 0xC8, 0x8D, 0x00, 0xC8, 0x8F, 0x00, 0xC8, 0x91, 0x00, 0xC8, 0x93,
+ 0x00, 0xC8, 0x95, 0x00, 0xC8, 0x97, 0x00, 0xC8, 0x99, 0x00, 0xC8, 0x9B,
+ 0x00, 0xC8, 0x9D, 0x00, 0xC8, 0x9F, 0x00, 0xC6, 0x9E, 0x00, 0xC8, 0xA3,
+ 0x00, 0xC8, 0xA5, 0x00, 0xC8, 0xA7, 0x00, 0xC8, 0xA9, 0x00, 0xC8, 0xAB,
+ 0x00, 0xC8, 0xAD, 0x00, 0xC8, 0xAF, 0x00, 0xC8, 0xB1, 0x00, 0xC8, 0xB3,
+ 0x00, 0xE2, 0xB1, 0xA5, 0x00, 0xC8, 0xBC, 0x00, 0xC6, 0x9A, 0x00, 0xE2,
+ 0xB1, 0xA6, 0x00, 0xC9, 0x82, 0x00, 0xC6, 0x80, 0x00, 0xCA, 0x89, 0x00,
+ 0xCA, 0x8C, 0x00, 0xC9, 0x87, 0x00, 0xC9, 0x89, 0x00, 0xC9, 0x8B, 0x00,
+ 0xC9, 0x8D, 0x00, 0xC9, 0x8F, 0x00, 0xCD, 0xB1, 0x00, 0xCD, 0xB3, 0x00,
+ 0xCD, 0xB7, 0x00, 0xCF, 0xB3, 0x00, 0xCE, 0xAC, 0x00, 0xCE, 0xAD, 0x00,
+ 0xCE, 0xAE, 0x00, 0xCE, 0xAF, 0x00, 0xCF, 0x8C, 0x00, 0xCF, 0x8D, 0x00,
+ 0xCF, 0x8E, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB2, 0x00, 0xCE, 0xB3, 0x00,
+ 0xCE, 0xB4, 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0xB6, 0x00, 0xCE, 0xB7, 0x00,
+ 0xCE, 0xB8, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xBA, 0x00, 0xCE, 0xBB, 0x00,
+ 0xCE, 0xBC, 0x00, 0xCE, 0xBD, 0x00, 0xCE, 0xBE, 0x00, 0xCE, 0xBF, 0x00,
+ 0xCF, 0x80, 0x00, 0xCF, 0x81, 0x00, 0xCF, 0x83, 0x00, 0xCF, 0x84, 0x00,
+ 0xCF, 0x85, 0x00, 0xCF, 0x86, 0x00, 0xCF, 0x87, 0x00, 0xCF, 0x88, 0x00,
+ 0xCF, 0x89, 0x00, 0xCF, 0x8A, 0x00, 0xCF, 0x8B, 0x00, 0xCF, 0x97, 0x00,
+ 0xCF, 0x99, 0x00, 0xCF, 0x9B, 0x00, 0xCF, 0x9D, 0x00, 0xCF, 0x9F, 0x00,
+ 0xCF, 0xA1, 0x00, 0xCF, 0xA3, 0x00, 0xCF, 0xA5, 0x00, 0xCF, 0xA7, 0x00,
+ 0xCF, 0xA9, 0x00, 0xCF, 0xAB, 0x00, 0xCF, 0xAD, 0x00, 0xCF, 0xAF, 0x00,
+ 0xCE, 0xB8, 0x00, 0xCF, 0xB8, 0x00, 0xCF, 0xB2, 0x00, 0xCF, 0xBB, 0x00,
+ 0xCD, 0xBB, 0x00, 0xCD, 0xBC, 0x00, 0xCD, 0xBD, 0x00, 0xD1, 0x90, 0x00,
+ 0xD1, 0x91, 0x00, 0xD1, 0x92, 0x00, 0xD1, 0x93, 0x00, 0xD1, 0x94, 0x00,
+ 0xD1, 0x95, 0x00, 0xD1, 0x96, 0x00, 0xD1, 0x97, 0x00, 0xD1, 0x98, 0x00,
+ 0xD1, 0x99, 0x00, 0xD1, 0x9A, 0x00, 0xD1, 0x9B, 0x00, 0xD1, 0x9C, 0x00,
+ 0xD1, 0x9D, 0x00, 0xD1, 0x9E, 0x00, 0xD1, 0x9F, 0x00, 0xD0, 0xB0, 0x00,
+ 0xD0, 0xB1, 0x00, 0xD0, 0xB2, 0x00, 0xD0, 0xB3, 0x00, 0xD0, 0xB4, 0x00,
+ 0xD0, 0xB5, 0x00, 0xD0, 0xB6, 0x00, 0xD0, 0xB7, 0x00, 0xD0, 0xB8, 0x00,
+ 0xD0, 0xB9, 0x00, 0xD0, 0xBA, 0x00, 0xD0, 0xBB, 0x00, 0xD0, 0xBC, 0x00,
+ 0xD0, 0xBD, 0x00, 0xD0, 0xBE, 0x00, 0xD0, 0xBF, 0x00, 0xD1, 0x80, 0x00,
+ 0xD1, 0x81, 0x00, 0xD1, 0x82, 0x00, 0xD1, 0x83, 0x00, 0xD1, 0x84, 0x00,
+ 0xD1, 0x85, 0x00, 0xD1, 0x86, 0x00, 0xD1, 0x87, 0x00, 0xD1, 0x88, 0x00,
+ 0xD1, 0x89, 0x00, 0xD1, 0x8A, 0x00, 0xD1, 0x8B, 0x00, 0xD1, 0x8C, 0x00,
+ 0xD1, 0x8D, 0x00, 0xD1, 0x8E, 0x00, 0xD1, 0x8F, 0x00, 0xD1, 0xA1, 0x00,
+ 0xD1, 0xA3, 0x00, 0xD1, 0xA5, 0x00, 0xD1, 0xA7, 0x00, 0xD1, 0xA9, 0x00,
+ 0xD1, 0xAB, 0x00, 0xD1, 0xAD, 0x00, 0xD1, 0xAF, 0x00, 0xD1, 0xB1, 0x00,
+ 0xD1, 0xB3, 0x00, 0xD1, 0xB5, 0x00, 0xD1, 0xB7, 0x00, 0xD1, 0xB9, 0x00,
+ 0xD1, 0xBB, 0x00, 0xD1, 0xBD, 0x00, 0xD1, 0xBF, 0x00, 0xD2, 0x81, 0x00,
+ 0xD2, 0x8B, 0x00, 0xD2, 0x8D, 0x00, 0xD2, 0x8F, 0x00, 0xD2, 0x91, 0x00,
+ 0xD2, 0x93, 0x00, 0xD2, 0x95, 0x00, 0xD2, 0x97, 0x00, 0xD2, 0x99, 0x00,
+ 0xD2, 0x9B, 0x00, 0xD2, 0x9D, 0x00, 0xD2, 0x9F, 0x00, 0xD2, 0xA1, 0x00,
+ 0xD2, 0xA3, 0x00, 0xD2, 0xA5, 0x00, 0xD2, 0xA7, 0x00, 0xD2, 0xA9, 0x00,
+ 0xD2, 0xAB, 0x00, 0xD2, 0xAD, 0x00, 0xD2, 0xAF, 0x00, 0xD2, 0xB1, 0x00,
+ 0xD2, 0xB3, 0x00, 0xD2, 0xB5, 0x00, 0xD2, 0xB7, 0x00, 0xD2, 0xB9, 0x00,
+ 0xD2, 0xBB, 0x00, 0xD2, 0xBD, 0x00, 0xD2, 0xBF, 0x00, 0xD3, 0x8F, 0x00,
+ 0xD3, 0x82, 0x00, 0xD3, 0x84, 0x00, 0xD3, 0x86, 0x00, 0xD3, 0x88, 0x00,
+ 0xD3, 0x8A, 0x00, 0xD3, 0x8C, 0x00, 0xD3, 0x8E, 0x00, 0xD3, 0x91, 0x00,
+ 0xD3, 0x93, 0x00, 0xD3, 0x95, 0x00, 0xD3, 0x97, 0x00, 0xD3, 0x99, 0x00,
+ 0xD3, 0x9B, 0x00, 0xD3, 0x9D, 0x00, 0xD3, 0x9F, 0x00, 0xD3, 0xA1, 0x00,
+ 0xD3, 0xA3, 0x00, 0xD3, 0xA5, 0x00, 0xD3, 0xA7, 0x00, 0xD3, 0xA9, 0x00,
+ 0xD3, 0xAB, 0x00, 0xD3, 0xAD, 0x00, 0xD3, 0xAF, 0x00, 0xD3, 0xB1, 0x00,
+ 0xD3, 0xB3, 0x00, 0xD3, 0xB5, 0x00, 0xD3, 0xB7, 0x00, 0xD3, 0xB9, 0x00,
+ 0xD3, 0xBB, 0x00, 0xD3, 0xBD, 0x00, 0xD3, 0xBF, 0x00, 0xD4, 0x81, 0x00,
+ 0xD4, 0x83, 0x00, 0xD4, 0x85, 0x00, 0xD4, 0x87, 0x00, 0xD4, 0x89, 0x00,
+ 0xD4, 0x8B, 0x00, 0xD4, 0x8D, 0x00, 0xD4, 0x8F, 0x00, 0xD4, 0x91, 0x00,
+ 0xD4, 0x93, 0x00, 0xD4, 0x95, 0x00, 0xD4, 0x97, 0x00, 0xD4, 0x99, 0x00,
+ 0xD4, 0x9B, 0x00, 0xD4, 0x9D, 0x00, 0xD4, 0x9F, 0x00, 0xD4, 0xA1, 0x00,
+ 0xD4, 0xA3, 0x00, 0xD4, 0xA5, 0x00, 0xD4, 0xA7, 0x00, 0xD4, 0xA9, 0x00,
+ 0xD4, 0xAB, 0x00, 0xD4, 0xAD, 0x00, 0xD4, 0xAF, 0x00, 0xD5, 0xA1, 0x00,
+ 0xD5, 0xA2, 0x00, 0xD5, 0xA3, 0x00, 0xD5, 0xA4, 0x00, 0xD5, 0xA5, 0x00,
+ 0xD5, 0xA6, 0x00, 0xD5, 0xA7, 0x00, 0xD5, 0xA8, 0x00, 0xD5, 0xA9, 0x00,
+ 0xD5, 0xAA, 0x00, 0xD5, 0xAB, 0x00, 0xD5, 0xAC, 0x00, 0xD5, 0xAD, 0x00,
+ 0xD5, 0xAE, 0x00, 0xD5, 0xAF, 0x00, 0xD5, 0xB0, 0x00, 0xD5, 0xB1, 0x00,
+ 0xD5, 0xB2, 0x00, 0xD5, 0xB3, 0x00, 0xD5, 0xB4, 0x00, 0xD5, 0xB5, 0x00,
+ 0xD5, 0xB6, 0x00, 0xD5, 0xB7, 0x00, 0xD5, 0xB8, 0x00, 0xD5, 0xB9, 0x00,
+ 0xD5, 0xBA, 0x00, 0xD5, 0xBB, 0x00, 0xD5, 0xBC, 0x00, 0xD5, 0xBD, 0x00,
+ 0xD5, 0xBE, 0x00, 0xD5, 0xBF, 0x00, 0xD6, 0x80, 0x00, 0xD6, 0x81, 0x00,
+ 0xD6, 0x82, 0x00, 0xD6, 0x83, 0x00, 0xD6, 0x84, 0x00, 0xD6, 0x85, 0x00,
+ 0xD6, 0x86, 0x00, 0xF0, 0x90, 0x90, 0xA8, 0x00, 0xF0, 0x90, 0x90, 0xA9,
+ 0x00, 0xF0, 0x90, 0x90, 0xAA, 0x00, 0xF0, 0x90, 0x90, 0xAB, 0x00, 0xF0,
+ 0x90, 0x90, 0xAC, 0x00, 0xF0, 0x90, 0x90, 0xAD, 0x00, 0xF0, 0x90, 0x90,
+ 0xAE, 0x00, 0xF0, 0x90, 0x90, 0xAF, 0x00, 0xF0, 0x90, 0x90, 0xB0, 0x00,
+ 0xF0, 0x90, 0x90, 0xB1, 0x00, 0xF0, 0x90, 0x90, 0xB2, 0x00, 0xF0, 0x90,
+ 0x90, 0xB3, 0x00, 0xF0, 0x90, 0x90, 0xB4, 0x00, 0xF0, 0x90, 0x90, 0xB5,
+ 0x00, 0xF0, 0x90, 0x90, 0xB6, 0x00, 0xF0, 0x90, 0x90, 0xB7, 0x00, 0xF0,
+ 0x90, 0x90, 0xB8, 0x00, 0xF0, 0x90, 0x90, 0xB9, 0x00, 0xF0, 0x90, 0x90,
+ 0xBA, 0x00, 0xF0, 0x90, 0x90, 0xBB, 0x00, 0xF0, 0x90, 0x90, 0xBC, 0x00,
+ 0xF0, 0x90, 0x90, 0xBD, 0x00, 0xF0, 0x90, 0x90, 0xBE, 0x00, 0xF0, 0x90,
+ 0x90, 0xBF, 0x00, 0xF0, 0x90, 0x91, 0x80, 0x00, 0xF0, 0x90, 0x91, 0x81,
+ 0x00, 0xF0, 0x90, 0x91, 0x82, 0x00, 0xF0, 0x90, 0x91, 0x83, 0x00, 0xF0,
+ 0x90, 0x91, 0x84, 0x00, 0xF0, 0x90, 0x91, 0x85, 0x00, 0xF0, 0x90, 0x91,
+ 0x86, 0x00, 0xF0, 0x90, 0x91, 0x87, 0x00, 0xF0, 0x90, 0x91, 0x88, 0x00,
+ 0xF0, 0x90, 0x91, 0x89, 0x00, 0xF0, 0x90, 0x91, 0x8A, 0x00, 0xF0, 0x90,
+ 0x91, 0x8B, 0x00, 0xF0, 0x90, 0x91, 0x8C, 0x00, 0xF0, 0x90, 0x91, 0x8D,
+ 0x00, 0xF0, 0x90, 0x91, 0x8E, 0x00, 0xF0, 0x90, 0x91, 0x8F, 0x00, 0xF0,
+ 0x90, 0x93, 0x98, 0x00, 0xF0, 0x90, 0x93, 0x99, 0x00, 0xF0, 0x90, 0x93,
+ 0x9A, 0x00, 0xF0, 0x90, 0x93, 0x9B, 0x00, 0xF0, 0x90, 0x93, 0x9C, 0x00,
+ 0xF0, 0x90, 0x93, 0x9D, 0x00, 0xF0, 0x90, 0x93, 0x9E, 0x00, 0xF0, 0x90,
+ 0x93, 0x9F, 0x00, 0xF0, 0x90, 0x93, 0xA0, 0x00, 0xF0, 0x90, 0x93, 0xA1,
+ 0x00, 0xF0, 0x90, 0x93, 0xA2, 0x00, 0xF0, 0x90, 0x93, 0xA3, 0x00, 0xF0,
+ 0x90, 0x93, 0xA4, 0x00, 0xF0, 0x90, 0x93, 0xA5, 0x00, 0xF0, 0x90, 0x93,
+ 0xA6, 0x00, 0xF0, 0x90, 0x93, 0xA7, 0x00, 0xF0, 0x90, 0x93, 0xA8, 0x00,
+ 0xF0, 0x90, 0x93, 0xA9, 0x00, 0xF0, 0x90, 0x93, 0xAA, 0x00, 0xF0, 0x90,
+ 0x93, 0xAB, 0x00, 0xF0, 0x90, 0x93, 0xAC, 0x00, 0xF0, 0x90, 0x93, 0xAD,
+ 0x00, 0xF0, 0x90, 0x93, 0xAE, 0x00, 0xF0, 0x90, 0x93, 0xAF, 0x00, 0xF0,
+ 0x90, 0x93, 0xB0, 0x00, 0xF0, 0x90, 0x93, 0xB1, 0x00, 0xF0, 0x90, 0x93,
+ 0xB2, 0x00, 0xF0, 0x90, 0x93, 0xB3, 0x00, 0xF0, 0x90, 0x93, 0xB4, 0x00,
+ 0xF0, 0x90, 0x93, 0xB5, 0x00, 0xF0, 0x90, 0x93, 0xB6, 0x00, 0xF0, 0x90,
+ 0x93, 0xB7, 0x00, 0xF0, 0x90, 0x93, 0xB8, 0x00, 0xF0, 0x90, 0x93, 0xB9,
+ 0x00, 0xF0, 0x90, 0x93, 0xBA, 0x00, 0xF0, 0x90, 0x93, 0xBB, 0x00, 0xE2,
+ 0xB4, 0x80, 0x00, 0xE2, 0xB4, 0x81, 0x00, 0xE2, 0xB4, 0x82, 0x00, 0xE2,
+ 0xB4, 0x83, 0x00, 0xE2, 0xB4, 0x84, 0x00, 0xE2, 0xB4, 0x85, 0x00, 0xE2,
+ 0xB4, 0x86, 0x00, 0xE2, 0xB4, 0x87, 0x00, 0xE2, 0xB4, 0x88, 0x00, 0xE2,
+ 0xB4, 0x89, 0x00, 0xE2, 0xB4, 0x8A, 0x00, 0xE2, 0xB4, 0x8B, 0x00, 0xE2,
+ 0xB4, 0x8C, 0x00, 0xE2, 0xB4, 0x8D, 0x00, 0xE2, 0xB4, 0x8E, 0x00, 0xE2,
+ 0xB4, 0x8F, 0x00, 0xE2, 0xB4, 0x90, 0x00, 0xE2, 0xB4, 0x91, 0x00, 0xE2,
+ 0xB4, 0x92, 0x00, 0xE2, 0xB4, 0x93, 0x00, 0xE2, 0xB4, 0x94, 0x00, 0xE2,
+ 0xB4, 0x95, 0x00, 0xE2, 0xB4, 0x96, 0x00, 0xE2, 0xB4, 0x97, 0x00, 0xE2,
+ 0xB4, 0x98, 0x00, 0xE2, 0xB4, 0x99, 0x00, 0xE2, 0xB4, 0x9A, 0x00, 0xE2,
+ 0xB4, 0x9B, 0x00, 0xE2, 0xB4, 0x9C, 0x00, 0xE2, 0xB4, 0x9D, 0x00, 0xE2,
+ 0xB4, 0x9E, 0x00, 0xE2, 0xB4, 0x9F, 0x00, 0xE2, 0xB4, 0xA0, 0x00, 0xE2,
+ 0xB4, 0xA1, 0x00, 0xE2, 0xB4, 0xA2, 0x00, 0xE2, 0xB4, 0xA3, 0x00, 0xE2,
+ 0xB4, 0xA4, 0x00, 0xE2, 0xB4, 0xA5, 0x00, 0xE2, 0xB4, 0xA7, 0x00, 0xF0,
+ 0x90, 0xB3, 0x80, 0x00, 0xF0, 0x90, 0xB3, 0x81, 0x00, 0xF0, 0x90, 0xB3,
+ 0x82, 0x00, 0xF0, 0x90, 0xB3, 0x83, 0x00, 0xF0, 0x90, 0xB3, 0x84, 0x00,
+ 0xF0, 0x90, 0xB3, 0x85, 0x00, 0xF0, 0x90, 0xB3, 0x86, 0x00, 0xF0, 0x90,
+ 0xB3, 0x87, 0x00, 0xF0, 0x90, 0xB3, 0x88, 0x00, 0xF0, 0x90, 0xB3, 0x89,
+ 0x00, 0xF0, 0x90, 0xB3, 0x8A, 0x00, 0xF0, 0x90, 0xB3, 0x8B, 0x00, 0xF0,
+ 0x90, 0xB3, 0x8C, 0x00, 0xF0, 0x90, 0xB3, 0x8D, 0x00, 0xF0, 0x90, 0xB3,
+ 0x8E, 0x00, 0xF0, 0x90, 0xB3, 0x8F, 0x00, 0xF0, 0x90, 0xB3, 0x90, 0x00,
+ 0xF0, 0x90, 0xB3, 0x91, 0x00, 0xF0, 0x90, 0xB3, 0x92, 0x00, 0xF0, 0x90,
+ 0xB3, 0x93, 0x00, 0xF0, 0x90, 0xB3, 0x94, 0x00, 0xF0, 0x90, 0xB3, 0x95,
+ 0x00, 0xF0, 0x90, 0xB3, 0x96, 0x00, 0xF0, 0x90, 0xB3, 0x97, 0x00, 0xF0,
+ 0x90, 0xB3, 0x98, 0x00, 0xF0, 0x90, 0xB3, 0x99, 0x00, 0xF0, 0x90, 0xB3,
+ 0x9A, 0x00, 0xF0, 0x90, 0xB3, 0x9B, 0x00, 0xF0, 0x90, 0xB3, 0x9C, 0x00,
+ 0xF0, 0x90, 0xB3, 0x9D, 0x00, 0xF0, 0x90, 0xB3, 0x9E, 0x00, 0xF0, 0x90,
+ 0xB3, 0x9F, 0x00, 0xF0, 0x90, 0xB3, 0xA0, 0x00, 0xF0, 0x90, 0xB3, 0xA1,
+ 0x00, 0xF0, 0x90, 0xB3, 0xA2, 0x00, 0xF0, 0x90, 0xB3, 0xA3, 0x00, 0xF0,
+ 0x90, 0xB3, 0xA4, 0x00, 0xF0, 0x90, 0xB3, 0xA5, 0x00, 0xF0, 0x90, 0xB3,
+ 0xA6, 0x00, 0xF0, 0x90, 0xB3, 0xA7, 0x00, 0xF0, 0x90, 0xB3, 0xA8, 0x00,
+ 0xF0, 0x90, 0xB3, 0xA9, 0x00, 0xF0, 0x90, 0xB3, 0xAA, 0x00, 0xF0, 0x90,
+ 0xB3, 0xAB, 0x00, 0xF0, 0x90, 0xB3, 0xAC, 0x00, 0xF0, 0x90, 0xB3, 0xAD,
+ 0x00, 0xF0, 0x90, 0xB3, 0xAE, 0x00, 0xF0, 0x90, 0xB3, 0xAF, 0x00, 0xF0,
+ 0x90, 0xB3, 0xB0, 0x00, 0xF0, 0x90, 0xB3, 0xB1, 0x00, 0xF0, 0x90, 0xB3,
+ 0xB2, 0x00, 0xE2, 0xB4, 0xAD, 0x00, 0xF0, 0x91, 0xA3, 0x80, 0x00, 0xF0,
+ 0x91, 0xA3, 0x81, 0x00, 0xF0, 0x91, 0xA3, 0x82, 0x00, 0xF0, 0x91, 0xA3,
+ 0x83, 0x00, 0xF0, 0x91, 0xA3, 0x84, 0x00, 0xF0, 0x91, 0xA3, 0x85, 0x00,
+ 0xF0, 0x91, 0xA3, 0x86, 0x00, 0xF0, 0x91, 0xA3, 0x87, 0x00, 0xF0, 0x91,
+ 0xA3, 0x88, 0x00, 0xF0, 0x91, 0xA3, 0x89, 0x00, 0xF0, 0x91, 0xA3, 0x8A,
+ 0x00, 0xF0, 0x91, 0xA3, 0x8B, 0x00, 0xF0, 0x91, 0xA3, 0x8C, 0x00, 0xF0,
+ 0x91, 0xA3, 0x8D, 0x00, 0xF0, 0x91, 0xA3, 0x8E, 0x00, 0xF0, 0x91, 0xA3,
+ 0x8F, 0x00, 0xF0, 0x91, 0xA3, 0x90, 0x00, 0xF0, 0x91, 0xA3, 0x91, 0x00,
+ 0xF0, 0x91, 0xA3, 0x92, 0x00, 0xF0, 0x91, 0xA3, 0x93, 0x00, 0xF0, 0x91,
+ 0xA3, 0x94, 0x00, 0xF0, 0x91, 0xA3, 0x95, 0x00, 0xF0, 0x91, 0xA3, 0x96,
+ 0x00, 0xF0, 0x91, 0xA3, 0x97, 0x00, 0xF0, 0x91, 0xA3, 0x98, 0x00, 0xF0,
+ 0x91, 0xA3, 0x99, 0x00, 0xF0, 0x91, 0xA3, 0x9A, 0x00, 0xF0, 0x91, 0xA3,
+ 0x9B, 0x00, 0xF0, 0x91, 0xA3, 0x9C, 0x00, 0xF0, 0x91, 0xA3, 0x9D, 0x00,
+ 0xF0, 0x91, 0xA3, 0x9E, 0x00, 0xF0, 0x91, 0xA3, 0x9F, 0x00, 0xEA, 0xAD,
+ 0xB0, 0x00, 0xEA, 0xAD, 0xB1, 0x00, 0xEA, 0xAD, 0xB2, 0x00, 0xEA, 0xAD,
+ 0xB3, 0x00, 0xEA, 0xAD, 0xB4, 0x00, 0xEA, 0xAD, 0xB5, 0x00, 0xEA, 0xAD,
+ 0xB6, 0x00, 0xEA, 0xAD, 0xB7, 0x00, 0xEA, 0xAD, 0xB8, 0x00, 0xEA, 0xAD,
+ 0xB9, 0x00, 0xEA, 0xAD, 0xBA, 0x00, 0xEA, 0xAD, 0xBB, 0x00, 0xEA, 0xAD,
+ 0xBC, 0x00, 0xEA, 0xAD, 0xBD, 0x00, 0xEA, 0xAD, 0xBE, 0x00, 0xEA, 0xAD,
+ 0xBF, 0x00, 0xEA, 0xAE, 0x80, 0x00, 0xEA, 0xAE, 0x81, 0x00, 0xEA, 0xAE,
+ 0x82, 0x00, 0xEA, 0xAE, 0x83, 0x00, 0xEA, 0xAE, 0x84, 0x00, 0xEA, 0xAE,
+ 0x85, 0x00, 0xEA, 0xAE, 0x86, 0x00, 0xEA, 0xAE, 0x87, 0x00, 0xEA, 0xAE,
+ 0x88, 0x00, 0xEA, 0xAE, 0x89, 0x00, 0xEA, 0xAE, 0x8A, 0x00, 0xEA, 0xAE,
+ 0x8B, 0x00, 0xEA, 0xAE, 0x8C, 0x00, 0xEA, 0xAE, 0x8D, 0x00, 0xEA, 0xAE,
+ 0x8E, 0x00, 0xEA, 0xAE, 0x8F, 0x00, 0xEA, 0xAE, 0x90, 0x00, 0xEA, 0xAE,
+ 0x91, 0x00, 0xEA, 0xAE, 0x92, 0x00, 0xEA, 0xAE, 0x93, 0x00, 0xEA, 0xAE,
+ 0x94, 0x00, 0xEA, 0xAE, 0x95, 0x00, 0xEA, 0xAE, 0x96, 0x00, 0xEA, 0xAE,
+ 0x97, 0x00, 0xEA, 0xAE, 0x98, 0x00, 0xEA, 0xAE, 0x99, 0x00, 0xEA, 0xAE,
+ 0x9A, 0x00, 0xEA, 0xAE, 0x9B, 0x00, 0xEA, 0xAE, 0x9C, 0x00, 0xEA, 0xAE,
+ 0x9D, 0x00, 0xEA, 0xAE, 0x9E, 0x00, 0xEA, 0xAE, 0x9F, 0x00, 0xEA, 0xAE,
+ 0xA0, 0x00, 0xEA, 0xAE, 0xA1, 0x00, 0xEA, 0xAE, 0xA2, 0x00, 0xEA, 0xAE,
+ 0xA3, 0x00, 0xEA, 0xAE, 0xA4, 0x00, 0xEA, 0xAE, 0xA5, 0x00, 0xEA, 0xAE,
+ 0xA6, 0x00, 0xEA, 0xAE, 0xA7, 0x00, 0xEA, 0xAE, 0xA8, 0x00, 0xEA, 0xAE,
+ 0xA9, 0x00, 0xEA, 0xAE, 0xAA, 0x00, 0xEA, 0xAE, 0xAB, 0x00, 0xEA, 0xAE,
+ 0xAC, 0x00, 0xEA, 0xAE, 0xAD, 0x00, 0xEA, 0xAE, 0xAE, 0x00, 0xEA, 0xAE,
+ 0xAF, 0x00, 0xEA, 0xAE, 0xB0, 0x00, 0xEA, 0xAE, 0xB1, 0x00, 0xEA, 0xAE,
+ 0xB2, 0x00, 0xEA, 0xAE, 0xB3, 0x00, 0xEA, 0xAE, 0xB4, 0x00, 0xEA, 0xAE,
+ 0xB5, 0x00, 0xEA, 0xAE, 0xB6, 0x00, 0xEA, 0xAE, 0xB7, 0x00, 0xEA, 0xAE,
+ 0xB8, 0x00, 0xEA, 0xAE, 0xB9, 0x00, 0xEA, 0xAE, 0xBA, 0x00, 0xEA, 0xAE,
+ 0xBB, 0x00, 0xEA, 0xAE, 0xBC, 0x00, 0xEA, 0xAE, 0xBD, 0x00, 0xEA, 0xAE,
+ 0xBE, 0x00, 0xEA, 0xAE, 0xBF, 0x00, 0xE1, 0x8F, 0xB8, 0x00, 0xE1, 0x8F,
+ 0xB9, 0x00, 0xE1, 0x8F, 0xBA, 0x00, 0xE1, 0x8F, 0xBB, 0x00, 0xE1, 0x8F,
+ 0xBC, 0x00, 0xE1, 0x8F, 0xBD, 0x00, 0xE1, 0xB8, 0x81, 0x00, 0xE1, 0xB8,
+ 0x83, 0x00, 0xE1, 0xB8, 0x85, 0x00, 0xE1, 0xB8, 0x87, 0x00, 0xE1, 0xB8,
+ 0x89, 0x00, 0xE1, 0xB8, 0x8B, 0x00, 0xE1, 0xB8, 0x8D, 0x00, 0xE1, 0xB8,
+ 0x8F, 0x00, 0xE1, 0xB8, 0x91, 0x00, 0xE1, 0xB8, 0x93, 0x00, 0xE1, 0xB8,
+ 0x95, 0x00, 0xE1, 0xB8, 0x97, 0x00, 0xE1, 0xB8, 0x99, 0x00, 0xE1, 0xB8,
+ 0x9B, 0x00, 0xE1, 0xB8, 0x9D, 0x00, 0xE1, 0xB8, 0x9F, 0x00, 0xE1, 0xB8,
+ 0xA1, 0x00, 0xE1, 0xB8, 0xA3, 0x00, 0xE1, 0xB8, 0xA5, 0x00, 0xE1, 0xB8,
+ 0xA7, 0x00, 0xE1, 0xB8, 0xA9, 0x00, 0xE1, 0xB8, 0xAB, 0x00, 0xE1, 0xB8,
+ 0xAD, 0x00, 0xE1, 0xB8, 0xAF, 0x00, 0xE1, 0xB8, 0xB1, 0x00, 0xE1, 0xB8,
+ 0xB3, 0x00, 0xE1, 0xB8, 0xB5, 0x00, 0xE1, 0xB8, 0xB7, 0x00, 0xE1, 0xB8,
+ 0xB9, 0x00, 0xE1, 0xB8, 0xBB, 0x00, 0xE1, 0xB8, 0xBD, 0x00, 0xE1, 0xB8,
+ 0xBF, 0x00, 0xE1, 0xB9, 0x81, 0x00, 0xE1, 0xB9, 0x83, 0x00, 0xE1, 0xB9,
+ 0x85, 0x00, 0xE1, 0xB9, 0x87, 0x00, 0xE1, 0xB9, 0x89, 0x00, 0xE1, 0xB9,
+ 0x8B, 0x00, 0xE1, 0xB9, 0x8D, 0x00, 0xE1, 0xB9, 0x8F, 0x00, 0xE1, 0xB9,
+ 0x91, 0x00, 0xE1, 0xB9, 0x93, 0x00, 0xE1, 0xB9, 0x95, 0x00, 0xE1, 0xB9,
+ 0x97, 0x00, 0xE1, 0xB9, 0x99, 0x00, 0xE1, 0xB9, 0x9B, 0x00, 0xE1, 0xB9,
+ 0x9D, 0x00, 0xE1, 0xB9, 0x9F, 0x00, 0xE1, 0xB9, 0xA1, 0x00, 0xE1, 0xB9,
+ 0xA3, 0x00, 0xE1, 0xB9, 0xA5, 0x00, 0xE1, 0xB9, 0xA7, 0x00, 0xE1, 0xB9,
+ 0xA9, 0x00, 0xE1, 0xB9, 0xAB, 0x00, 0xE1, 0xB9, 0xAD, 0x00, 0xE1, 0xB9,
+ 0xAF, 0x00, 0xE1, 0xB9, 0xB1, 0x00, 0xE1, 0xB9, 0xB3, 0x00, 0xE1, 0xB9,
+ 0xB5, 0x00, 0xE1, 0xB9, 0xB7, 0x00, 0xE1, 0xB9, 0xB9, 0x00, 0xE1, 0xB9,
+ 0xBB, 0x00, 0xE1, 0xB9, 0xBD, 0x00, 0xE1, 0xB9, 0xBF, 0x00, 0xE1, 0xBA,
+ 0x81, 0x00, 0xE1, 0xBA, 0x83, 0x00, 0xE1, 0xBA, 0x85, 0x00, 0xE1, 0xBA,
+ 0x87, 0x00, 0xE1, 0xBA, 0x89, 0x00, 0xE1, 0xBA, 0x8B, 0x00, 0xE1, 0xBA,
+ 0x8D, 0x00, 0xE1, 0xBA, 0x8F, 0x00, 0xE1, 0xBA, 0x91, 0x00, 0xF0, 0x9E,
+ 0xA4, 0xA2, 0x00, 0xF0, 0x9E, 0xA4, 0xA3, 0x00, 0xF0, 0x9E, 0xA4, 0xA4,
+ 0x00, 0xF0, 0x9E, 0xA4, 0xA5, 0x00, 0xF0, 0x9E, 0xA4, 0xA6, 0x00, 0xF0,
+ 0x9E, 0xA4, 0xA7, 0x00, 0xF0, 0x9E, 0xA4, 0xA8, 0x00, 0xF0, 0x9E, 0xA4,
+ 0xA9, 0x00, 0xF0, 0x9E, 0xA4, 0xAA, 0x00, 0xF0, 0x9E, 0xA4, 0xAB, 0x00,
+ 0xF0, 0x9E, 0xA4, 0xAC, 0x00, 0xF0, 0x9E, 0xA4, 0xAD, 0x00, 0xF0, 0x9E,
+ 0xA4, 0xAE, 0x00, 0xF0, 0x9E, 0xA4, 0xAF, 0x00, 0xF0, 0x9E, 0xA4, 0xB0,
+ 0x00, 0xF0, 0x9E, 0xA4, 0xB1, 0x00, 0xF0, 0x9E, 0xA4, 0xB2, 0x00, 0xF0,
+ 0x9E, 0xA4, 0xB3, 0x00, 0xF0, 0x9E, 0xA4, 0xB4, 0x00, 0xF0, 0x9E, 0xA4,
+ 0xB5, 0x00, 0xF0, 0x9E, 0xA4, 0xB6, 0x00, 0xF0, 0x9E, 0xA4, 0xB7, 0x00,
+ 0xF0, 0x9E, 0xA4, 0xB8, 0x00, 0xF0, 0x9E, 0xA4, 0xB9, 0x00, 0xF0, 0x9E,
+ 0xA4, 0xBA, 0x00, 0xF0, 0x9E, 0xA4, 0xBB, 0x00, 0xF0, 0x9E, 0xA4, 0xBC,
+ 0x00, 0xF0, 0x9E, 0xA4, 0xBD, 0x00, 0xF0, 0x9E, 0xA4, 0xBE, 0x00, 0xF0,
+ 0x9E, 0xA4, 0xBF, 0x00, 0xF0, 0x9E, 0xA5, 0x80, 0x00, 0xF0, 0x9E, 0xA5,
+ 0x81, 0x00, 0xE1, 0xBA, 0x93, 0x00, 0xF0, 0x9E, 0xA5, 0x82, 0x00, 0xF0,
+ 0x9E, 0xA5, 0x83, 0x00, 0xE1, 0xBA, 0x95, 0x00, 0xC3, 0x9F, 0x00, 0xE1,
+ 0xBA, 0xA1, 0x00, 0xE1, 0xBA, 0xA3, 0x00, 0xE1, 0xBA, 0xA5, 0x00, 0xE1,
+ 0xBA, 0xA7, 0x00, 0xE1, 0xBA, 0xA9, 0x00, 0xE1, 0xBA, 0xAB, 0x00, 0xE1,
+ 0xBA, 0xAD, 0x00, 0xE1, 0xBA, 0xAF, 0x00, 0xE1, 0xBA, 0xB1, 0x00, 0xE1,
+ 0xBA, 0xB3, 0x00, 0xE1, 0xBA, 0xB5, 0x00, 0xE1, 0xBA, 0xB7, 0x00, 0xE1,
+ 0xBA, 0xB9, 0x00, 0xE1, 0xBA, 0xBB, 0x00, 0xE1, 0xBA, 0xBD, 0x00, 0xE1,
+ 0xBA, 0xBF, 0x00, 0xE1, 0xBB, 0x81, 0x00, 0xE1, 0xBB, 0x83, 0x00, 0xE1,
+ 0xBB, 0x85, 0x00, 0xE1, 0xBB, 0x87, 0x00, 0xE1, 0xBB, 0x89, 0x00, 0xE1,
+ 0xBB, 0x8B, 0x00, 0xE1, 0xBB, 0x8D, 0x00, 0xE1, 0xBB, 0x8F, 0x00, 0xE1,
+ 0xBB, 0x91, 0x00, 0xE1, 0xBB, 0x93, 0x00, 0xE1, 0xBB, 0x95, 0x00, 0xE1,
+ 0xBB, 0x97, 0x00, 0xE1, 0xBB, 0x99, 0x00, 0xE1, 0xBB, 0x9B, 0x00, 0xE1,
+ 0xBB, 0x9D, 0x00, 0xE1, 0xBB, 0x9F, 0x00, 0xE1, 0xBB, 0xA1, 0x00, 0xE1,
+ 0xBB, 0xA3, 0x00, 0xE1, 0xBB, 0xA5, 0x00, 0xE1, 0xBB, 0xA7, 0x00, 0xE1,
+ 0xBB, 0xA9, 0x00, 0xE1, 0xBB, 0xAB, 0x00, 0xE1, 0xBB, 0xAD, 0x00, 0xE1,
+ 0xBB, 0xAF, 0x00, 0xE1, 0xBB, 0xB1, 0x00, 0xE1, 0xBB, 0xB3, 0x00, 0xE1,
+ 0xBB, 0xB5, 0x00, 0xE1, 0xBB, 0xB7, 0x00, 0xE1, 0xBB, 0xB9, 0x00, 0xE1,
+ 0xBB, 0xBB, 0x00, 0xE1, 0xBB, 0xBD, 0x00, 0xE1, 0xBB, 0xBF, 0x00, 0xE1,
+ 0xBC, 0x80, 0x00, 0xE1, 0xBC, 0x81, 0x00, 0xE1, 0xBC, 0x82, 0x00, 0xE1,
+ 0xBC, 0x83, 0x00, 0xE1, 0xBC, 0x84, 0x00, 0xE1, 0xBC, 0x85, 0x00, 0xE1,
+ 0xBC, 0x86, 0x00, 0xE1, 0xBC, 0x87, 0x00, 0xE1, 0xBC, 0x90, 0x00, 0xE1,
+ 0xBC, 0x91, 0x00, 0xE1, 0xBC, 0x92, 0x00, 0xE1, 0xBC, 0x93, 0x00, 0xE1,
+ 0xBC, 0x94, 0x00, 0xE1, 0xBC, 0x95, 0x00, 0xE1, 0xBC, 0xA0, 0x00, 0xE1,
+ 0xBC, 0xA1, 0x00, 0xE1, 0xBC, 0xA2, 0x00, 0xE1, 0xBC, 0xA3, 0x00, 0xE1,
+ 0xBC, 0xA4, 0x00, 0xE1, 0xBC, 0xA5, 0x00, 0xE1, 0xBC, 0xA6, 0x00, 0xE1,
+ 0xBC, 0xA7, 0x00, 0xE1, 0xBC, 0xB0, 0x00, 0xE1, 0xBC, 0xB1, 0x00, 0xE1,
+ 0xBC, 0xB2, 0x00, 0xE1, 0xBC, 0xB3, 0x00, 0xE1, 0xBC, 0xB4, 0x00, 0xE1,
+ 0xBC, 0xB5, 0x00, 0xE1, 0xBC, 0xB6, 0x00, 0xE1, 0xBC, 0xB7, 0x00, 0xE1,
+ 0xBD, 0x80, 0x00, 0xE1, 0xBD, 0x81, 0x00, 0xE1, 0xBD, 0x82, 0x00, 0xE1,
+ 0xBD, 0x83, 0x00, 0xE1, 0xBD, 0x84, 0x00, 0xE1, 0xBD, 0x85, 0x00, 0xE1,
+ 0xBD, 0x91, 0x00, 0xE1, 0xBD, 0x93, 0x00, 0xE1, 0xBD, 0x95, 0x00, 0xE1,
+ 0xBD, 0x97, 0x00, 0xE1, 0xBD, 0xA0, 0x00, 0xE1, 0xBD, 0xA1, 0x00, 0xE1,
+ 0xBD, 0xA2, 0x00, 0xE1, 0xBD, 0xA3, 0x00, 0xE1, 0xBD, 0xA4, 0x00, 0xE1,
+ 0xBD, 0xA5, 0x00, 0xE1, 0xBD, 0xA6, 0x00, 0xE1, 0xBD, 0xA7, 0x00, 0xE1,
+ 0xBE, 0x80, 0x00, 0xE1, 0xBE, 0x81, 0x00, 0xE1, 0xBE, 0x82, 0x00, 0xE1,
+ 0xBE, 0x83, 0x00, 0xE1, 0xBE, 0x84, 0x00, 0xE1, 0xBE, 0x85, 0x00, 0xE1,
+ 0xBE, 0x86, 0x00, 0xE1, 0xBE, 0x87, 0x00, 0xE1, 0xBE, 0x90, 0x00, 0xE1,
+ 0xBE, 0x91, 0x00, 0xE1, 0xBE, 0x92, 0x00, 0xE1, 0xBE, 0x93, 0x00, 0xE1,
+ 0xBE, 0x94, 0x00, 0xE1, 0xBE, 0x95, 0x00, 0xE1, 0xBE, 0x96, 0x00, 0xE1,
+ 0xBE, 0x97, 0x00, 0xE1, 0xBE, 0xA0, 0x00, 0xE1, 0xBE, 0xA1, 0x00, 0xE1,
+ 0xBE, 0xA2, 0x00, 0xE1, 0xBE, 0xA3, 0x00, 0xE1, 0xBE, 0xA4, 0x00, 0xE1,
+ 0xBE, 0xA5, 0x00, 0xE1, 0xBE, 0xA6, 0x00, 0xE1, 0xBE, 0xA7, 0x00, 0xE1,
+ 0xBE, 0xB0, 0x00, 0xE1, 0xBE, 0xB1, 0x00, 0xE1, 0xBD, 0xB0, 0x00, 0xE1,
+ 0xBD, 0xB1, 0x00, 0xE1, 0xBE, 0xB3, 0x00, 0xE1, 0xBD, 0xB2, 0x00, 0xE1,
+ 0xBD, 0xB3, 0x00, 0xE1, 0xBD, 0xB4, 0x00, 0xE1, 0xBD, 0xB5, 0x00, 0xE1,
+ 0xBF, 0x83, 0x00, 0xE1, 0xBF, 0x90, 0x00, 0xE1, 0xBF, 0x91, 0x00, 0xE1,
+ 0xBD, 0xB6, 0x00, 0xE1, 0xBD, 0xB7, 0x00, 0xE1, 0xBF, 0xA0, 0x00, 0xE1,
+ 0xBF, 0xA1, 0x00, 0xE1, 0xBD, 0xBA, 0x00, 0xE1, 0xBD, 0xBB, 0x00, 0xE1,
+ 0xBF, 0xA5, 0x00, 0xE1, 0xBD, 0xB8, 0x00, 0xE1, 0xBD, 0xB9, 0x00, 0xE1,
+ 0xBD, 0xBC, 0x00, 0xE1, 0xBD, 0xBD, 0x00, 0xE1, 0xBF, 0xB3, 0x00, 0xCF,
+ 0x89, 0x00, 0x6B, 0x00, 0xC3, 0xA5, 0x00, 0xE2, 0x85, 0x8E, 0x00, 0xE2,
+ 0x85, 0xB0, 0x00, 0xE2, 0x85, 0xB1, 0x00, 0xE2, 0x85, 0xB2, 0x00, 0xE2,
+ 0x85, 0xB3, 0x00, 0xE2, 0x85, 0xB4, 0x00, 0xE2, 0x85, 0xB5, 0x00, 0xE2,
+ 0x85, 0xB6, 0x00, 0xE2, 0x85, 0xB7, 0x00, 0xE2, 0x85, 0xB8, 0x00, 0xE2,
+ 0x85, 0xB9, 0x00, 0xE2, 0x85, 0xBA, 0x00, 0xE2, 0x85, 0xBB, 0x00, 0xE2,
+ 0x85, 0xBC, 0x00, 0xE2, 0x85, 0xBD, 0x00, 0xE2, 0x85, 0xBE, 0x00, 0xE2,
+ 0x85, 0xBF, 0x00, 0xE2, 0x86, 0x84, 0x00, 0xE2, 0x93, 0x90, 0x00, 0xE2,
+ 0x93, 0x91, 0x00, 0xE2, 0x93, 0x92, 0x00, 0xE2, 0x93, 0x93, 0x00, 0xE2,
+ 0x93, 0x94, 0x00, 0xE2, 0x93, 0x95, 0x00, 0xE2, 0x93, 0x96, 0x00, 0xE2,
+ 0x93, 0x97, 0x00, 0xE2, 0x93, 0x98, 0x00, 0xE2, 0x93, 0x99, 0x00, 0xE2,
+ 0x93, 0x9A, 0x00, 0xE2, 0x93, 0x9B, 0x00, 0xE2, 0x93, 0x9C, 0x00, 0xE2,
+ 0x93, 0x9D, 0x00, 0xE2, 0x93, 0x9E, 0x00, 0xE2, 0x93, 0x9F, 0x00, 0xE2,
+ 0x93, 0xA0, 0x00, 0xE2, 0x93, 0xA1, 0x00, 0xE2, 0x93, 0xA2, 0x00, 0xE2,
+ 0x93, 0xA3, 0x00, 0xE2, 0x93, 0xA4, 0x00, 0xE2, 0x93, 0xA5, 0x00, 0xE2,
+ 0x93, 0xA6, 0x00, 0xE2, 0x93, 0xA7, 0x00, 0xE2, 0x93, 0xA8, 0x00, 0xE2,
+ 0x93, 0xA9, 0x00, 0xE2, 0xB0, 0xB0, 0x00, 0xE2, 0xB0, 0xB1, 0x00, 0xE2,
+ 0xB0, 0xB2, 0x00, 0xE2, 0xB0, 0xB3, 0x00, 0xE2, 0xB0, 0xB4, 0x00, 0xE2,
+ 0xB0, 0xB5, 0x00, 0xE2, 0xB0, 0xB6, 0x00, 0xE2, 0xB0, 0xB7, 0x00, 0xE2,
+ 0xB0, 0xB8, 0x00, 0xE2, 0xB0, 0xB9, 0x00, 0xE2, 0xB0, 0xBA, 0x00, 0xE2,
+ 0xB0, 0xBB, 0x00, 0xE2, 0xB0, 0xBC, 0x00, 0xE2, 0xB0, 0xBD, 0x00, 0xE2,
+ 0xB0, 0xBE, 0x00, 0xE2, 0xB0, 0xBF, 0x00, 0xE2, 0xB1, 0x80, 0x00, 0xE2,
+ 0xB1, 0x81, 0x00, 0xE2, 0xB1, 0x82, 0x00, 0xE2, 0xB1, 0x83, 0x00, 0xE2,
+ 0xB1, 0x84, 0x00, 0xE2, 0xB1, 0x85, 0x00, 0xE2, 0xB1, 0x86, 0x00, 0xE2,
+ 0xB1, 0x87, 0x00, 0xE2, 0xB1, 0x88, 0x00, 0xE2, 0xB1, 0x89, 0x00, 0xE2,
+ 0xB1, 0x8A, 0x00, 0xE2, 0xB1, 0x8B, 0x00, 0xE2, 0xB1, 0x8C, 0x00, 0xE2,
+ 0xB1, 0x8D, 0x00, 0xE2, 0xB1, 0x8E, 0x00, 0xE2, 0xB1, 0x8F, 0x00, 0xE2,
+ 0xB1, 0x90, 0x00, 0xE2, 0xB1, 0x91, 0x00, 0xE2, 0xB1, 0x92, 0x00, 0xE2,
+ 0xB1, 0x93, 0x00, 0xE2, 0xB1, 0x94, 0x00, 0xE2, 0xB1, 0x95, 0x00, 0xE2,
+ 0xB1, 0x96, 0x00, 0xE2, 0xB1, 0x97, 0x00, 0xE2, 0xB1, 0x98, 0x00, 0xE2,
+ 0xB1, 0x99, 0x00, 0xE2, 0xB1, 0x9A, 0x00, 0xE2, 0xB1, 0x9B, 0x00, 0xE2,
+ 0xB1, 0x9C, 0x00, 0xE2, 0xB1, 0x9D, 0x00, 0xE2, 0xB1, 0x9E, 0x00, 0xE2,
+ 0xB1, 0xA1, 0x00, 0xC9, 0xAB, 0x00, 0xE1, 0xB5, 0xBD, 0x00, 0xC9, 0xBD,
+ 0x00, 0xE2, 0xB1, 0xA8, 0x00, 0xE2, 0xB1, 0xAA, 0x00, 0xE2, 0xB1, 0xAC,
+ 0x00, 0xC9, 0x91, 0x00, 0xC9, 0xB1, 0x00, 0xC9, 0x90, 0x00, 0xC9, 0x92,
+ 0x00, 0xE2, 0xB1, 0xB3, 0x00, 0xE2, 0xB1, 0xB6, 0x00, 0xC8, 0xBF, 0x00,
+ 0xC9, 0x80, 0x00, 0xE2, 0xB2, 0x81, 0x00, 0xE2, 0xB2, 0x83, 0x00, 0xE2,
+ 0xB2, 0x85, 0x00, 0xE2, 0xB2, 0x87, 0x00, 0xE2, 0xB2, 0x89, 0x00, 0xE2,
+ 0xB2, 0x8B, 0x00, 0xE2, 0xB2, 0x8D, 0x00, 0xE2, 0xB2, 0x8F, 0x00, 0xE2,
+ 0xB2, 0x91, 0x00, 0xE2, 0xB2, 0x93, 0x00, 0xE2, 0xB2, 0x95, 0x00, 0xE2,
+ 0xB2, 0x97, 0x00, 0xE2, 0xB2, 0x99, 0x00, 0xE2, 0xB2, 0x9B, 0x00, 0xE2,
+ 0xB2, 0x9D, 0x00, 0xE2, 0xB2, 0x9F, 0x00, 0xE2, 0xB2, 0xA1, 0x00, 0xE2,
+ 0xB2, 0xA3, 0x00, 0xE2, 0xB2, 0xA5, 0x00, 0xE2, 0xB2, 0xA7, 0x00, 0xE2,
+ 0xB2, 0xA9, 0x00, 0xE2, 0xB2, 0xAB, 0x00, 0xE2, 0xB2, 0xAD, 0x00, 0xE2,
+ 0xB2, 0xAF, 0x00, 0xE2, 0xB2, 0xB1, 0x00, 0xE2, 0xB2, 0xB3, 0x00, 0xE2,
+ 0xB2, 0xB5, 0x00, 0xE2, 0xB2, 0xB7, 0x00, 0xE2, 0xB2, 0xB9, 0x00, 0xE2,
+ 0xB2, 0xBB, 0x00, 0xE2, 0xB2, 0xBD, 0x00, 0xE2, 0xB2, 0xBF, 0x00, 0xE2,
+ 0xB3, 0x81, 0x00, 0xE2, 0xB3, 0x83, 0x00, 0xE2, 0xB3, 0x85, 0x00, 0xE2,
+ 0xB3, 0x87, 0x00, 0xE2, 0xB3, 0x89, 0x00, 0xE2, 0xB3, 0x8B, 0x00, 0xE2,
+ 0xB3, 0x8D, 0x00, 0xE2, 0xB3, 0x8F, 0x00, 0xE2, 0xB3, 0x91, 0x00, 0xE2,
+ 0xB3, 0x93, 0x00, 0xE2, 0xB3, 0x95, 0x00, 0xE2, 0xB3, 0x97, 0x00, 0xE2,
+ 0xB3, 0x99, 0x00, 0xE2, 0xB3, 0x9B, 0x00, 0xE2, 0xB3, 0x9D, 0x00, 0xE2,
+ 0xB3, 0x9F, 0x00, 0xE2, 0xB3, 0xA1, 0x00, 0xE2, 0xB3, 0xA3, 0x00, 0xE2,
+ 0xB3, 0xAC, 0x00, 0xE2, 0xB3, 0xAE, 0x00, 0xE2, 0xB3, 0xB3, 0x00, 0xEA,
+ 0x99, 0x81, 0x00, 0xEA, 0x99, 0x83, 0x00, 0xEA, 0x99, 0x85, 0x00, 0xEA,
+ 0x99, 0x87, 0x00, 0xEA, 0x99, 0x89, 0x00, 0xEA, 0x99, 0x8B, 0x00, 0xEA,
+ 0x99, 0x8D, 0x00, 0xEA, 0x99, 0x8F, 0x00, 0xEA, 0x99, 0x91, 0x00, 0xEA,
+ 0x99, 0x93, 0x00, 0xEA, 0x99, 0x95, 0x00, 0xEA, 0x99, 0x97, 0x00, 0xEA,
+ 0x99, 0x99, 0x00, 0xEA, 0x99, 0x9B, 0x00, 0xEA, 0x99, 0x9D, 0x00, 0xEA,
+ 0x99, 0x9F, 0x00, 0xEA, 0x99, 0xA1, 0x00, 0xEA, 0x99, 0xA3, 0x00, 0xEA,
+ 0x99, 0xA5, 0x00, 0xEA, 0x99, 0xA7, 0x00, 0xEA, 0x99, 0xA9, 0x00, 0xEA,
+ 0x99, 0xAB, 0x00, 0xEA, 0x99, 0xAD, 0x00, 0xEA, 0x9A, 0x81, 0x00, 0xEA,
+ 0x9A, 0x83, 0x00, 0xEA, 0x9A, 0x85, 0x00, 0xEA, 0x9A, 0x87, 0x00, 0xEA,
+ 0x9A, 0x89, 0x00, 0xEA, 0x9A, 0x8B, 0x00, 0xEA, 0x9A, 0x8D, 0x00, 0xEA,
+ 0x9A, 0x8F, 0x00, 0xEA, 0x9A, 0x91, 0x00, 0xEA, 0x9A, 0x93, 0x00, 0xEA,
+ 0x9A, 0x95, 0x00, 0xEA, 0x9A, 0x97, 0x00, 0xEA, 0x9A, 0x99, 0x00, 0xEA,
+ 0x9A, 0x9B, 0x00, 0xEA, 0x9C, 0xA3, 0x00, 0xEA, 0x9C, 0xA5, 0x00, 0xEA,
+ 0x9C, 0xA7, 0x00, 0xEA, 0x9C, 0xA9, 0x00, 0xEA, 0x9C, 0xAB, 0x00, 0xEA,
+ 0x9C, 0xAD, 0x00, 0xEA, 0x9C, 0xAF, 0x00, 0xEA, 0x9C, 0xB3, 0x00, 0xEA,
+ 0x9C, 0xB5, 0x00, 0xEA, 0x9C, 0xB7, 0x00, 0xEA, 0x9C, 0xB9, 0x00, 0xEA,
+ 0x9C, 0xBB, 0x00, 0xEA, 0x9C, 0xBD, 0x00, 0xEA, 0x9C, 0xBF, 0x00, 0xEA,
+ 0x9D, 0x81, 0x00, 0xEA, 0x9D, 0x83, 0x00, 0xEA, 0x9D, 0x85, 0x00, 0xEA,
+ 0x9D, 0x87, 0x00, 0xEA, 0x9D, 0x89, 0x00, 0xEA, 0x9D, 0x8B, 0x00, 0xEA,
+ 0x9D, 0x8D, 0x00, 0xEA, 0x9D, 0x8F, 0x00, 0xEA, 0x9D, 0x91, 0x00, 0xEA,
+ 0x9D, 0x93, 0x00, 0xEA, 0x9D, 0x95, 0x00, 0xEA, 0x9D, 0x97, 0x00, 0xEA,
+ 0x9D, 0x99, 0x00, 0xEA, 0x9D, 0x9B, 0x00, 0xEA, 0x9D, 0x9D, 0x00, 0xEA,
+ 0x9D, 0x9F, 0x00, 0xEA, 0x9D, 0xA1, 0x00, 0xEA, 0x9D, 0xA3, 0x00, 0xEA,
+ 0x9D, 0xA5, 0x00, 0xEA, 0x9D, 0xA7, 0x00, 0xEA, 0x9D, 0xA9, 0x00, 0xEA,
+ 0x9D, 0xAB, 0x00, 0xEA, 0x9D, 0xAD, 0x00, 0xEA, 0x9D, 0xAF, 0x00, 0xEA,
+ 0x9D, 0xBA, 0x00, 0xEA, 0x9D, 0xBC, 0x00, 0xE1, 0xB5, 0xB9, 0x00, 0xEA,
+ 0x9D, 0xBF, 0x00, 0xEA, 0x9E, 0x81, 0x00, 0xEA, 0x9E, 0x83, 0x00, 0xEA,
+ 0x9E, 0x85, 0x00, 0xEA, 0x9E, 0x87, 0x00, 0xEA, 0x9E, 0x8C, 0x00, 0xC9,
+ 0xA5, 0x00, 0xEA, 0x9E, 0x91, 0x00, 0xEA, 0x9E, 0x93, 0x00, 0xEA, 0x9E,
+ 0x97, 0x00, 0xEA, 0x9E, 0x99, 0x00, 0xEA, 0x9E, 0x9B, 0x00, 0xEA, 0x9E,
+ 0x9D, 0x00, 0xEA, 0x9E, 0x9F, 0x00, 0xEA, 0x9E, 0xA1, 0x00, 0xEA, 0x9E,
+ 0xA3, 0x00, 0xEA, 0x9E, 0xA5, 0x00, 0xEA, 0x9E, 0xA7, 0x00, 0xEA, 0x9E,
+ 0xA9, 0x00, 0xC9, 0xA6, 0x00, 0xC9, 0x9C, 0x00, 0xC9, 0xA1, 0x00, 0xC9,
+ 0xAC, 0x00, 0xC9, 0xAA, 0x00, 0xCA, 0x9E, 0x00, 0xCA, 0x87, 0x00, 0xCA,
+ 0x9D, 0x00, 0xEA, 0xAD, 0x93, 0x00, 0xEA, 0x9E, 0xB5, 0x00, 0xEA, 0x9E,
+ 0xB7, 0x00, 0xEF, 0xBD, 0x81, 0x00, 0xEF, 0xBD, 0x82, 0x00, 0xEF, 0xBD,
+ 0x83, 0x00, 0xEF, 0xBD, 0x84, 0x00, 0xEF, 0xBD, 0x85, 0x00, 0xEF, 0xBD,
+ 0x86, 0x00, 0xEF, 0xBD, 0x87, 0x00, 0xEF, 0xBD, 0x88, 0x00, 0xEF, 0xBD,
+ 0x89, 0x00, 0xEF, 0xBD, 0x8A, 0x00, 0xEF, 0xBD, 0x8B, 0x00, 0xEF, 0xBD,
+ 0x8C, 0x00, 0xEF, 0xBD, 0x8D, 0x00, 0xEF, 0xBD, 0x8E, 0x00, 0xEF, 0xBD,
+ 0x8F, 0x00, 0xEF, 0xBD, 0x90, 0x00, 0xEF, 0xBD, 0x91, 0x00, 0xEF, 0xBD,
+ 0x92, 0x00, 0xEF, 0xBD, 0x93, 0x00, 0xEF, 0xBD, 0x94, 0x00, 0xEF, 0xBD,
+ 0x95, 0x00, 0xEF, 0xBD, 0x96, 0x00, 0xEF, 0xBD, 0x97, 0x00, 0xEF, 0xBD,
+ 0x98, 0x00, 0xEF, 0xBD, 0x99, 0x00, 0xEF, 0xBD, 0x9A, 0x00, 0x69, 0xCC,
+ 0x87, 0x00, 0xE1, 0xBE, 0x80, 0x00, 0xE1, 0xBE, 0x81, 0x00, 0xE1, 0xBE,
+ 0x82, 0x00, 0xE1, 0xBE, 0x83, 0x00, 0xE1, 0xBE, 0x84, 0x00, 0xE1, 0xBE,
+ 0x85, 0x00, 0xE1, 0xBE, 0x86, 0x00, 0xE1, 0xBE, 0x87, 0x00, 0xE1, 0xBE,
+ 0x90, 0x00, 0xE1, 0xBE, 0x91, 0x00, 0xE1, 0xBE, 0x92, 0x00, 0xE1, 0xBE,
+ 0x93, 0x00, 0xE1, 0xBE, 0x94, 0x00, 0xE1, 0xBE, 0x95, 0x00, 0xE1, 0xBE,
+ 0x96, 0x00, 0xE1, 0xBE, 0x97, 0x00, 0xE1, 0xBE, 0xA0, 0x00, 0xE1, 0xBE,
+ 0xA1, 0x00, 0xE1, 0xBE, 0xA2, 0x00, 0xE1, 0xBE, 0xA3, 0x00, 0xE1, 0xBE,
+ 0xA4, 0x00, 0xE1, 0xBE, 0xA5, 0x00, 0xE1, 0xBE, 0xA6, 0x00, 0xE1, 0xBE,
+ 0xA7, 0x00, 0xE1, 0xBE, 0xB3, 0x00, 0xE1, 0xBF, 0x83, 0x00, 0xE1, 0xBF,
+ 0xB3, 0x00,
+};
+
diff --git a/vendor/nunicode/src/libnu/gen/_tounaccent.c b/vendor/nunicode/src/libnu/gen/_tounaccent.c
new file mode 100644
index 0000000000..d672d6368b
--- /dev/null
+++ b/vendor/nunicode/src/libnu/gen/_tounaccent.c
@@ -0,0 +1,460 @@
+/* Automatically generated file (mph.py), 1491062342
+ *
+ * Tag : NU_TOUNACCENT
+ * Prime : 01000193,
+ * G size : 845,
+ * Combined length : 2082,
+ * Encoding : UTF-8
+ */
+
+#include <stdint.h>
+
+const int16_t NU_TOUNACCENT_G[] = {
+ -845, -844, -843, -842, -841, -840, -839, -838, -837, -836, -834, -833,
+ -832, -831, -830, -829, -828, 0, -827, 0, -826, 0, -825, 0,
+ -824, -823, -822, -821, 0, 0, -820, -819, -818, -817, -816, -815,
+ 0, 0, -814, -813, -812, -811, -810, -809, -808, -807, -806, -805,
+ -804, -803, -802, -801, 0, 0, -800, -799, -798, -797, -796, -795,
+ -794, 1, 1, 1, -793, -792, 1, 1, 1, 1, 1, 1,
+ 1, -791, -790, 11, 2, 1, 1, 5, -789, -788, -787, 2,
+ -786, -785, -784, -783, 1, 30, 2, 32, 32, 2, 24, 18,
+ -782, -781, 48, 48, 52, 49, 20, 49, 1, 4, -780, 5,
+ 6, 10, 17, 30, 16, 66, -779, 68, 68, 65, 20, 69,
+ 65, 24, 65, 79, 65, -778, -777, -776, -775, -774, -773, -772,
+ -771, -770, -769, -768, -767, -766, -765, -764, -763, -762, -761, -760,
+ -759, -758, -757, -756, -755, -754, -753, -752, -751, -750, -749, -748,
+ -747, -746, -745, -744, -743, -742, -741, -740, -739, -738, -737, -736,
+ -735, -734, -733, -732, -731, -730, -729, -728, 0, 0, -727, -726,
+ 0, 0, 0, 0, -725, -724, -723, -722, -721, -720, -719, -718,
+ -717, -716, -715, -714, -713, -712, -711, -710, -709, -708, -707, -706,
+ -705, -704, -703, -702, -701, -700, -699, -698, -697, -696, -695, -694,
+ -693, -692, -691, -690, -689, -688, -687, -686, -685, -684, -683, -682,
+ -681, -680, -679, -678, -677, -676, -675, -674, -673, -672, -671, -670,
+ 1, 1, 4, 1, 1, 1, -669, -668, 1, 1, -667, -666,
+ 1, 1, 1, 1, 1, 1, 1, -665, -664, -663, -662, -661,
+ -660, -659, -658, -657, -656, 2, 21, -655, 9, 1, 1, 1,
+ -654, 16, 1, 1, 1, 5, 2, 1, 1, -653, -652, -651,
+ 1, 1, -650, -649, 2, 1, 4, 8, 1, 1, -648, -647,
+ 1, 6, 4, 18, -646, -645, -644, -643, -642, 10, 18, 16,
+ 9, 1, 1, 5, 9, -641, -640, -639, 88, -638, 88, 88,
+ 88, -637, -636, -635, 0, 0, 0, 0, 0, -634, -633, -632,
+ -631, -630, 0, 0, 0, -629, -628, 0, 0, 0, 64, -627,
+ -626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -625, -624, -623, -622, 0, -621, 0, -620, 6,
+ 11, 0, 0, 0, 0, -619, -618, 0, 0, -617, -616, -615,
+ 0, 0, 0, 0, 0, -614, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -613, 0, -612, 6, 0, 0,
+ 0, 0, -611, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -610, -609, -608, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -607, 0, -606, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -605, 0, -604, 0, 0, -603, 0,
+ 0, -602, 0, 0, 0, 0, 0, 0, 0, -601, -600, 0,
+ 0, -599, -598, 0, 0, -597, -596, 0, 0, 0, 0, 0,
+ -595, 0, -594, 0, 0, 0, 0, 0, 0, 0, 0, -593,
+ -592, -591, 0, 0, 0, 0, 0, 0, -590, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -589, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -588, 2, -379, -336, -297, -295, -293, -290, -289, -277, 6, -152,
+ -148, -145, 1, -136, -132, 1, 1, 5, 5, 16, 16, 13,
+ 16, 1, 4, 2, 7, 8, 8, 20, 22, 1, 1, 1,
+ 1, -97, -73, -72, -58, -57, 32, 32, 37, -54, -53, -52,
+ -50, 8, -48, -47, 2, 2, 1, 9, 56, 1, 4, 2,
+ 14, 16, 16, -46, 1, 39, 71, 80, -41, 0, -39, -34,
+ 82, 84, 80, 80, 88, 96, 12, 12, 64, 64, 64, 68,
+ 73, 64, 66, 81, 85, 1, 2, 2, 5, 9, 1, -32,
+ -31, 17, 23, 17, 34, 30, 33, 35, -30, 27, 20, 24,
+ -29, 49, -28, 0, -27, 9, 15, 20, 181, 254, 253, 249,
+ 252, -26, -25, -24, -23, 2, 6, -22, 15, 224, 229, 259,
+ 261, -21, -20, -19, 258, 260, 262, 260, 265, 267, -18, -17,
+ 200, 256, 256, 280, 256, -16, 280, 280, 284, 5, 5, 1,
+ 5, -15, -14, 12, 12, -13, 18, 4, 42, -12, 0, -11,
+ -10, 33, 36, 32, 42, 41, 260, 44, 261, 38, 266, 73,
+ 268, 273, 257, 261, 286, 274, -9, 288, 261, 298, 256, 16,
+ 339, 336, -6, -4, 291, 338, 365, 365, 365, 330, 293, 295,
+ 308, 335, -3, -2, -1, };
+
+const size_t NU_TOUNACCENT_G_SIZE = sizeof(NU_TOUNACCENT_G) / sizeof(*NU_TOUNACCENT_G);
+
+/* codepoints */
+const uint32_t NU_TOUNACCENT_VALUES_C[] = {
+ 0x001F24, 0x001F25, 0x001F26, 0x001F39, 0x000169, 0x001F3A, 0x00016B, 0x00016A,
+ 0x001F32, 0x001F1C, 0x001F1D, 0x000144, 0x001F1B, 0x000143, 0x00015C, 0x000154,
+ 0x001FE5, 0x001FE6, 0x00012A, 0x00012B, 0x000124, 0x000122, 0x00013D, 0x00013E,
+ 0x001FF2, 0x001FF3, 0x001FC4, 0x001FC6, 0x00010D, 0x000109, 0x000101, 0x000102,
+ 0x000125, 0x0001EA, 0x000168, 0x00016C, 0x00012D, 0x000126, 0x0001EB, 0x00012C,
+ 0x001FB8, 0x00012F, 0x00012E, 0x000129, 0x000128, 0x00022D, 0x001F89, 0x001F8A,
+ 0x000160, 0x001F84, 0x000161, 0x001F85, 0x001F86, 0x001F87, 0x000164, 0x000385,
+ 0x001F83, 0x001F9C, 0x000386, 0x000389, 0x000388, 0x00038F, 0x00038A, 0x00038E,
+ 0x00038C, 0x0003CE, 0x00015A, 0x00015B, 0x000390, 0x000159, 0x000165, 0x001F9D,
+ 0x001F9E, 0x00016E, 0x00016F, 0x001F0A, 0x001F04, 0x001F06, 0x000156, 0x001F08,
+ 0x000150, 0x001F21, 0x001F22, 0x001F0D, 0x0003AB, 0x000155, 0x00017C, 0x000157,
+ 0x0003AC, 0x00016D, 0x001F0E, 0x0003AD, 0x001F31, 0x001F0C, 0x00017E, 0x001F20,
+ 0x001F9F, 0x0003AF, 0x0003AE, 0x000163, 0x0003B0, 0x000174, 0x001F38, 0x000179,
+ 0x001F37, 0x001F0F, 0x000178, 0x0003AA, 0x001F33, 0x001E23, 0x001E22, 0x001E25,
+ 0x001E24, 0x001E27, 0x001E26, 0x001E29, 0x000171, 0x001E2B, 0x001E2A, 0x000173,
+ 0x00017D, 0x000175, 0x00017B, 0x001E68, 0x001E69, 0x000177, 0x001E6B, 0x00017A,
+ 0x001F30, 0x001F36, 0x001E6F, 0x0001D1, 0x001E38, 0x001E3B, 0x001E3A, 0x0001D2,
+ 0x001E39, 0x001E3F, 0x001E3E, 0x001E55, 0x001E40, 0x001E43, 0x001E41, 0x001E4C,
+ 0x00021F, 0x001E47, 0x001E42, 0x000218, 0x001E4D, 0x001E4B, 0x001E4A, 0x000219,
+ 0x001E4F, 0x001E5E, 0x001E4E, 0x001F3D, 0x001F3C, 0x001E5B, 0x001F3E, 0x001E56,
+ 0x0000E4, 0x0000E5, 0x0000ED, 0x001E59, 0x001E58, 0x0000E7, 0x001E5A, 0x001E5D,
+ 0x001E5C, 0x0000E8, 0x0000EB, 0x001E61, 0x0000E9, 0x0000EC, 0x001E62, 0x0000EE,
+ 0x001E60, 0x001E74, 0x001F34, 0x001F27, 0x001F23, 0x001E63, 0x001F3B, 0x001E7C,
+ 0x001F3F, 0x001E67, 0x001E7D, 0x001E76, 0x001E75, 0x001E73, 0x001E72, 0x001E7E,
+ 0x0000F4, 0x001E77, 0x0000C3, 0x0000C2, 0x0000C1, 0x0000F5, 0x0000F6, 0x0000C5,
+ 0x0000F9, 0x0000C8, 0x0000FB, 0x000419, 0x0000CE, 0x001E83, 0x001E81, 0x001E86,
+ 0x0000D1, 0x0000CF, 0x0000D3, 0x0000D2, 0x0000D5, 0x0000D4, 0x0000DD, 0x0000D6,
+ 0x0000D9, 0x0000D8, 0x0000DB, 0x0000DA, 0x001E94, 0x001E93, 0x0000DC, 0x001E95,
+ 0x001E97, 0x001E84, 0x001E96, 0x0000F1, 0x001E8D, 0x001E98, 0x001E90, 0x001E82,
+ 0x001E85, 0x0000E3, 0x0000F2, 0x001E80, 0x0000CC, 0x0000CD, 0x0000FA, 0x001EB5,
+ 0x0000E0, 0x0000F3, 0x001E87, 0x0000E2, 0x001EBD, 0x001EB4, 0x001EBB, 0x0000EF,
+ 0x0000FD, 0x0000F8, 0x0000FC, 0x0000FF, 0x001EB7, 0x001EB3, 0x0000EA, 0x0000E1,
+ 0x001EB0, 0x001EB2, 0x000103, 0x001E88, 0x001E89, 0x001EA2, 0x001E8F, 0x001EB6,
+ 0x001E8C, 0x000450, 0x001E8E, 0x000400, 0x000401, 0x002209, 0x000403, 0x000457,
+ 0x000107, 0x000100, 0x000407, 0x000108, 0x00021B, 0x00011C, 0x00010E, 0x000106,
+ 0x00011D, 0x000118, 0x000104, 0x00010F, 0x00011E, 0x00011F, 0x000112, 0x000113,
+ 0x000214, 0x000215, 0x000136, 0x000476, 0x000216, 0x000123, 0x000217, 0x000105,
+ 0x000210, 0x00010A, 0x00010B, 0x001EA1, 0x000439, 0x001EA3, 0x000121, 0x001FE2,
+ 0x001FE1, 0x001EA7, 0x001FE3, 0x001FE8, 0x001FE0, 0x001FEA, 0x001FEB, 0x001FE7,
+ 0x000137, 0x000130, 0x001EA0, 0x001FEC, 0x001FE9, 0x00010C, 0x00013C, 0x000176,
+ 0x001FED, 0x001FEE, 0x000146, 0x001EBA, 0x001EBC, 0x001FF9, 0x001EBF, 0x001EB8,
+ 0x001FF8, 0x001FFC, 0x001EBE, 0x00011A, 0x000119, 0x000141, 0x000142, 0x000211,
+ 0x000110, 0x000111, 0x000116, 0x001F1A, 0x000114, 0x000147, 0x000170, 0x000117,
+ 0x00015D, 0x00011B, 0x00015F, 0x001F11, 0x000115, 0x000158, 0x000172, 0x00015E,
+ 0x001F10, 0x001F13, 0x001F12, 0x001F14, 0x001F15, 0x00014C, 0x001FFB, 0x00014D,
+ 0x001F19, 0x000148, 0x001FFA, 0x00014F, 0x001F01, 0x001F03, 0x00014E, 0x000145,
+ 0x001F35, 0x001F02, 0x000162, 0x0004C1, 0x001F05, 0x001F00, 0x0004C2, 0x001FE4,
+ 0x001F0B, 0x001F07, 0x000212, 0x001FCC, 0x001FCF, 0x001F18, 0x001FCE, 0x001FCD,
+ 0x000135, 0x002281, 0x002285, 0x002284, 0x0004D0, 0x0004D3, 0x0004D2, 0x002288,
+ 0x0004D1, 0x0004D7, 0x0004D6, 0x001F09, 0x0001EC, 0x0004DB, 0x0004DA, 0x0004DD,
+ 0x0004DC, 0x0004DF, 0x0004DE, 0x002280, 0x0004E5, 0x0004E3, 0x0004E2, 0x002289,
+ 0x0004E7, 0x000151, 0x0004E6, 0x0004EE, 0x0004ED, 0x0004EB, 0x0004EA, 0x0004E4,
+ 0x0001E7, 0x0004EF, 0x0001A0, 0x0004F1, 0x0004F0, 0x0022AE, 0x0004F2, 0x0004F5,
+ 0x0004F4, 0x0001AF, 0x0022AD, 0x0022AC, 0x0004F8, 0x0004F3, 0x0004F9, 0x001F65,
+ 0x001F64, 0x0004EC, 0x001F66, 0x001F69, 0x001F68, 0x0001ED, 0x0001E6, 0x001F6D,
+ 0x001F6C, 0x001F6F, 0x001F6E, 0x0001E9, 0x0001E8, 0x0022AF, 0x0001EE, 0x0001EF,
+ 0x000120, 0x0001F9, 0x000127, 0x00013A, 0x0001D4, 0x000139, 0x00013B, 0x0001E0,
+ 0x001FC8, 0x0001D9, 0x000134, 0x0001DB, 0x001F95, 0x001F94, 0x001F8B, 0x001F8D,
+ 0x0001D5, 0x0001D0, 0x0001D3, 0x0001D6, 0x0001DC, 0x001F88, 0x0001D7, 0x0001DA,
+ 0x001F8F, 0x0001D8, 0x001F8E, 0x0001DF, 0x0001DE, 0x001F93, 0x001F91, 0x0022EA,
+ 0x0001E1, 0x001F92, 0x001F90, 0x001F99, 0x001F98, 0x001F9B, 0x001F9A, 0x001FBB,
+ 0x0001CD, 0x001F96, 0x001F97, 0x0022EB, 0x001F81, 0x001F82, 0x0001CE, 0x0001CF,
+ 0x001F80, 0x001FB6, 0x001FB7, 0x0001FA, 0x001FA5, 0x001FA6, 0x0001F4, 0x0001F5,
+ 0x0001F0, 0x0001F8, 0x0001FB, 0x0001FF, 0x0001FE, 0x001FB3, 0x001FB1, 0x001F8C,
+ 0x001FB4, 0x001FB2, 0x000203, 0x000202, 0x000201, 0x000200, 0x00020E, 0x00020F,
+ 0x000205, 0x001FB0, 0x00020B, 0x000209, 0x001FDF, 0x001FCB, 0x00020A, 0x000208,
+ 0x001FCA, 0x000213, 0x001FA7, 0x001FD9, 0x000204, 0x001FDB, 0x000206, 0x000207,
+ 0x001FDA, 0x00020D, 0x00020C, 0x001FD2, 0x00021A, 0x001FD3, 0x001FD1, 0x00021E,
+ 0x001FD0, 0x001FC2, 0x001FD6, 0x001FC3, 0x001FC1, 0x000227, 0x000228, 0x000226,
+ 0x001FC9, 0x001FD7, 0x00022B, 0x000229, 0x001FA8, 0x00022C, 0x00022A, 0x001FA4,
+ 0x000231, 0x000230, 0x000233, 0x000232, 0x001FB9, 0x001FAA, 0x001FAB, 0x001FAE,
+ 0x001FA9, 0x001FBC, 0x001FAF, 0x001FF6, 0x001FA1, 0x001FA2, 0x00022E, 0x00022F,
+ 0x001FF7, 0x001FC7, 0x001FA3, 0x001FA0, 0x001FAC, 0x001FD8, 0x001FF4, 0x001FAD,
+ 0x001FBA, 0x001FDD, 0x001FDE, 0x0001A1, 0x0001B0, 0x00212B, 0x00226D, 0x00226E,
+ 0x00226F, 0x002260, 0x002262, 0x002278, 0x002279, 0x002274, 0x002275, 0x002270,
+ 0x002271, 0x002249, 0x002244, 0x002247, 0x002241, 0x002224, 0x002226, 0x0021CD,
+ 0x0021CE, 0x0021CF, 0x00220C, 0x000477, 0x002204, 0x0021AE, 0x00045C, 0x00045D,
+ 0x00045E, 0x0022EC, 0x0022ED, 0x000451, 0x000453, 0x0022E0, 0x0022E1, 0x0022E2,
+ 0x0022E3, 0x0003CC, 0x0003CD, 0x0003CA, 0x0003CB, 0x00219A, 0x00219B, 0x00040C,
+ 0x00040D, 0x00040E, 0x001E6C, 0x001E6D, 0x001E6E, 0x001E6A, 0x001E64, 0x001E65,
+ 0x001E66, 0x001E7F, 0x001E78, 0x001E79, 0x001E7A, 0x001E7B, 0x001E70, 0x001E71,
+ 0x001E48, 0x001E49, 0x001E44, 0x001E45, 0x001E46, 0x001E5F, 0x001E54, 0x001E57,
+ 0x001E50, 0x001E51, 0x001E52, 0x001E53, 0x001E2C, 0x001E2D, 0x001E2E, 0x001E2F,
+ 0x001E28, 0x001E20, 0x001E21, 0x001E3C, 0x001E3D, 0x001E34, 0x001E35, 0x001E36,
+ 0x001E37, 0x001E30, 0x001E31, 0x001E32, 0x001E33, 0x001E0C, 0x001E0D, 0x001E0E,
+ 0x001E0F, 0x001E08, 0x001E09, 0x001E0A, 0x001E0B, 0x001E04, 0x001E05, 0x001E06,
+ 0x001E07, 0x001E00, 0x001E01, 0x001E02, 0x001E03, 0x001E1C, 0x001E1D, 0x001E1E,
+ 0x001E1F, 0x001E18, 0x001E19, 0x001E1A, 0x001E1B, 0x001E14, 0x001E15, 0x001E16,
+ 0x001E17, 0x001E10, 0x001E11, 0x001E12, 0x001E13, 0x001EEC, 0x001EED, 0x001EEE,
+ 0x001EEF, 0x001EE8, 0x001EE9, 0x001EEA, 0x001EEB, 0x001EE4, 0x001EE5, 0x001EE6,
+ 0x001EE7, 0x001EE0, 0x001EE1, 0x001EE2, 0x001EE3, 0x001EF8, 0x001EF9, 0x001EF4,
+ 0x001EF5, 0x001EF6, 0x001EF7, 0x001EF0, 0x001EF1, 0x001EF2, 0x001EF3, 0x001ECC,
+ 0x001ECD, 0x001ECE, 0x001ECF, 0x001EC8, 0x001EC9, 0x001ECA, 0x001ECB, 0x001EC4,
+ 0x001EC5, 0x001EC6, 0x001EC7, 0x001EC0, 0x001EC1, 0x001EC2, 0x001EC3, 0x001EDC,
+ 0x001EDD, 0x001EDE, 0x001EDF, 0x001ED8, 0x001ED9, 0x001EDA, 0x001EDB, 0x001ED4,
+ 0x001ED5, 0x001ED6, 0x001ED7, 0x001ED0, 0x001ED1, 0x001ED2, 0x001ED3, 0x001EAC,
+ 0x001EAD, 0x001EAE, 0x001EAF, 0x001EA8, 0x001EA9, 0x001EAA, 0x001EAB, 0x001EA4,
+ 0x001EA5, 0x001EA6, 0x001EB9, 0x001EB1, 0x001E8A, 0x001E8B, 0x0000C9, 0x0000CA,
+ 0x0000CB, 0x0000C4, 0x001E99, 0x0000C7, 0x0000C0, 0x001E91, 0x001E92, 0x001F6A,
+ 0x001F6B, 0x001F67, 0x001F60, 0x001F61, 0x001F62, 0x001F63, 0x001F7C, 0x001F7D,
+ 0x001F78, 0x001F79, 0x001F7A, 0x001F7B, 0x001F74, 0x001F75, 0x001F76, 0x001F77,
+ 0x001F70, 0x001F71, 0x001F72, 0x001F73, 0x001F4C, 0x001F4D, 0x001F48, 0x001F49,
+ 0x001F4A, 0x001F4B, 0x001F44, 0x001F45, 0x001F40, 0x001F41, 0x001F42, 0x001F43,
+ 0x001F5D, 0x001F5F, 0x001F59, 0x001F5B, 0x001F54, 0x001F55, 0x001F56, 0x001F57,
+ 0x001F50, 0x001F51, 0x002ADC, 0x001F52, 0x001F53, 0x001F2C, 0x001F2D, 0x001F2E,
+ 0x001F2F, 0x001F28, 0x001F29, 0x001F2A, 0x001F2B, };
+
+/* indexes */
+const uint16_t NU_TOUNACCENT_VALUES_I[] = {
+ 0x0526, 0x0529, 0x052C, 0x0565, 0x0127, 0x0568, 0x012B, 0x0129, 0x0550, 0x0514,
+ 0x0517, 0x00EB, 0x0511, 0x00E9, 0x0111, 0x0101, 0x0736, 0x0739, 0x00C3, 0x00C5,
+ 0x00B7, 0x00B3, 0x00E1, 0x00E3, 0x0754, 0x0757, 0x06D9, 0x06DC, 0x0089, 0x0081,
+ 0x0071, 0x0073, 0x00B9, 0x018B, 0x0125, 0x012D, 0x00C9, 0x00BB, 0x018D, 0x00C7,
+ 0x06C1, 0x00CD, 0x00CB, 0x00C1, 0x00BF, 0x01F5, 0x0637, 0x063A, 0x0119, 0x0628,
+ 0x011B, 0x062B, 0x062E, 0x0631, 0x0121, 0x0203, 0x0625, 0x0670, 0x0206, 0x020C,
+ 0x0209, 0x0218, 0x020F, 0x0215, 0x0212, 0x023F, 0x010D, 0x010F, 0x021B, 0x010B,
+ 0x0123, 0x0673, 0x0676, 0x0131, 0x0133, 0x04E4, 0x04D2, 0x04D8, 0x0105, 0x04DE,
+ 0x00FD, 0x051D, 0x0520, 0x04ED, 0x0221, 0x0103, 0x014D, 0x0107, 0x0224, 0x012F,
+ 0x04F0, 0x0227, 0x054D, 0x04EA, 0x0151, 0x051A, 0x0679, 0x022D, 0x022A, 0x011F,
+ 0x0230, 0x013D, 0x0562, 0x0147, 0x055F, 0x04F3, 0x0145, 0x021E, 0x0553, 0x0324,
+ 0x0322, 0x0328, 0x0326, 0x032C, 0x032A, 0x0330, 0x0137, 0x0334, 0x0332, 0x013B,
+ 0x014F, 0x013F, 0x014B, 0x03AE, 0x03B0, 0x0143, 0x03B4, 0x0149, 0x054A, 0x055C,
+ 0x03BC, 0x0163, 0x034E, 0x0354, 0x0352, 0x0165, 0x0350, 0x035C, 0x035A, 0x0388,
+ 0x035E, 0x0364, 0x0360, 0x0376, 0x01E5, 0x036C, 0x0362, 0x01DB, 0x0378, 0x0374,
+ 0x0372, 0x01DD, 0x037C, 0x039A, 0x037A, 0x0571, 0x056E, 0x0394, 0x0574, 0x038A,
+ 0x003F, 0x0041, 0x004F, 0x0390, 0x038E, 0x0043, 0x0392, 0x0398, 0x0396, 0x0045,
+ 0x004B, 0x03A0, 0x0047, 0x004D, 0x03A2, 0x0051, 0x039E, 0x03C6, 0x0556, 0x052F,
+ 0x0523, 0x03A4, 0x056B, 0x03D6, 0x0577, 0x03AC, 0x03D8, 0x03CA, 0x03C8, 0x03C4,
+ 0x03C2, 0x03DA, 0x005B, 0x03CC, 0x0007, 0x0005, 0x0003, 0x005D, 0x005F, 0x000B,
+ 0x0063, 0x000F, 0x0067, 0x0257, 0x001B, 0x03E4, 0x03E0, 0x03EA, 0x001F, 0x001D,
+ 0x0023, 0x0021, 0x0027, 0x0025, 0x0035, 0x0029, 0x002D, 0x002B, 0x0031, 0x002F,
+ 0x0406, 0x0404, 0x0033, 0x0408, 0x040C, 0x03E6, 0x040A, 0x0055, 0x03F8, 0x040E,
+ 0x03FE, 0x03E2, 0x03E8, 0x003D, 0x0057, 0x03DE, 0x0017, 0x0019, 0x0065, 0x043C,
+ 0x0037, 0x0059, 0x03EC, 0x003B, 0x044C, 0x043A, 0x0448, 0x0053, 0x006B, 0x0061,
+ 0x0069, 0x006D, 0x0440, 0x0438, 0x0049, 0x0039, 0x0432, 0x0436, 0x0075, 0x03EE,
+ 0x03F0, 0x0416, 0x03FC, 0x043E, 0x03F6, 0x025D, 0x03FA, 0x0242, 0x0245, 0x0790,
+ 0x0248, 0x0266, 0x007D, 0x006F, 0x024B, 0x007F, 0x01E1, 0x00A7, 0x008B, 0x007B,
+ 0x00A9, 0x009F, 0x0077, 0x008D, 0x00AB, 0x00AD, 0x0093, 0x0095, 0x01D3, 0x01D5,
+ 0x00D5, 0x0272, 0x01D7, 0x00B5, 0x01D9, 0x0079, 0x01CB, 0x0083, 0x0085, 0x0414,
+ 0x025A, 0x0418, 0x00B1, 0x072D, 0x072A, 0x0420, 0x0730, 0x073F, 0x0727, 0x0745,
+ 0x0748, 0x073C, 0x00D7, 0x00CF, 0x0412, 0x074B, 0x0742, 0x0087, 0x00DF, 0x0141,
+ 0x074E, 0x0751, 0x00EF, 0x0446, 0x044A, 0x0766, 0x0450, 0x0442, 0x0763, 0x076F,
+ 0x044E, 0x00A3, 0x00A1, 0x00E5, 0x00E7, 0x01CD, 0x008F, 0x0091, 0x009B, 0x050E,
+ 0x0097, 0x00F1, 0x0135, 0x009D, 0x0113, 0x00A5, 0x0117, 0x04F9, 0x0099, 0x0109,
+ 0x0139, 0x0115, 0x04F6, 0x04FF, 0x04FC, 0x0502, 0x0505, 0x00F5, 0x076C, 0x00F7,
+ 0x050B, 0x00F3, 0x0769, 0x00FB, 0x04C9, 0x04CF, 0x00F9, 0x00ED, 0x0559, 0x04CC,
+ 0x011D, 0x0278, 0x04D5, 0x04C6, 0x027B, 0x0733, 0x04E7, 0x04DB, 0x01CF, 0x06EE,
+ 0x06F9, 0x0508, 0x06F5, 0x06F1, 0x00D3, 0x07DA, 0x07E2, 0x07DE, 0x027E, 0x0287,
+ 0x0284, 0x07E6, 0x0281, 0x028D, 0x028A, 0x04E1, 0x018F, 0x0293, 0x0290, 0x0299,
+ 0x0296, 0x029F, 0x029C, 0x07D6, 0x02AB, 0x02A5, 0x02A2, 0x07EA, 0x02B1, 0x00FF,
+ 0x02AE, 0x02C0, 0x02BD, 0x02B7, 0x02B4, 0x02A8, 0x0185, 0x02C3, 0x0153, 0x02C9,
+ 0x02C6, 0x07F6, 0x02CC, 0x02D5, 0x02D2, 0x0157, 0x07F2, 0x07EE, 0x02D8, 0x02CF,
+ 0x02DB, 0x05D1, 0x05CE, 0x02BA, 0x05D4, 0x05DD, 0x05DA, 0x0191, 0x0183, 0x05E9,
+ 0x05E6, 0x05EF, 0x05EC, 0x0189, 0x0187, 0x07FA, 0x0193, 0x0196, 0x00AF, 0x01A1,
+ 0x00BD, 0x00DB, 0x0169, 0x00D9, 0x00DD, 0x017F, 0x06E2, 0x0173, 0x00D1, 0x0177,
+ 0x065B, 0x0658, 0x063D, 0x0643, 0x016B, 0x0161, 0x0167, 0x016D, 0x0179, 0x0634,
+ 0x016F, 0x0175, 0x0649, 0x0171, 0x0646, 0x017D, 0x017B, 0x0655, 0x064F, 0x080E,
+ 0x0181, 0x0652, 0x064C, 0x0667, 0x0664, 0x066D, 0x066A, 0x06CA, 0x015B, 0x065E,
+ 0x0661, 0x0812, 0x061F, 0x0622, 0x015D, 0x015F, 0x061C, 0x06BB, 0x06BE, 0x01A3,
+ 0x068B, 0x068E, 0x019B, 0x019D, 0x0199, 0x019F, 0x01A5, 0x01A9, 0x01A7, 0x06B5,
+ 0x06AF, 0x0640, 0x06B8, 0x06B2, 0x01B1, 0x01AF, 0x01AD, 0x01AB, 0x01C7, 0x01C9,
+ 0x01B5, 0x06AC, 0x01C1, 0x01BD, 0x0723, 0x06EB, 0x01BF, 0x01BB, 0x06E8, 0x01D1,
+ 0x0691, 0x0712, 0x01B3, 0x0718, 0x01B7, 0x01B9, 0x0715, 0x01C5, 0x01C3, 0x0703,
+ 0x01DF, 0x0706, 0x0700, 0x01E3, 0x06FD, 0x06D3, 0x0709, 0x06D6, 0x06D0, 0x01E9,
+ 0x01EB, 0x01E7, 0x06E5, 0x070C, 0x01F1, 0x01ED, 0x0694, 0x01F3, 0x01EF, 0x0688,
+ 0x01FD, 0x01FB, 0x0201, 0x01FF, 0x06C4, 0x069A, 0x069D, 0x06A6, 0x0697, 0x06CD,
+ 0x06A9, 0x075D, 0x067F, 0x0682, 0x01F7, 0x01F9, 0x0760, 0x06DF, 0x0685, 0x067C,
+ 0x06A0, 0x070F, 0x075A, 0x06A3, 0x06C7, 0x071B, 0x071F, 0x0155, 0x0159, 0x0772,
+ 0x07B6, 0x07BA, 0x07BC, 0x07B0, 0x07B2, 0x07CE, 0x07D2, 0x07C6, 0x07CA, 0x07BE,
+ 0x07C2, 0x07AC, 0x07A4, 0x07A8, 0x07A0, 0x0798, 0x079C, 0x0780, 0x0784, 0x0788,
+ 0x0794, 0x0275, 0x078C, 0x077C, 0x0269, 0x026C, 0x026F, 0x0816, 0x081A, 0x0260,
+ 0x0263, 0x07FE, 0x0802, 0x0806, 0x080A, 0x0239, 0x023C, 0x0233, 0x0236, 0x0774,
+ 0x0778, 0x024E, 0x0251, 0x0254, 0x03B6, 0x03B8, 0x03BA, 0x03B2, 0x03A6, 0x03A8,
+ 0x03AA, 0x03DC, 0x03CE, 0x03D0, 0x03D2, 0x03D4, 0x03BE, 0x03C0, 0x036E, 0x0370,
+ 0x0366, 0x0368, 0x036A, 0x039C, 0x0386, 0x038C, 0x037E, 0x0380, 0x0382, 0x0384,
+ 0x0336, 0x0338, 0x033A, 0x033C, 0x032E, 0x031E, 0x0320, 0x0356, 0x0358, 0x0346,
+ 0x0348, 0x034A, 0x034C, 0x033E, 0x0340, 0x0342, 0x0344, 0x02F6, 0x02F8, 0x02FA,
+ 0x02FC, 0x02EE, 0x02F0, 0x02F2, 0x02F4, 0x02E6, 0x02E8, 0x02EA, 0x02EC, 0x02DE,
+ 0x02E0, 0x02E2, 0x02E4, 0x0316, 0x0318, 0x031A, 0x031C, 0x030E, 0x0310, 0x0312,
+ 0x0314, 0x0306, 0x0308, 0x030A, 0x030C, 0x02FE, 0x0300, 0x0302, 0x0304, 0x04AA,
+ 0x04AC, 0x04AE, 0x04B0, 0x04A2, 0x04A4, 0x04A6, 0x04A8, 0x049A, 0x049C, 0x049E,
+ 0x04A0, 0x0492, 0x0494, 0x0496, 0x0498, 0x04C2, 0x04C4, 0x04BA, 0x04BC, 0x04BE,
+ 0x04C0, 0x04B2, 0x04B4, 0x04B6, 0x04B8, 0x046A, 0x046C, 0x046E, 0x0470, 0x0462,
+ 0x0464, 0x0466, 0x0468, 0x045A, 0x045C, 0x045E, 0x0460, 0x0452, 0x0454, 0x0456,
+ 0x0458, 0x048A, 0x048C, 0x048E, 0x0490, 0x0482, 0x0484, 0x0486, 0x0488, 0x047A,
+ 0x047C, 0x047E, 0x0480, 0x0472, 0x0474, 0x0476, 0x0478, 0x042A, 0x042C, 0x042E,
+ 0x0430, 0x0422, 0x0424, 0x0426, 0x0428, 0x041A, 0x041C, 0x041E, 0x0444, 0x0434,
+ 0x03F2, 0x03F4, 0x0011, 0x0013, 0x0015, 0x0009, 0x0410, 0x000D, 0x0001, 0x0400,
+ 0x0402, 0x05E0, 0x05E3, 0x05D7, 0x05C2, 0x05C5, 0x05C8, 0x05CB, 0x0616, 0x0619,
+ 0x060A, 0x060D, 0x0610, 0x0613, 0x05FE, 0x0601, 0x0604, 0x0607, 0x05F2, 0x05F5,
+ 0x05F8, 0x05FB, 0x0598, 0x059B, 0x058C, 0x058F, 0x0592, 0x0595, 0x0586, 0x0589,
+ 0x057A, 0x057D, 0x0580, 0x0583, 0x05BC, 0x05BF, 0x05B6, 0x05B9, 0x05AA, 0x05AD,
+ 0x05B0, 0x05B3, 0x059E, 0x05A1, 0x081E, 0x05A4, 0x05A7, 0x053E, 0x0541, 0x0544,
+ 0x0547, 0x0532, 0x0535, 0x0538, 0x053B, };
+
+const uint8_t NU_TOUNACCENT_COMBINED[] = {
+ 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41,
+ 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x49,
+ 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x4F, 0x00, 0x4F,
+ 0x00, 0x4F, 0x00, 0x4F, 0x00, 0x4F, 0x00, 0x4F, 0x00, 0x55, 0x00, 0x55,
+ 0x00, 0x55, 0x00, 0x55, 0x00, 0x59, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61,
+ 0x00, 0x61, 0x00, 0x61, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x65,
+ 0x00, 0x65, 0x00, 0x65, 0x00, 0x69, 0x00, 0x69, 0x00, 0x69, 0x00, 0x69,
+ 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x6F,
+ 0x00, 0x6F, 0x00, 0x75, 0x00, 0x75, 0x00, 0x75, 0x00, 0x75, 0x00, 0x79,
+ 0x00, 0x79, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41,
+ 0x00, 0x61, 0x00, 0x43, 0x00, 0x63, 0x00, 0x43, 0x00, 0x63, 0x00, 0x43,
+ 0x00, 0x63, 0x00, 0x43, 0x00, 0x63, 0x00, 0x44, 0x00, 0x64, 0x00, 0x44,
+ 0x00, 0x64, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45,
+ 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x47,
+ 0x00, 0x67, 0x00, 0x47, 0x00, 0x67, 0x00, 0x47, 0x00, 0x67, 0x00, 0x47,
+ 0x00, 0x67, 0x00, 0x48, 0x00, 0x68, 0x00, 0x48, 0x00, 0x68, 0x00, 0x49,
+ 0x00, 0x69, 0x00, 0x49, 0x00, 0x69, 0x00, 0x49, 0x00, 0x69, 0x00, 0x49,
+ 0x00, 0x69, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x6A, 0x00, 0x4B, 0x00, 0x6B,
+ 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x4C, 0x00, 0x6C,
+ 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x4E, 0x00, 0x6E,
+ 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F,
+ 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x52, 0x00, 0x72, 0x00, 0x52, 0x00, 0x72,
+ 0x00, 0x52, 0x00, 0x72, 0x00, 0x53, 0x00, 0x73, 0x00, 0x53, 0x00, 0x73,
+ 0x00, 0x53, 0x00, 0x73, 0x00, 0x53, 0x00, 0x73, 0x00, 0x54, 0x00, 0x74,
+ 0x00, 0x54, 0x00, 0x74, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75,
+ 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75,
+ 0x00, 0x55, 0x00, 0x75, 0x00, 0x57, 0x00, 0x77, 0x00, 0x59, 0x00, 0x79,
+ 0x00, 0x59, 0x00, 0x5A, 0x00, 0x7A, 0x00, 0x5A, 0x00, 0x7A, 0x00, 0x5A,
+ 0x00, 0x7A, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x55, 0x00, 0x75, 0x00, 0x41,
+ 0x00, 0x61, 0x00, 0x49, 0x00, 0x69, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x55,
+ 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55,
+ 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41,
+ 0x00, 0x61, 0x00, 0x47, 0x00, 0x67, 0x00, 0x4B, 0x00, 0x6B, 0x00, 0x4F,
+ 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0xC6, 0xB7, 0x00, 0xCA, 0x92,
+ 0x00, 0x6A, 0x00, 0x47, 0x00, 0x67, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x41,
+ 0x00, 0x61, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41,
+ 0x00, 0x61, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x49,
+ 0x00, 0x69, 0x00, 0x49, 0x00, 0x69, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F,
+ 0x00, 0x6F, 0x00, 0x52, 0x00, 0x72, 0x00, 0x52, 0x00, 0x72, 0x00, 0x55,
+ 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x53, 0x00, 0x73, 0x00, 0x54,
+ 0x00, 0x74, 0x00, 0x48, 0x00, 0x68, 0x00, 0x41, 0x00, 0x61, 0x00, 0x45,
+ 0x00, 0x65, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F,
+ 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x59, 0x00, 0x79, 0x00, 0xC2,
+ 0xA8, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x95, 0x00, 0xCE, 0x97, 0x00, 0xCE,
+ 0x99, 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xA9, 0x00, 0xCE,
+ 0xB9, 0x00, 0xCE, 0x99, 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xB1, 0x00, 0xCE,
+ 0xB5, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB9, 0x00, 0xCF, 0x85, 0x00, 0xCE,
+ 0xB9, 0x00, 0xCF, 0x85, 0x00, 0xCE, 0xBF, 0x00, 0xCF, 0x85, 0x00, 0xCF,
+ 0x89, 0x00, 0xD0, 0x95, 0x00, 0xD0, 0x95, 0x00, 0xD0, 0x93, 0x00, 0xD0,
+ 0x86, 0x00, 0xD0, 0x9A, 0x00, 0xD0, 0x98, 0x00, 0xD0, 0xA3, 0x00, 0xD0,
+ 0x98, 0x00, 0xD0, 0xB8, 0x00, 0xD0, 0xB5, 0x00, 0xD0, 0xB5, 0x00, 0xD0,
+ 0xB3, 0x00, 0xD1, 0x96, 0x00, 0xD0, 0xBA, 0x00, 0xD0, 0xB8, 0x00, 0xD1,
+ 0x83, 0x00, 0xD1, 0xB4, 0x00, 0xD1, 0xB5, 0x00, 0xD0, 0x96, 0x00, 0xD0,
+ 0xB6, 0x00, 0xD0, 0x90, 0x00, 0xD0, 0xB0, 0x00, 0xD0, 0x90, 0x00, 0xD0,
+ 0xB0, 0x00, 0xD0, 0x95, 0x00, 0xD0, 0xB5, 0x00, 0xD3, 0x98, 0x00, 0xD3,
+ 0x99, 0x00, 0xD0, 0x96, 0x00, 0xD0, 0xB6, 0x00, 0xD0, 0x97, 0x00, 0xD0,
+ 0xB7, 0x00, 0xD0, 0x98, 0x00, 0xD0, 0xB8, 0x00, 0xD0, 0x98, 0x00, 0xD0,
+ 0xB8, 0x00, 0xD0, 0x9E, 0x00, 0xD0, 0xBE, 0x00, 0xD3, 0xA8, 0x00, 0xD3,
+ 0xA9, 0x00, 0xD0, 0xAD, 0x00, 0xD1, 0x8D, 0x00, 0xD0, 0xA3, 0x00, 0xD1,
+ 0x83, 0x00, 0xD0, 0xA3, 0x00, 0xD1, 0x83, 0x00, 0xD0, 0xA3, 0x00, 0xD1,
+ 0x83, 0x00, 0xD0, 0xA7, 0x00, 0xD1, 0x87, 0x00, 0xD0, 0xAB, 0x00, 0xD1,
+ 0x8B, 0x00, 0x41, 0x00, 0x61, 0x00, 0x42, 0x00, 0x62, 0x00, 0x42, 0x00,
+ 0x62, 0x00, 0x42, 0x00, 0x62, 0x00, 0x43, 0x00, 0x63, 0x00, 0x44, 0x00,
+ 0x64, 0x00, 0x44, 0x00, 0x64, 0x00, 0x44, 0x00, 0x64, 0x00, 0x44, 0x00,
+ 0x64, 0x00, 0x44, 0x00, 0x64, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00,
+ 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00,
+ 0x65, 0x00, 0x46, 0x00, 0x66, 0x00, 0x47, 0x00, 0x67, 0x00, 0x48, 0x00,
+ 0x68, 0x00, 0x48, 0x00, 0x68, 0x00, 0x48, 0x00, 0x68, 0x00, 0x48, 0x00,
+ 0x68, 0x00, 0x48, 0x00, 0x68, 0x00, 0x49, 0x00, 0x69, 0x00, 0x49, 0x00,
+ 0x69, 0x00, 0x4B, 0x00, 0x6B, 0x00, 0x4B, 0x00, 0x6B, 0x00, 0x4B, 0x00,
+ 0x6B, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x4C, 0x00,
+ 0x6C, 0x00, 0x4C, 0x00, 0x6C, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x4D, 0x00,
+ 0x6D, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x4E, 0x00,
+ 0x6E, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x4E, 0x00, 0x6E, 0x00, 0x4F, 0x00,
+ 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00,
+ 0x6F, 0x00, 0x50, 0x00, 0x70, 0x00, 0x50, 0x00, 0x70, 0x00, 0x52, 0x00,
+ 0x72, 0x00, 0x52, 0x00, 0x72, 0x00, 0x52, 0x00, 0x72, 0x00, 0x52, 0x00,
+ 0x72, 0x00, 0x53, 0x00, 0x73, 0x00, 0x53, 0x00, 0x73, 0x00, 0x53, 0x00,
+ 0x73, 0x00, 0x53, 0x00, 0x73, 0x00, 0x53, 0x00, 0x73, 0x00, 0x54, 0x00,
+ 0x74, 0x00, 0x54, 0x00, 0x74, 0x00, 0x54, 0x00, 0x74, 0x00, 0x54, 0x00,
+ 0x74, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00,
+ 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x56, 0x00,
+ 0x76, 0x00, 0x56, 0x00, 0x76, 0x00, 0x57, 0x00, 0x77, 0x00, 0x57, 0x00,
+ 0x77, 0x00, 0x57, 0x00, 0x77, 0x00, 0x57, 0x00, 0x77, 0x00, 0x57, 0x00,
+ 0x77, 0x00, 0x58, 0x00, 0x78, 0x00, 0x58, 0x00, 0x78, 0x00, 0x59, 0x00,
+ 0x79, 0x00, 0x5A, 0x00, 0x7A, 0x00, 0x5A, 0x00, 0x7A, 0x00, 0x5A, 0x00,
+ 0x7A, 0x00, 0x68, 0x00, 0x74, 0x00, 0x77, 0x00, 0x79, 0x00, 0x41, 0x00,
+ 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00,
+ 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00,
+ 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00,
+ 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x45, 0x00,
+ 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00,
+ 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x45, 0x00,
+ 0x65, 0x00, 0x45, 0x00, 0x65, 0x00, 0x49, 0x00, 0x69, 0x00, 0x49, 0x00,
+ 0x69, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00,
+ 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00,
+ 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00,
+ 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00, 0x6F, 0x00, 0x4F, 0x00,
+ 0x6F, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00,
+ 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x55, 0x00,
+ 0x75, 0x00, 0x55, 0x00, 0x75, 0x00, 0x59, 0x00, 0x79, 0x00, 0x59, 0x00,
+ 0x79, 0x00, 0x59, 0x00, 0x79, 0x00, 0x59, 0x00, 0x79, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0x91,
+ 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91,
+ 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0xB5,
+ 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0xB5,
+ 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0x95, 0x00, 0xCE, 0x95, 0x00, 0xCE, 0x95,
+ 0x00, 0xCE, 0x95, 0x00, 0xCE, 0x95, 0x00, 0xCE, 0x95, 0x00, 0xCE, 0xB7,
+ 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7,
+ 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0x97,
+ 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97,
+ 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0xB9,
+ 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9,
+ 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0x99,
+ 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99,
+ 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99, 0x00, 0xCE, 0xBF,
+ 0x00, 0xCE, 0xBF, 0x00, 0xCE, 0xBF, 0x00, 0xCE, 0xBF, 0x00, 0xCE, 0xBF,
+ 0x00, 0xCE, 0xBF, 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0x9F,
+ 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0x9F, 0x00, 0xCF, 0x85,
+ 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85,
+ 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCE, 0xA5,
+ 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xA5, 0x00, 0xCF, 0x89,
+ 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89,
+ 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCE, 0xA9,
+ 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9,
+ 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0xB5, 0x00, 0xCE, 0xB7,
+ 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xBF,
+ 0x00, 0xCE, 0xBF, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x89,
+ 0x00, 0xCF, 0x89, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91,
+ 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91,
+ 0x00, 0xCE, 0x91, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7,
+ 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7,
+ 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97,
+ 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97,
+ 0x00, 0xCE, 0x97, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89,
+ 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89,
+ 0x00, 0xCF, 0x89, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9,
+ 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9,
+ 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1, 0x00, 0xCE, 0xB1,
+ 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91, 0x00, 0xCE, 0x91,
+ 0x00, 0xCE, 0x91, 0x00, 0xC2, 0xA8, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7,
+ 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0xB7, 0x00, 0xCE, 0x95,
+ 0x00, 0xCE, 0x95, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x97,
+ 0x00, 0xE1, 0xBE, 0xBF, 0x00, 0xE1, 0xBE, 0xBF, 0x00, 0xE1, 0xBE, 0xBF,
+ 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9,
+ 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0xB9, 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99,
+ 0x00, 0xCE, 0x99, 0x00, 0xCE, 0x99, 0x00, 0xE1, 0xBF, 0xBE, 0x00, 0xE1,
+ 0xBF, 0xBE, 0x00, 0xE1, 0xBF, 0xBE, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85,
+ 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x81, 0x00, 0xCF, 0x81,
+ 0x00, 0xCF, 0x85, 0x00, 0xCF, 0x85, 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xA5,
+ 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xA5, 0x00, 0xCE, 0xA1, 0x00, 0xC2, 0xA8,
+ 0x00, 0xC2, 0xA8, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89,
+ 0x00, 0xCF, 0x89, 0x00, 0xCF, 0x89, 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0x9F,
+ 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0xCE, 0xA9, 0x00, 0x41, 0x00,
+ 0xE2, 0x86, 0x90, 0x00, 0xE2, 0x86, 0x92, 0x00, 0xE2, 0x86, 0x94, 0x00,
+ 0xE2, 0x87, 0x90, 0x00, 0xE2, 0x87, 0x94, 0x00, 0xE2, 0x87, 0x92, 0x00,
+ 0xE2, 0x88, 0x83, 0x00, 0xE2, 0x88, 0x88, 0x00, 0xE2, 0x88, 0x8B, 0x00,
+ 0xE2, 0x88, 0xA3, 0x00, 0xE2, 0x88, 0xA5, 0x00, 0xE2, 0x88, 0xBC, 0x00,
+ 0xE2, 0x89, 0x83, 0x00, 0xE2, 0x89, 0x85, 0x00, 0xE2, 0x89, 0x88, 0x00,
+ 0x3D, 0x00, 0xE2, 0x89, 0xA1, 0x00, 0xE2, 0x89, 0x8D, 0x00, 0x3C, 0x00,
+ 0x3E, 0x00, 0xE2, 0x89, 0xA4, 0x00, 0xE2, 0x89, 0xA5, 0x00, 0xE2, 0x89,
+ 0xB2, 0x00, 0xE2, 0x89, 0xB3, 0x00, 0xE2, 0x89, 0xB6, 0x00, 0xE2, 0x89,
+ 0xB7, 0x00, 0xE2, 0x89, 0xBA, 0x00, 0xE2, 0x89, 0xBB, 0x00, 0xE2, 0x8A,
+ 0x82, 0x00, 0xE2, 0x8A, 0x83, 0x00, 0xE2, 0x8A, 0x86, 0x00, 0xE2, 0x8A,
+ 0x87, 0x00, 0xE2, 0x8A, 0xA2, 0x00, 0xE2, 0x8A, 0xA8, 0x00, 0xE2, 0x8A,
+ 0xA9, 0x00, 0xE2, 0x8A, 0xAB, 0x00, 0xE2, 0x89, 0xBC, 0x00, 0xE2, 0x89,
+ 0xBD, 0x00, 0xE2, 0x8A, 0x91, 0x00, 0xE2, 0x8A, 0x92, 0x00, 0xE2, 0x8A,
+ 0xB2, 0x00, 0xE2, 0x8A, 0xB3, 0x00, 0xE2, 0x8A, 0xB4, 0x00, 0xE2, 0x8A,
+ 0xB5, 0x00, 0xE2, 0xAB, 0x9D, 0x00,
+};
+
diff --git a/vendor/nunicode/src/libnu/gen/_toupper.c b/vendor/nunicode/src/libnu/gen/_toupper.c
new file mode 100644
index 0000000000..afaa708d99
--- /dev/null
+++ b/vendor/nunicode/src/libnu/gen/_toupper.c
@@ -0,0 +1,917 @@
+/* Automatically generated file (mph.py), 1490539881
+ *
+ * Tag : NU_TOUPPER
+ * Prime : 01000193,
+ * G size : 1396,
+ * Combined length : 5530,
+ * Encoding : UTF-8
+ */
+
+#include <stdint.h>
+
+const int16_t NU_TOUPPER_G[] = {
+ 1, -1396, 1, -1395, 1, -1394, 1, -1393, 1, -1392, 1, -1391,
+ 1, -1390, 1, -1389, 1, 1, 1, 5, 8, 1, 4, 9,
+ -1388, 0, -1387, 0, -1386, 0, -1385, 0, -1384, 0, -1383, 0,
+ -1382, 0, -1381, 0, -1380, 0, -1379, 0, -1377, 0, -1376, 0,
+ -1375, 0, -1374, 0, 0, -1373, 0, 0, -1372, 1, -1371, 1,
+ -1370, 1, -1369, 1, 7, 10, -1368, 12, 2, -1367, 2, -1366,
+ -1365, 0, -1364, 0, -1363, 0, -1362, 0, 2, -1361, 1, -1360,
+ 1, -1359, 1, -1358, -1357, -1355, -1354, 0, -1353, 0, 17, 0,
+ -1352, -1351, 19, 0, 0, -1350, 0, 0, 1, -1349, -1348, 1,
+ -1347, -1346, 3, -1345, -1343, -1342, -1341, 4, -1340, -1339, -1338, 2,
+ 0, 0, 0, -1337, 0, 2, 0, -1336, -1335, -1334, 8, -1333,
+ 1, 8, 1, 9, 1, 1, 1, 7, 28, 31, 1, 33,
+ -1332, -1331, -1330, 1, 0, 0, -1329, 0, 0, -1327, 0, -1325,
+ 0, -1324, 0, -1322, 0, -1320, 0, -1319, 1, -1316, 1, 1,
+ -1314, -1312, -1310, -1308, -1306, 1, 1, -1304, 1, -1302, 1, 1,
+ -1300, 1, -1298, 1, 1, 1, -1296, 1, -1295, -1292, 1, -1290,
+ 1, -1288, 1, -1286, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 2, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 2, 0, 2, 0, 2, 0, 1, 0,
+ -1284, 0, -1282, 0, -1280, 0, -1276, 0, -1275, 0, -1274, 0,
+ -1272, 0, -1271, 0, -1270, 0, -1269, 0, -1267, 0, -1265, 0,
+ -1264, 0, -1263, 0, 0, -1262, 0, 0, 0, -1261, 0, -1260,
+ -1259, 0, -1258, 0, -1257, 0, -1256, 0, -1255, 0, -1254, 0,
+ -1253, 0, -1252, 0, -1250, 0, -1248, 0, -1247, 0, -1246, 0,
+ -1245, 0, -1242, 0, -1241, 0, -1240, 0, 0, -1239, 0, -1238,
+ 0, -1237, 0, -1236, -1235, 0, -1234, -1233, -1231, 0, -1230, 0,
+ 48, -1229, 49, -1227, 63, -1223, 64, -1220, -1219, 64, -1218, -1216,
+ 68, 70, -1214, 69, 64, -1126, 64, -1115, 32, 1, 32, 1,
+ 32, 1, 32, 1, 32, 1, 32, 1, -1114, -1111, -1110, -1109,
+ -906, -893, -891, -887, -884, -883, -881, -872, -870, -868, -862, -860,
+ 32, 32, 32, 32, 33, -859, 33, 40, -858, -857, -853, -850,
+ -848, -846, 35, -839, -837, -836, -833, -830, -828, -826, 17, -825,
+ -824, -823, -822, -820, -819, -818, -817, -816, -812, -810, -808, -804,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 32, -800, 32, -799,
+ -798, -797, 33, -796, 32, -794, 35, -792, 32, -790, 32, -788,
+ 40, -786, 40, -784, 40, -783, 40, -782, 33, -781, 33, -780,
+ 33, -778, 33, -776, -774, 0, -772, 0, -770, 0, -768, 0,
+ -766, 0, -761, 0, -760, 0, -758, 0, -756, 0, -754, 0,
+ -748, 0, -747, 0, -746, 0, -745, 0, -743, 0, -742, 0,
+ -741, 0, -736, 0, -734, 0, 1, 0, -732, 0, 4, 0,
+ -730, 0, -720, 0, -717, 0, -706, 0, 1, 0, -703, 0,
+ -701, 0, -689, 0, -671, 0, -669, 0, -668, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -667, -666, -665, -641,
+ 5, -640, 5, -639, -638, -635, -634, 11, -615, -613, -612, -610,
+ -608, 2, -607, 6, 2, 1, 1, 5, -606, -605, -604, -603,
+ 0, -602, -601, -597, 0, 0, 0, 0, -594, -592, -588, 0,
+ -587, -584, -581, -580, -578, -577, -576, -575, -574, -573, -572, -571,
+ -570, -569, -568, 1, -567, -564, -563, -562, -561, -560, -558, -556,
+ 1, 1, 1, 1, -555, -554, 9, 10, -553, -552, -551, -550,
+ -549, -548, -547, -546, -545, -544, -543, -542, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -541, 1, 16, 1,
+ -540, -539, -538, -537, -536, -534, -532, -530, -528, -526, -525, -524,
+ 1, 1, 1, 4, 1, -523, 16, 19, 12, 1, 16, -522,
+ 16, -521, 64, -520, -519, 0, -518, 0, -517, -516, 17, -515,
+ -514, 30, 28, -513, -512, 32, -510, 41, 0, -508, -506, 47,
+ -504, -503, -502, -497, 0, 0, -496, 0, 12, 0, -494, -490,
+ -489, 0, 0, 0, 44, 0, 53, 0, 67, 0, 69, 0,
+ 31, 0, 32, 0, 39, 0, 43, 0, 0, 0, 0, 0,
+ 0, 0, 0, -488, 0, 0, 0, 0, -486, 0, -484, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -482, 0, -480, 0,
+ -476, 0, -475, 0, 0, 0, -474, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -473, -472, -471, -470,
+ -469, -468, -467, -466, -465, -463, -461, -455, -451, -449, -439, -428,
+ -424, -423, -422, -384, -383, -382, -381, -380, -379, -377, 4, -376,
+ -375, -374, -373, -372, -371, -370, -369, -363, 2, -361, -352, -351,
+ -350, 0, 0, 0, -349, -348, 0, -347, -346, -345, 2, 5,
+ -344, -343, -342, -341, -340, -339, -338, -337, -335, -323, -322, -312,
+ -311, -308, -307, -306, -305, 1, 0, 0, 0, 0, 0, 0,
+ -304, 0, 0, 0, 4, 3, 8, 0, 1, -303, -302, 1,
+ 4, 0, -301, 0, 1, -300, -299, 23, 2, -298, -297, -296,
+ 4, -294, -293, -291, 1, -289, 5, -287, 36, -285, 53, 1,
+ 8, 12, 9, 40, 1, 40, 1, 40, 11, -279, 64, -264,
+ 64, -263, 64, -262, 4, 45, 4, 44, 76, -261, 11, 41,
+ -260, 0, -259, 0, 0, 0, 0, 0, 66, 69, 68, 79,
+ 180, 4, 186, 189, 70, -258, -257, 81, 93, -256, 100, -255,
+ 5, 67, 65, -254, 5, 67, 4, 131, 68, -253, 78, -252,
+ 68, -251, 115, -250, 81, -249, 98, -248, 101, -247, 101, -246,
+ 0, 0, 0, 0, -245, 0, -244, 0, 3, 167, 2, 169,
+ 1, -243, 1, -242, 1, 0, 1, 0, -241, 0, -240, 0,
+ 136, -239, 139, -238, -237, 0, 15, -236, -235, 0, -234, 0,
+ -233, 0, -232, 0, 158, -231, 157, -230, 136, -229, 142, -228,
+ -227, -226, -225, -223, 0, 0, -221, -215, 183, -214, -168, 199,
+ 141, -167, -163, -161, -156, 0, -155, 0, -154, 0, -153, 0,
+ 1, 0, 1, 0, 1, 1, 1, -152, 1, 1, -151, 1,
+ -150, 0, -148, 0, -147, 0, -145, -144, -143, -142, -141, -140,
+ 2, 0, -139, 0, 2, 0, 1, 0, 1, 0, 1, 0,
+ -138, -137, 9, 0, -136, 0, 1, 0, 48, -135, 54, -134,
+ 6, -133, 1, -132, 1, -131, 1, 23, -130, -129, 16, 0,
+ 1, 39, 1, -128, 1, -127, 81, 46, 22, -126, 83, -125,
+ 89, -124, 98, -123, -122, 0, -121, 0, -120, 0, -119, 0,
+ 1, -117, 1, -115, 1, -112, 1, -111, -110, 0, -109, 0,
+ -108, 0, -107, 0, -106, 0, -105, 0, -104, 0, -103, 0,
+ 39, 0, 43, 0, 8, 0, 35, 0, 32, 0, 32, 0,
+ 32, 0, 37, 0, 77, 0, 82, 0, 7, 0, 8, 0,
+ 1, 0, 20, 0, 38, 0, 40, 0, -102, 0, -101, 0,
+ -100, 0, -99, 0, -98, 0, -97, 0, -96, 0, -95, 0,
+ 5, 0, 10, 0, 75, 0, 79, 0, 5, 0, 11, 0,
+ -94, 0, 83, 0, -93, 0, -92, 0, -91, 0, -90, 0,
+ -89, 0, -88, 0, -87, 0, -86, 0, -85, 0, -84, 0,
+ -83, 0, -82, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, -81, 1, -80, 1, -79, 1, -78, 1, -77, 1, -76,
+ 1, -75, 1, -74, 1, 0, 1, 0, 2, 0, 1, 0,
+ -73, 0, -72, 0, -71, 0, -70, 0, -69, 0, -68, 0,
+ -67, 0, -66, 0, 1, 0, 1, 0, 2, 0, 1, 0,
+ 1, -65, 1, -64, 16, -62, 162, -60, 0, 0, -58, -57,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -56, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -55, -53, -52, -51, -50, -49, -47, -45,
+ -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, 0,
+ -29, -27, -26, -25, -24, -23, -22, -21, 14, 37, 64, 67,
+ 72, -20, 75, -18, -16, 0, -14, 0, -12, 0, -11, 0,
+ -10, 0, -9, 0, 0, 0, -8, 0, -7, -6, -5, -4,
+ 68, -3, -2, -1, };
+
+const size_t NU_TOUPPER_G_SIZE = sizeof(NU_TOUPPER_G) / sizeof(*NU_TOUPPER_G);
+
+/* codepoints */
+const uint32_t NU_TOUPPER_VALUES_C[] = {
+ 0x0104F4, 0x0104F5, 0x0104F6, 0x0104F0, 0x0104F1, 0x0104F2, 0x0104F3, 0x000481,
+ 0x00049D, 0x00049F, 0x000499, 0x00049B, 0x000581, 0x000495, 0x000583, 0x000497,
+ 0x000585, 0x0104DC, 0x000587, 0x0104DE, 0x000568, 0x000569, 0x00056A, 0x00056B,
+ 0x000564, 0x000565, 0x000566, 0x00052D, 0x000567, 0x000561, 0x000562, 0x000563,
+ 0x00057C, 0x00057D, 0x00057E, 0x00057F, 0x000578, 0x000579, 0x00057A, 0x00057B,
+ 0x00FB01, 0x00FB05, 0x00FB03, 0x00FB02, 0x000574, 0x00FB00, 0x000575, 0x00FB06,
+ 0x000576, 0x000577, 0x000570, 0x000571, 0x000572, 0x00FB04, 0x000573, 0x002184,
+ 0x0024E8, 0x0024E9, 0x00FB13, 0x0024E4, 0x00FB15, 0x0024E6, 0x00FB17, 0x0024E0,
+ 0x0024E2, 0x001E61, 0x001E63, 0x001E7D, 0x001E7F, 0x001E79, 0x001E7B, 0x001E75,
+ 0x001E77, 0x0024DC, 0x0024DE, 0x0024D8, 0x0024DA, 0x0024D4, 0x0024D6, 0x0024D0,
+ 0x0024D2, 0x001E51, 0x001E53, 0x001E2D, 0x001E2F, 0x001E29, 0x001E2B, 0x001E25,
+ 0x001E27, 0x001E21, 0x001E23, 0x001E3D, 0x001E3F, 0x001E3B, 0x001E09, 0x001E0B,
+ 0x001E05, 0x001E07, 0x001E01, 0x001E03, 0x001E1D, 0x001E1F, 0x001EF9, 0x001EFB,
+ 0x001EF5, 0x001EF7, 0x001EF1, 0x001EF3, 0x001ECD, 0x001ECF, 0x000584, 0x000586,
+ 0x000071, 0x000073, 0x000580, 0x000072, 0x000582, 0x000070, 0x001EC1, 0x001EC3,
+ 0x001EDD, 0x001EDF, 0x00FF4C, 0x00FF4E, 0x00FF48, 0x00FF4A, 0x00FF46, 0x000268,
+ 0x000266, 0x001EAB, 0x00FF5A, 0x00FF54, 0x00FF56, 0x00FF50, 0x00FF52, 0x001EBB,
+ 0x000272, 0x001EB7, 0x001E89, 0x000240, 0x001E85, 0x000242, 0x001E87, 0x00025C,
+ 0x001E81, 0x002C30, 0x001E83, 0x000259, 0x00214E, 0x00025B, 0x001E99, 0x000250,
+ 0x000229, 0x00022B, 0x000225, 0x000227, 0x002C3D, 0x002C3C, 0x002C3F, 0x002C3E,
+ 0x001F64, 0x002C68, 0x001F65, 0x002C6C, 0x0000B5, 0x00217C, 0x001F66, 0x001F61,
+ 0x002C4C, 0x00217E, 0x002C6A, 0x00217F, 0x002C4D, 0x002C5D, 0x002C4F, 0x002C4E,
+ 0x002C51, 0x002C50, 0x002C53, 0x002C52, 0x002C55, 0x002C54, 0x002C57, 0x002C56,
+ 0x002C59, 0x002C58, 0x002C5B, 0x002C5A, 0x002175, 0x002C5C, 0x002177, 0x002C5E,
+ 0x002179, 0x002171, 0x00217B, 0x00217A, 0x00217D, 0x002174, 0x002176, 0x002178,
+ 0x0000E9, 0x0000E1, 0x0000EB, 0x0000E3, 0x0000ED, 0x0000E5, 0x0000EF, 0x0000E7,
+ 0x002C61, 0x0000F1, 0x002C73, 0x0000F3, 0x0000F5, 0x001F62, 0x001F7C, 0x002C76,
+ 0x002C66, 0x002C65, 0x0000F9, 0x0000FB, 0x001F7D, 0x0000FD, 0x001F78, 0x0000FF,
+ 0x001F79, 0x001F7A, 0x001F7B, 0x001F74, 0x001F76, 0x001F70, 0x001F72, 0x000209,
+ 0x00020B, 0x000205, 0x000207, 0x001F44, 0x000203, 0x001F40, 0x001F42, 0x000219,
+ 0x00021B, 0x001F54, 0x001F56, 0x00A681, 0x00A683, 0x001F24, 0x001F26, 0x001F20,
+ 0x001F22, 0x01E92C, 0x01E92E, 0x01E928, 0x01E92A, 0x001F30, 0x01E93C, 0x01E93E,
+ 0x01E939, 0x01E93A, 0x00A74D, 0x00A74F, 0x0118CE, 0x0118C4, 0x0118C6, 0x0118C0,
+ 0x002C89, 0x002C81, 0x002C8B, 0x002C83, 0x002C8D, 0x002C85, 0x002C8F, 0x002C87,
+ 0x000111, 0x002C91, 0x000113, 0x002C93, 0x002C95, 0x000117, 0x0118C2, 0x000115,
+ 0x000119, 0x00011B, 0x002C99, 0x002C9B, 0x0118D6, 0x002C9D, 0x0118D0, 0x002C9F,
+ 0x0118D2, 0x000161, 0x001FF4, 0x000163, 0x00A729, 0x001FF6, 0x002CC7, 0x00028C,
+ 0x00A725, 0x001FF2, 0x000289, 0x00028A, 0x00A73D, 0x00A739, 0x001FC6, 0x00A733,
+ 0x001FD7, 0x001FD0, 0x001FD1, 0x001FD2, 0x002CD5, 0x000175, 0x001FD3, 0x001FAC,
+ 0x00017E, 0x00017C, 0x00017A, 0x00017F, 0x001C85, 0x002CD9, 0x001C87, 0x001C88,
+ 0x000171, 0x001FAD, 0x001FAE, 0x000173, 0x002CE1, 0x000165, 0x002CE3, 0x000167,
+ 0x000177, 0x000169, 0x002CEC, 0x00016B, 0x002CEE, 0x00016D, 0x001FAF, 0x00016F,
+ 0x001FA8, 0x001FA9, 0x001FAA, 0x001FAB, 0x001FA4, 0x001FA5, 0x001FA6, 0x001FA7,
+ 0x001FA2, 0x001FA3, 0x001FBC, 0x001FBE, 0x00037B, 0x000377, 0x001FB4, 0x000371,
+ 0x002D20, 0x002D21, 0x002D22, 0x002D23, 0x002D25, 0x002D04, 0x002D27, 0x002D06,
+ 0x001FB6, 0x002D08, 0x001FB0, 0x002D0A, 0x002D24, 0x002D0C, 0x002D2D, 0x002D0E,
+ 0x001FB1, 0x001FB2, 0x001FB3, 0x001F8C, 0x001F8D, 0x001F8E, 0x001F8F, 0x001F88,
+ 0x001F8A, 0x010CED, 0x001F8B, 0x001F84, 0x001F85, 0x001F86, 0x001F87, 0x001F80,
+ 0x002D11, 0x000180, 0x000183, 0x002D13, 0x000195, 0x002D05, 0x000185, 0x002D07,
+ 0x002D17, 0x002D09, 0x000199, 0x002D0B, 0x000188, 0x002D0D, 0x00018C, 0x002D0F,
+ 0x010CC5, 0x010CC4, 0x010CC7, 0x010CC6, 0x010CC9, 0x010CC8, 0x010CCB, 0x010CCA,
+ 0x010CCD, 0x010CCC, 0x010CCF, 0x010CCE, 0x010CD1, 0x010CD0, 0x010CD3, 0x010CD2,
+ 0x0001A1, 0x002D01, 0x0001A3, 0x002D03, 0x0001A5, 0x001F81, 0x001F82, 0x001F83,
+ 0x010CD5, 0x0001A8, 0x010CD4, 0x001F9C, 0x010CE1, 0x010CF1, 0x010CE3, 0x010CE2,
+ 0x010CE0, 0x0001B9, 0x010CE7, 0x010CEB, 0x0001B6, 0x002D15, 0x001F9D, 0x010CEA,
+ 0x002D1E, 0x002D1C, 0x002D1A, 0x002D1F, 0x0001BD, 0x010CF0, 0x0001BF, 0x010CF2,
+ 0x001F9E, 0x010CE5, 0x001F9F, 0x010CE4, 0x0001C5, 0x010CE9, 0x001F98, 0x0001C6,
+ 0x0001C9, 0x0001C8, 0x0001CB, 0x010CEF, 0x001F99, 0x0001CC, 0x001F9A, 0x0001CE,
+ 0x001F9B, 0x001F94, 0x001F95, 0x001F96, 0x001F97, 0x001F90, 0x001F91, 0x001F92,
+ 0x001F93, 0x00A7A9, 0x00A7A5, 0x00A7A7, 0x0001DD, 0x0001DC, 0x0001DF, 0x00A7A1,
+ 0x0001E1, 0x00A7A3, 0x0001E3, 0x00A7B5, 0x0001E5, 0x00A7B7, 0x0001E7, 0x00A78C,
+ 0x00A797, 0x0003F8, 0x0001EB, 0x0001E9, 0x0001ED, 0x00A791, 0x0001EF, 0x0003F5,
+ 0x0003F0, 0x0001F0, 0x0001F3, 0x0001F2, 0x0001F5, 0x0003F1, 0x0003F2, 0x0003F3,
+ 0x0001F9, 0x0003CD, 0x0001FB, 0x0003CE, 0x0001FD, 0x0003C9, 0x0001FF, 0x0003CB,
+ 0x0003C4, 0x0003C7, 0x0003C0, 0x0003C2, 0x0003C3, 0x0003DD, 0x0003DF, 0x010CEC,
+ 0x010CEE, 0x010CE8, 0x010CE6, 0x002C48, 0x002C49, 0x002C4A, 0x000201, 0x002C4B,
+ 0x000211, 0x002C44, 0x000213, 0x002C45, 0x000215, 0x002C46, 0x000217, 0x002C47,
+ 0x002C40, 0x002C41, 0x002C42, 0x002C43, 0x0003BF, 0x010CC0, 0x010CC1, 0x010CC2,
+ 0x010CC3, 0x010CDC, 0x010CDD, 0x010CDE, 0x010CDF, 0x010CD8, 0x010CD9, 0x010CDA,
+ 0x010CDB, 0x010CD6, 0x010CD7, 0x002C38, 0x00022D, 0x002C39, 0x00022F, 0x002C3A,
+ 0x002C3B, 0x002C34, 0x002C35, 0x002C36, 0x001D79, 0x001D7D, 0x002C37, 0x002C31,
+ 0x002C32, 0x002C33, 0x00006C, 0x00006D, 0x00006E, 0x00006F, 0x000068, 0x000069,
+ 0x00006A, 0x00006B, 0x00026C, 0x000064, 0x000065, 0x000247, 0x00AB53, 0x000066,
+ 0x000249, 0x00024B, 0x000067, 0x000061, 0x00024D, 0x00026A, 0x00024F, 0x000062,
+ 0x000251, 0x000063, 0x000253, 0x000252, 0x000078, 0x000254, 0x000257, 0x000256,
+ 0x000079, 0x00007A, 0x000074, 0x000075, 0x000076, 0x000077, 0x00AB79, 0x00AB7B,
+ 0x000261, 0x00AB74, 0x000263, 0x00AB75, 0x00AB76, 0x0118C1, 0x00AB77, 0x0118CF,
+ 0x000269, 0x0118C5, 0x00026B, 0x0118C7, 0x00AB7A, 0x00AB7C, 0x00026F, 0x00AB70,
+ 0x00AB7D, 0x00AB7F, 0x00AB78, 0x00AB7E, 0x000275, 0x000265, 0x00A643, 0x000260,
+ 0x000271, 0x00AB71, 0x00AB72, 0x00A641, 0x00027D, 0x00AB73, 0x001C84, 0x001C86,
+ 0x001C80, 0x000280, 0x000283, 0x000287, 0x00ABB1, 0x00AB90, 0x00ABB3, 0x00AB92,
+ 0x00023F, 0x00AB94, 0x00028B, 0x00AB96, 0x00ABB0, 0x00AB98, 0x00ABB9, 0x00AB9A,
+ 0x00020D, 0x00020F, 0x00A665, 0x000292, 0x00A667, 0x00029D, 0x00021D, 0x00021F,
+ 0x001C81, 0x001C82, 0x001C83, 0x002CF3, 0x002CCD, 0x00029E, 0x002CCF, 0x000288,
+ 0x00AB8C, 0x00AB8D, 0x00AB8E, 0x00AB8F, 0x00ABA1, 0x00AB91, 0x00A66D, 0x00AB93,
+ 0x00A647, 0x00AB95, 0x0118CD, 0x00AB97, 0x0118C3, 0x00AB99, 0x000223, 0x00AB9B,
+ 0x002CC9, 0x0118C9, 0x00A64B, 0x0118CB, 0x0118D9, 0x00A645, 0x0118D3, 0x0118DB,
+ 0x0118D1, 0x0118D4, 0x0118DA, 0x000233, 0x002CCB, 0x001E15, 0x002CC5, 0x000231,
+ 0x0118DD, 0x002CC1, 0x0118DF, 0x001E0D, 0x0118D5, 0x00A649, 0x001E0F, 0x00A657,
+ 0x0118C8, 0x0118CC, 0x00A669, 0x0118CA, 0x002CC3, 0x00A64D, 0x00A663, 0x002CDD,
+ 0x001E13, 0x00A64F, 0x001E17, 0x00A661, 0x0118D8, 0x001E11, 0x00A66B, 0x0118D7,
+ 0x0118DC, 0x002CDF, 0x0118DE, 0x002CDB, 0x00A653, 0x002CD7, 0x00A655, 0x002CD1,
+ 0x00A65D, 0x00A659, 0x00A651, 0x00A65B, 0x002CD3, 0x002CAD, 0x002CAF, 0x00A65F,
+ 0x002CA9, 0x002CAB, 0x002CA5, 0x002CA7, 0x00A687, 0x001E19, 0x001E37, 0x00A685,
+ 0x00A689, 0x002CA1, 0x00A68B, 0x002CA3, 0x00A68D, 0x002CBD, 0x00A68F, 0x002CBF,
+ 0x002CB9, 0x001E1B, 0x001E35, 0x00023C, 0x001E41, 0x002CBB, 0x001E43, 0x002CB5,
+ 0x001E45, 0x002CB7, 0x001E47, 0x002CB1, 0x001E49, 0x002CB3, 0x001E4B, 0x0000EC,
+ 0x001E4D, 0x0000EE, 0x001E4F, 0x0000E8, 0x0000EA, 0x0000E4, 0x0000E6, 0x0000E0,
+ 0x001E55, 0x0000E2, 0x001E57, 0x0000FC, 0x001E59, 0x0000FE, 0x001E5B, 0x0000F8,
+ 0x001E5D, 0x0000FA, 0x001E5F, 0x0000F4, 0x0000F6, 0x002C97, 0x0000F0, 0x0000F2,
+ 0x001E65, 0x0000DF, 0x001E67, 0x00ABAC, 0x001E69, 0x001E6B, 0x001E39, 0x00ABAD,
+ 0x001E6D, 0x00ABAE, 0x001E6F, 0x00ABAF, 0x001E71, 0x001E73, 0x00A697, 0x00ABA8,
+ 0x00ABA9, 0x00ABAA, 0x00ABAB, 0x00ABA4, 0x001E33, 0x00ABA5, 0x00ABA6, 0x00ABA7,
+ 0x00ABA0, 0x00ABA2, 0x001E31, 0x00ABA3, 0x001ED1, 0x00ABBC, 0x001EDB, 0x00A693,
+ 0x00ABBD, 0x000345, 0x001ED5, 0x00ABBE, 0x00ABBF, 0x001E8B, 0x00ABB8, 0x001EBD,
+ 0x001E8D, 0x001E8F, 0x00A691, 0x001EBF, 0x001E91, 0x00ABBA, 0x001E93, 0x00ABBB,
+ 0x001E95, 0x00ABB4, 0x001E97, 0x001E96, 0x00ABB5, 0x001E98, 0x001E9B, 0x001E9A,
+ 0x00ABB6, 0x00ABB7, 0x00ABB2, 0x00AB88, 0x001EA1, 0x00AB89, 0x001EEF, 0x00A695,
+ 0x001EA5, 0x001EA3, 0x001EA7, 0x00AB8A, 0x00A699, 0x00AB8B, 0x00A69B, 0x00AB84,
+ 0x001EAD, 0x00A741, 0x001EAF, 0x00A743, 0x001EB1, 0x00A761, 0x001EB3, 0x00A74B,
+ 0x00AB85, 0x000373, 0x00AB86, 0x00AB87, 0x001EB9, 0x001EA9, 0x00AB80, 0x001ED9,
+ 0x001EB5, 0x00037C, 0x00AB81, 0x001EED, 0x00AB82, 0x001ED7, 0x001EE1, 0x00037D,
+ 0x001EC5, 0x001EE5, 0x001EC7, 0x001EE7, 0x001EC9, 0x00A75D, 0x001ECB, 0x001EEB,
+ 0x001EE9, 0x00AB83, 0x00A723, 0x00A76D, 0x00A765, 0x00A727, 0x001ED3, 0x0024E5,
+ 0x00A72D, 0x000390, 0x001EFD, 0x00A76F, 0x001EFF, 0x00A77C, 0x00A72F, 0x00A72B,
+ 0x0013FD, 0x0003D9, 0x0013FC, 0x00A737, 0x0013F9, 0x0013F8, 0x0013FB, 0x0013FA,
+ 0x0003E5, 0x00A77F, 0x00A73B, 0x00A73F, 0x0003E7, 0x00A735, 0x00A763, 0x001EE3,
+ 0x0003AC, 0x00A745, 0x00A749, 0x00A747, 0x0003AD, 0x0003BD, 0x0003AF, 0x0003AE,
+ 0x0003B1, 0x0003B0, 0x0003B3, 0x0003B2, 0x0003B5, 0x0003B4, 0x0003B7, 0x0003B6,
+ 0x0003B9, 0x0003B8, 0x0003BB, 0x0003BA, 0x00A75F, 0x0003BC, 0x001F06, 0x0003BE,
+ 0x00A759, 0x0003D1, 0x00A75B, 0x0003D0, 0x00A755, 0x0003D5, 0x0003ED, 0x00A757,
+ 0x0003EF, 0x0003E9, 0x00A767, 0x0003DB, 0x00A751, 0x01E925, 0x01E927, 0x0003E3,
+ 0x0003C1, 0x001F11, 0x01E923, 0x001F13, 0x0003E1, 0x00A769, 0x00A76B, 0x0003D6,
+ 0x0003C6, 0x0003C5, 0x001F15, 0x0003D7, 0x010429, 0x01042B, 0x01E936, 0x00A753,
+ 0x01042D, 0x0003C8, 0x01042F, 0x0003CC, 0x01043A, 0x010430, 0x00A77A, 0x010432,
+ 0x010438, 0x010434, 0x0003CA, 0x010436, 0x01E943, 0x001F35, 0x001F37, 0x01E941,
+ 0x01043B, 0x01043F, 0x001F33, 0x01043D, 0x0003EB, 0x010440, 0x010443, 0x0003FB,
+ 0x001F10, 0x001F14, 0x010445, 0x001F12, 0x001F25, 0x001F03, 0x001F27, 0x001F21,
+ 0x010448, 0x001F01, 0x01044C, 0x001F02, 0x00A783, 0x01E93D, 0x001F45, 0x00A793,
+ 0x00A787, 0x00A781, 0x01E92D, 0x001F00, 0x001F53, 0x01E922, 0x01E93F, 0x001F51,
+ 0x001F55, 0x01E926, 0x001F57, 0x01E929, 0x00A799, 0x01E938, 0x00A785, 0x01E92F,
+ 0x0024D1, 0x000438, 0x0024D3, 0x01E92B, 0x0024D5, 0x01E933, 0x0024D7, 0x00A79B,
+ 0x0024D9, 0x01E931, 0x0024DB, 0x01E932, 0x0024DD, 0x00043A, 0x0024DF, 0x00043B,
+ 0x0024E1, 0x01E93B, 0x0024E3, 0x01E930, 0x001F31, 0x001F32, 0x001F23, 0x01E937,
+ 0x000431, 0x001F36, 0x000433, 0x000434, 0x000435, 0x01E934, 0x000437, 0x000436,
+ 0x000439, 0x000430, 0x000432, 0x01E935, 0x00FF45, 0x00043C, 0x00FF4F, 0x0024E7,
+ 0x00A79D, 0x000440, 0x00FF49, 0x000442, 0x00A79F, 0x000444, 0x000447, 0x000446,
+ 0x000449, 0x001F89, 0x0104DD, 0x0104DF, 0x00044D, 0x0104D9, 0x00044F, 0x0104D8,
+ 0x000451, 0x000450, 0x000453, 0x01E924, 0x00AB9C, 0x00AB9D, 0x00AB9E, 0x00FF4D,
+ 0x000459, 0x00AB9F, 0x002D00, 0x00045A, 0x00045D, 0x00045C, 0x00045F, 0x001FA1,
+ 0x000461, 0x001FA0, 0x000463, 0x001F60, 0x000465, 0x002D02, 0x000467, 0x0104F7,
+ 0x00FF41, 0x00046B, 0x00FF43, 0x000469, 0x00046D, 0x00046F, 0x00FF47, 0x001F07,
+ 0x000471, 0x001FB7, 0x000473, 0x001F34, 0x000475, 0x001F04, 0x000477, 0x00FF58,
+ 0x000479, 0x00FF57, 0x00047B, 0x001F05, 0x00FF55, 0x001FC2, 0x00047F, 0x00047D,
+ 0x00FF59, 0x001FC4, 0x001FC7, 0x001FC3, 0x001FE0, 0x00FF4B, 0x001F41, 0x001F43,
+ 0x001FE4, 0x0104DB, 0x001FE6, 0x00FF53, 0x00048D, 0x00FF42, 0x00048F, 0x00FF51,
+ 0x001F63, 0x01E942, 0x00FF44, 0x001FD6, 0x0104E1, 0x01E940, 0x0104E3, 0x001FCC,
+ 0x0104E5, 0x0104EC, 0x0104E7, 0x0104EF, 0x0104E9, 0x0104ED, 0x0104EB, 0x0104EA,
+ 0x001FE5, 0x0104E8, 0x001FE7, 0x0104EE, 0x001FE1, 0x0004A1, 0x001F67, 0x001FE3,
+ 0x001F71, 0x001F73, 0x001FE2, 0x0004A3, 0x0104F9, 0x001FF3, 0x0104FB, 0x001FF7,
+ 0x0004B1, 0x001F52, 0x0004B3, 0x0104DA, 0x0004B5, 0x001F50, 0x0004B7, 0x001F75,
+ 0x0004B9, 0x001FFC, 0x0004BB, 0x001F77, 0x0004BD, 0x002D1D, 0x0004BF, 0x002D18,
+ 0x0004CC, 0x002D19, 0x002D1B, 0x002D14, 0x0004CE, 0x0004C4, 0x002D16, 0x0004C6,
+ 0x0004CF, 0x0004C8, 0x002D10, 0x0004CA, 0x002D12, 0x00014D, 0x00014F, 0x00048B,
+ 0x000148, 0x000149, 0x00014B, 0x000144, 0x000146, 0x000140, 0x000142, 0x00015D,
+ 0x00015F, 0x000159, 0x000491, 0x000493, 0x00015B, 0x000155, 0x000157, 0x000151,
+ 0x0004E1, 0x000153, 0x0004E3, 0x00012D, 0x00012F, 0x000129, 0x00012B, 0x000125,
+ 0x000127, 0x000121, 0x000123, 0x00013C, 0x00013E, 0x00013A, 0x000135, 0x000137,
+ 0x000131, 0x0004F3, 0x000133, 0x0004F1, 0x00010D, 0x00010F, 0x000109, 0x00010B,
+ 0x0004E9, 0x000105, 0x000107, 0x000101, 0x0004FD, 0x0004FF, 0x0004ED, 0x000103,
+ 0x000501, 0x00011D, 0x000503, 0x00011F, 0x000505, 0x00044C, 0x000507, 0x00044E,
+ 0x000509, 0x000448, 0x00050B, 0x00044A, 0x00050D, 0x00050F, 0x00044B, 0x000445,
+ 0x000511, 0x000441, 0x000513, 0x000443, 0x000515, 0x00045E, 0x000517, 0x000458,
+ 0x000519, 0x00045B, 0x00051B, 0x000454, 0x00051D, 0x000455, 0x00051F, 0x000456,
+ 0x000521, 0x000457, 0x000523, 0x000452, 0x000525, 0x000527, 0x0001D8, 0x0001DA,
+ 0x000529, 0x0001D4, 0x00052B, 0x0001D6, 0x0001D0, 0x00056D, 0x0001D2, 0x00056C,
+ 0x0001AD, 0x00043D, 0x00043E, 0x00043F, 0x002170, 0x002172, 0x002173, 0x0001B4,
+ 0x0001B0, 0x01044D, 0x01044E, 0x01044F, 0x010449, 0x01044A, 0x01044B, 0x00052F,
+ 0x010444, 0x010446, 0x010447, 0x010441, 0x010442, 0x00019E, 0x00019A, 0x0004EF,
+ 0x0004EB, 0x0004E5, 0x000192, 0x00056E, 0x0004E7, 0x01042C, 0x01042E, 0x010428,
+ 0x01042A, 0x0004F9, 0x0004FB, 0x0004F5, 0x0004F7, 0x01043C, 0x01043E, 0x010439,
+ 0x010435, 0x010437, 0x010431, 0x010433, 0x0004C2, 0x0004DD, 0x0004DF, 0x0004D9,
+ 0x0004DB, 0x00056F, 0x0004D5, 0x0004D7, 0x0004D1, 0x0004D3, 0x0004AD, 0x0004AF,
+ 0x0004A9, 0x0004AB, 0x0004A5, 0x0004A7, 0x0104E4, 0x0104E6, 0x0104E0, 0x0104E2,
+ 0x00FB14, 0x00FB16, 0x0104F8, 0x0104FA, };
+
+/* indexes */
+const uint16_t NU_TOUPPER_VALUES_I[] = {
+ 0x0714, 0x0719, 0x071E, 0x0700, 0x0705, 0x070A, 0x070F, 0x0452, 0x0470, 0x0473,
+ 0x046A, 0x046D, 0x05AE, 0x0464, 0x05B4, 0x0467, 0x05BA, 0x069C, 0x137B, 0x06A6,
+ 0x0563, 0x0566, 0x0569, 0x056C, 0x0557, 0x055A, 0x055D, 0x0548, 0x0560, 0x054E,
+ 0x0551, 0x0554, 0x059F, 0x05A2, 0x05A5, 0x05A8, 0x0593, 0x0596, 0x0599, 0x059C,
+ 0x156D, 0x157B, 0x1573, 0x1570, 0x0587, 0x156A, 0x058A, 0x157E, 0x058D, 0x0590,
+ 0x057B, 0x057E, 0x0581, 0x1577, 0x0584, 0x0D78, 0x0DDC, 0x0DE0, 0x1581, 0x0DCC,
+ 0x158B, 0x0DD4, 0x1595, 0x0DBC, 0x0DC4, 0x09D7, 0x09DB, 0x0A0F, 0x0A13, 0x0A07,
+ 0x0A0B, 0x09FF, 0x0A03, 0x0DAC, 0x0DB4, 0x0D9C, 0x0DA4, 0x0D8C, 0x0D94, 0x0D7C,
+ 0x0D84, 0x09B7, 0x09BB, 0x096F, 0x0973, 0x0967, 0x096B, 0x095F, 0x0963, 0x0957,
+ 0x095B, 0x098F, 0x0993, 0x098B, 0x0927, 0x092B, 0x091F, 0x0923, 0x0917, 0x091B,
+ 0x094F, 0x0953, 0x0BA1, 0x0BA5, 0x0B99, 0x0B9D, 0x0B91, 0x0B95, 0x0B49, 0x0B4D,
+ 0x05B7, 0x05BD, 0x0021, 0x0025, 0x05AB, 0x0023, 0x05B1, 0x001F, 0x0B31, 0x0B35,
+ 0x0B69, 0x0B6D, 0x1326, 0x132E, 0x1316, 0x131E, 0x130E, 0x0288, 0x0284, 0x0B05,
+ 0x135E, 0x1346, 0x134E, 0x1336, 0x133E, 0x0B25, 0x02A1, 0x0B1D, 0x0A27, 0x023E,
+ 0x0A1F, 0x0242, 0x0A23, 0x0272, 0x0A17, 0x0DE4, 0x0A1B, 0x026C, 0x0D34, 0x026F,
+ 0x138C, 0x0254, 0x0225, 0x0228, 0x021F, 0x0222, 0x0E18, 0x0E14, 0x0E20, 0x0E1C,
+ 0x0C61, 0x0EAA, 0x0C65, 0x0EB2, 0x0035, 0x0D68, 0x0C69, 0x0C55, 0x0E54, 0x0D70,
+ 0x0EAE, 0x0D74, 0x0E58, 0x0E98, 0x0E60, 0x0E5C, 0x0E68, 0x0E64, 0x0E70, 0x0E6C,
+ 0x0E78, 0x0E74, 0x0E80, 0x0E7C, 0x0E88, 0x0E84, 0x0E90, 0x0E8C, 0x0D4C, 0x0E94,
+ 0x0D54, 0x0E9C, 0x0D5C, 0x0D3C, 0x0D64, 0x0D60, 0x0D6C, 0x0D48, 0x0D50, 0x0D58,
+ 0x0053, 0x003B, 0x0059, 0x0041, 0x005F, 0x0047, 0x0065, 0x004D, 0x0EA0, 0x006B,
+ 0x0EB6, 0x0071, 0x0077, 0x0C59, 0x0CA1, 0x0EBA, 0x0EA7, 0x0EA4, 0x0080, 0x0086,
+ 0x0CA5, 0x008C, 0x0C91, 0x0092, 0x0C95, 0x0C99, 0x0C9D, 0x0C81, 0x0C89, 0x0C71,
+ 0x0C79, 0x01F8, 0x01FB, 0x01F2, 0x01F5, 0x0C39, 0x01EF, 0x0C29, 0x0C31, 0x0210,
+ 0x0213, 0x13A0, 0x13A7, 0x108E, 0x1092, 0x0BF9, 0x0C01, 0x0BE9, 0x0BF1, 0x0A6D,
+ 0x0A77, 0x0A59, 0x0A63, 0x0C09, 0x0AC1, 0x0ACB, 0x0AB2, 0x0AB7, 0x1116, 0x111A,
+ 0x0881, 0x084F, 0x0859, 0x083B, 0x0ECE, 0x0EBE, 0x0ED2, 0x0EC2, 0x0ED6, 0x0EC6,
+ 0x0EDA, 0x0ECA, 0x00AD, 0x0EDE, 0x00B0, 0x0EE2, 0x0EE6, 0x00B6, 0x0845, 0x00B3,
+ 0x00B9, 0x00BC, 0x0EEE, 0x0EF2, 0x08A9, 0x0EF6, 0x088B, 0x0EFA, 0x0895, 0x0121,
+ 0x1554, 0x0124, 0x10D2, 0x1559, 0x0F4A, 0x02C1, 0x10CA, 0x1549, 0x02B8, 0x02BB,
+ 0x10F6, 0x10EE, 0x14FF, 0x10E2, 0x1523, 0x0D1C, 0x0D20, 0x1510, 0x0F66, 0x013F,
+ 0x1517, 0x14B6, 0x014B, 0x0148, 0x0145, 0x014E, 0x0902, 0x0F6E, 0x0908, 0x090B,
+ 0x0139, 0x14BC, 0x14C2, 0x013C, 0x0F7E, 0x0127, 0x0F82, 0x012A, 0x0142, 0x012D,
+ 0x0F86, 0x0130, 0x0F8A, 0x0133, 0x14C8, 0x0136, 0x149E, 0x14A4, 0x14AA, 0x14B0,
+ 0x1486, 0x148C, 0x1492, 0x1498, 0x147A, 0x1480, 0x14EA, 0x0D15, 0x02DB, 0x02D8,
+ 0x14D9, 0x02D2, 0x1012, 0x1016, 0x101A, 0x101E, 0x1026, 0x0FA2, 0x102A, 0x0FAA,
+ 0x14DE, 0x0FB2, 0x0D09, 0x0FBA, 0x1022, 0x0FC2, 0x102E, 0x0FCA, 0x0D0D, 0x14CE,
+ 0x14D4, 0x13F6, 0x13FC, 0x1402, 0x1408, 0x13DE, 0x13EA, 0x081D, 0x13F0, 0x13C6,
+ 0x13CC, 0x13D2, 0x13D8, 0x13AE, 0x0FD6, 0x0150, 0x0153, 0x0FDE, 0x0162, 0x0FA6,
+ 0x0156, 0x0FAE, 0x0FEE, 0x0FB6, 0x0165, 0x0FBE, 0x0159, 0x0FC6, 0x015C, 0x0FCE,
+ 0x0755, 0x0750, 0x075F, 0x075A, 0x0769, 0x0764, 0x0773, 0x076E, 0x077D, 0x0778,
+ 0x0787, 0x0782, 0x0791, 0x078C, 0x079B, 0x0796, 0x016E, 0x0F96, 0x0171, 0x0F9E,
+ 0x0174, 0x13B4, 0x13BA, 0x13C0, 0x07A5, 0x0177, 0x07A0, 0x1456, 0x07E1, 0x0831,
+ 0x07EB, 0x07E6, 0x07DC, 0x0186, 0x07FF, 0x0813, 0x0183, 0x0FE6, 0x145C, 0x080E,
+ 0x100A, 0x1002, 0x0FFA, 0x100E, 0x0189, 0x082C, 0x018C, 0x0836, 0x1462, 0x07F5,
+ 0x1468, 0x07F0, 0x018F, 0x0809, 0x143E, 0x0192, 0x0198, 0x0195, 0x019B, 0x0827,
+ 0x1444, 0x019E, 0x144A, 0x01A1, 0x1450, 0x1426, 0x142C, 0x1432, 0x1438, 0x140E,
+ 0x1414, 0x141A, 0x1420, 0x11AA, 0x11A2, 0x11A6, 0x01B9, 0x01B6, 0x01BC, 0x119A,
+ 0x01BF, 0x119E, 0x01C2, 0x11AE, 0x01C5, 0x11B2, 0x01C8, 0x117A, 0x1186, 0x038C,
+ 0x01CE, 0x01CB, 0x01D1, 0x117E, 0x01D4, 0x0389, 0x037D, 0x1369, 0x01DA, 0x01D7,
+ 0x01DD, 0x0380, 0x0383, 0x0386, 0x01E0, 0x0344, 0x01E3, 0x0347, 0x01E6, 0x0338,
+ 0x01E9, 0x033E, 0x0329, 0x0332, 0x031D, 0x0323, 0x0326, 0x035F, 0x0362, 0x0818,
+ 0x0822, 0x0804, 0x07FA, 0x0E44, 0x0E48, 0x0E4C, 0x01EC, 0x0E50, 0x0204, 0x0E34,
+ 0x0207, 0x0E38, 0x020A, 0x0E3C, 0x020D, 0x0E40, 0x0E24, 0x0E28, 0x0E2C, 0x0E30,
+ 0x031A, 0x073C, 0x0741, 0x0746, 0x074B, 0x07C8, 0x07CD, 0x07D2, 0x07D7, 0x07B4,
+ 0x07B9, 0x07BE, 0x07C3, 0x07AA, 0x07AF, 0x0E04, 0x022B, 0x0E08, 0x022E, 0x0E0C,
+ 0x0E10, 0x0DF4, 0x0DF8, 0x0DFC, 0x090F, 0x0913, 0x0E00, 0x0DE8, 0x0DEC, 0x0DF0,
+ 0x0017, 0x0019, 0x001B, 0x001D, 0x000F, 0x0011, 0x0013, 0x0015, 0x0296, 0x0007,
+ 0x0009, 0x0245, 0x11B6, 0x000B, 0x0248, 0x024B, 0x000D, 0x0001, 0x024E, 0x028E,
+ 0x0251, 0x0003, 0x0258, 0x0005, 0x0260, 0x025C, 0x002F, 0x0263, 0x0269, 0x0266,
+ 0x0031, 0x0033, 0x0027, 0x0029, 0x002B, 0x002D, 0x11DE, 0x11E6, 0x0279, 0x11CA,
+ 0x027D, 0x11CE, 0x11D2, 0x0840, 0x11D6, 0x0886, 0x028B, 0x0854, 0x0292, 0x085E,
+ 0x11E2, 0x11EA, 0x029A, 0x11BA, 0x11EE, 0x11F6, 0x11DA, 0x11F2, 0x02A4, 0x0280,
+ 0x1036, 0x0276, 0x029D, 0x11BE, 0x11C2, 0x1032, 0x02A7, 0x11C6, 0x08FF, 0x0905,
+ 0x08F3, 0x02AB, 0x02AE, 0x02B1, 0x12BE, 0x123A, 0x12C6, 0x1242, 0x023A, 0x124A,
+ 0x02BE, 0x1252, 0x12BA, 0x125A, 0x12DE, 0x1262, 0x01FE, 0x0201, 0x107A, 0x02C4,
+ 0x107E, 0x02C7, 0x0216, 0x0219, 0x08F6, 0x08F9, 0x08FC, 0x0F8E, 0x0F56, 0x02CB,
+ 0x0F5A, 0x02B5, 0x122A, 0x122E, 0x1232, 0x1236, 0x127E, 0x123E, 0x108A, 0x1246,
+ 0x103E, 0x124E, 0x087C, 0x1256, 0x084A, 0x125E, 0x021C, 0x1266, 0x0F4E, 0x0868,
+ 0x1046, 0x0872, 0x08B8, 0x103A, 0x089A, 0x08C2, 0x0890, 0x089F, 0x08BD, 0x0234,
+ 0x0F52, 0x093F, 0x0F46, 0x0231, 0x08CC, 0x0F3E, 0x08D6, 0x092F, 0x08A4, 0x1042,
+ 0x0933, 0x105E, 0x0863, 0x0877, 0x1082, 0x086D, 0x0F42, 0x104A, 0x1076, 0x0F76,
+ 0x093B, 0x104E, 0x0943, 0x1072, 0x08B3, 0x0937, 0x1086, 0x08AE, 0x08C7, 0x0F7A,
+ 0x08D1, 0x0F72, 0x1056, 0x0F6A, 0x105A, 0x0F5E, 0x106A, 0x1062, 0x1052, 0x1066,
+ 0x0F62, 0x0F16, 0x0F1A, 0x106E, 0x0F0E, 0x0F12, 0x0F06, 0x0F0A, 0x109A, 0x0947,
+ 0x0983, 0x1096, 0x109E, 0x0EFE, 0x10A2, 0x0F02, 0x10A6, 0x0F36, 0x10AA, 0x0F3A,
+ 0x0F2E, 0x094B, 0x097F, 0x0237, 0x0997, 0x0F32, 0x099B, 0x0F26, 0x099F, 0x0F2A,
+ 0x09A3, 0x0F1E, 0x09A7, 0x0F22, 0x09AB, 0x005C, 0x09AF, 0x0062, 0x09B3, 0x0050,
+ 0x0056, 0x0044, 0x004A, 0x0038, 0x09BF, 0x003E, 0x09C3, 0x0089, 0x09C7, 0x008F,
+ 0x09CB, 0x007D, 0x09CF, 0x0083, 0x09D3, 0x0074, 0x007A, 0x0EEA, 0x0068, 0x006E,
+ 0x09DF, 0x1362, 0x09E3, 0x12AA, 0x09E7, 0x09EB, 0x0987, 0x12AE, 0x09EF, 0x12B2,
+ 0x09F3, 0x12B6, 0x09F7, 0x09FB, 0x10BA, 0x129A, 0x129E, 0x12A2, 0x12A6, 0x128A,
+ 0x097B, 0x128E, 0x1292, 0x1296, 0x127A, 0x1282, 0x0977, 0x1286, 0x0B51, 0x12EA,
+ 0x0B65, 0x10B2, 0x12EE, 0x02CF, 0x0B59, 0x12F2, 0x12F6, 0x0A2B, 0x12DA, 0x0B29,
+ 0x0A2F, 0x0A33, 0x10AE, 0x0B2D, 0x0A37, 0x12E2, 0x0A81, 0x12E6, 0x0AE9, 0x12CA,
+ 0x1384, 0x1380, 0x12CE, 0x1388, 0x0AED, 0x1390, 0x12D2, 0x12D6, 0x12C2, 0x121A,
+ 0x0AF1, 0x121E, 0x0B8D, 0x10B6, 0x0AF9, 0x0AF5, 0x0AFD, 0x1222, 0x10BE, 0x1226,
+ 0x10C2, 0x120A, 0x0B09, 0x10FE, 0x0B0D, 0x1102, 0x0B11, 0x113E, 0x0B15, 0x1112,
+ 0x120E, 0x02D5, 0x1212, 0x1216, 0x0B21, 0x0B01, 0x11FA, 0x0B61, 0x0B19, 0x02DE,
+ 0x11FE, 0x0B89, 0x1202, 0x0B5D, 0x0B71, 0x02E1, 0x0B39, 0x0B79, 0x0B3D, 0x0B7D,
+ 0x0B41, 0x1136, 0x0B45, 0x0B85, 0x0B81, 0x1206, 0x10C6, 0x1156, 0x1146, 0x10CE,
+ 0x0B55, 0x0DD0, 0x10DA, 0x136D, 0x0BA9, 0x115A, 0x0BAD, 0x1162, 0x10DE, 0x10D6,
+ 0x08EF, 0x0359, 0x08EB, 0x10EA, 0x08DF, 0x08DB, 0x08E7, 0x08E3, 0x036B, 0x1166,
+ 0x10F2, 0x10FA, 0x036E, 0x10E6, 0x1142, 0x0B75, 0x02E4, 0x1106, 0x110E, 0x110A,
+ 0x02E7, 0x0314, 0x02ED, 0x02EA, 0x02F0, 0x1374, 0x02F6, 0x02F3, 0x02FC, 0x02F9,
+ 0x0302, 0x02FF, 0x0308, 0x0305, 0x030E, 0x030B, 0x113A, 0x0311, 0x0BC9, 0x0317,
+ 0x112E, 0x034D, 0x1132, 0x034A, 0x1126, 0x0350, 0x0377, 0x112A, 0x037A, 0x0371,
+ 0x114A, 0x035C, 0x111E, 0x0A4A, 0x0A54, 0x0368, 0x0320, 0x0BD5, 0x0A40, 0x0BDD,
+ 0x0365, 0x114E, 0x1152, 0x0353, 0x032F, 0x032C, 0x0BE5, 0x0356, 0x05C5, 0x05CF,
+ 0x0AA3, 0x1122, 0x05D9, 0x0335, 0x05E3, 0x0341, 0x061A, 0x05E8, 0x115E, 0x05F2,
+ 0x0610, 0x05FC, 0x033B, 0x0606, 0x0AE4, 0x0C1D, 0x0C25, 0x0ADA, 0x061F, 0x0633,
+ 0x0C15, 0x0629, 0x0374, 0x0638, 0x0647, 0x038F, 0x0BD1, 0x0BE1, 0x0651, 0x0BD9,
+ 0x0BFD, 0x0BBD, 0x0C05, 0x0BED, 0x0660, 0x0BB5, 0x0674, 0x0BB9, 0x116E, 0x0AC6,
+ 0x0C3D, 0x1182, 0x1176, 0x116A, 0x0A72, 0x0BB1, 0x0C45, 0x0A3B, 0x0AD0, 0x0C41,
+ 0x0C49, 0x0A4F, 0x0C4D, 0x0A5E, 0x118A, 0x0AAD, 0x1172, 0x0A7C, 0x0D80, 0x03AA,
+ 0x0D88, 0x0A68, 0x0D90, 0x0A94, 0x0D98, 0x118E, 0x0DA0, 0x0A8A, 0x0DA8, 0x0A8F,
+ 0x0DB0, 0x03B0, 0x0DB8, 0x03B3, 0x0DC0, 0x0ABC, 0x0DC8, 0x0A85, 0x0C0D, 0x0C11,
+ 0x0BF5, 0x0AA8, 0x0395, 0x0C21, 0x039B, 0x039E, 0x03A1, 0x0A99, 0x03A7, 0x03A4,
+ 0x03AD, 0x0392, 0x0398, 0x0A9E, 0x130A, 0x03B6, 0x1332, 0x0DD8, 0x1192, 0x03C2,
+ 0x131A, 0x03C8, 0x1196, 0x03CE, 0x03D7, 0x03D4, 0x03DD, 0x13E4, 0x06A1, 0x06AB,
+ 0x03E9, 0x068D, 0x03EF, 0x0688, 0x03F5, 0x03F2, 0x03FB, 0x0A45, 0x126A, 0x126E,
+ 0x1272, 0x132A, 0x040D, 0x1276, 0x0F92, 0x0410, 0x0419, 0x0416, 0x041F, 0x1474,
+ 0x0422, 0x146E, 0x0425, 0x0C51, 0x0428, 0x0F9A, 0x042B, 0x0723, 0x12FA, 0x0431,
+ 0x1302, 0x042E, 0x0434, 0x0437, 0x1312, 0x0BCD, 0x043A, 0x14E3, 0x043D, 0x0C19,
+ 0x0440, 0x0BC1, 0x0443, 0x1356, 0x0446, 0x1352, 0x0449, 0x0BC5, 0x134A, 0x14EF,
+ 0x044F, 0x044C, 0x135A, 0x14FA, 0x1504, 0x14F5, 0x0D24, 0x1322, 0x0C2D, 0x0C35,
+ 0x1538, 0x0697, 0x153D, 0x1342, 0x0458, 0x12FE, 0x045B, 0x133A, 0x0C5D, 0x0ADF,
+ 0x1306, 0x151E, 0x06B5, 0x0AD5, 0x06BF, 0x150B, 0x06C9, 0x06EC, 0x06D3, 0x06FB,
+ 0x06DD, 0x06F1, 0x06E7, 0x06E2, 0x0D2C, 0x06D8, 0x1542, 0x06F6, 0x0D28, 0x0476,
+ 0x0C6D, 0x1531, 0x0C75, 0x0C7D, 0x152A, 0x0479, 0x072D, 0x154F, 0x0737, 0x155E,
+ 0x048E, 0x1399, 0x0491, 0x0692, 0x0494, 0x1394, 0x0497, 0x0C85, 0x049A, 0x1565,
+ 0x049D, 0x0C8D, 0x04A0, 0x1006, 0x04A3, 0x0FF2, 0x04B5, 0x0FF6, 0x0FFE, 0x0FE2,
+ 0x04B8, 0x04A9, 0x0FEA, 0x04AC, 0x04BB, 0x04AF, 0x0FD2, 0x04B2, 0x0FDA, 0x0103,
+ 0x0106, 0x0455, 0x00FD, 0x1365, 0x0100, 0x00F7, 0x00FA, 0x00F1, 0x00F4, 0x011B,
+ 0x011E, 0x0115, 0x045E, 0x0461, 0x0118, 0x010F, 0x0112, 0x0109, 0x04D6, 0x010C,
+ 0x04D9, 0x00D7, 0x00DA, 0x00D1, 0x00D4, 0x00CB, 0x00CE, 0x00C5, 0x00C8, 0x00EB,
+ 0x00EE, 0x00E8, 0x00E2, 0x00E5, 0x00DD, 0x04F1, 0x00DF, 0x04EE, 0x00A7, 0x00AA,
+ 0x00A1, 0x00A4, 0x04E2, 0x009B, 0x009E, 0x0095, 0x0500, 0x0503, 0x04E8, 0x0098,
+ 0x0506, 0x00BF, 0x0509, 0x00C2, 0x050C, 0x03E6, 0x050F, 0x03EC, 0x0512, 0x03DA,
+ 0x0515, 0x03E0, 0x0518, 0x051B, 0x03E3, 0x03D1, 0x051E, 0x03C5, 0x0521, 0x03CB,
+ 0x0524, 0x041C, 0x0527, 0x040A, 0x052A, 0x0413, 0x052D, 0x03FE, 0x0530, 0x0401,
+ 0x0533, 0x0404, 0x0536, 0x0407, 0x0539, 0x03F8, 0x053C, 0x053F, 0x01B0, 0x01B3,
+ 0x0542, 0x01AA, 0x0545, 0x01AD, 0x01A4, 0x0572, 0x01A7, 0x056F, 0x017A, 0x03B9,
+ 0x03BC, 0x03BF, 0x0D38, 0x0D40, 0x0D44, 0x0180, 0x017D, 0x0679, 0x067E, 0x0683,
+ 0x0665, 0x066A, 0x066F, 0x054B, 0x064C, 0x0656, 0x065B, 0x063D, 0x0642, 0x016B,
+ 0x0168, 0x04EB, 0x04E5, 0x04DC, 0x015F, 0x0575, 0x04DF, 0x05D4, 0x05DE, 0x05C0,
+ 0x05CA, 0x04FA, 0x04FD, 0x04F4, 0x04F7, 0x0624, 0x062E, 0x0615, 0x0601, 0x060B,
+ 0x05ED, 0x05F7, 0x04A6, 0x04D0, 0x04D3, 0x04CA, 0x04CD, 0x0578, 0x04C4, 0x04C7,
+ 0x04BE, 0x04C1, 0x0488, 0x048B, 0x0482, 0x0485, 0x047C, 0x047F, 0x06C4, 0x06CE,
+ 0x06B0, 0x06BA, 0x1586, 0x1590, 0x0728, 0x0732, };
+
+const uint8_t NU_TOUPPER_COMBINED[] = {
+ 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46,
+ 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C,
+ 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52,
+ 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58,
+ 0x00, 0x59, 0x00, 0x5A, 0x00, 0xCE, 0x9C, 0x00, 0xC3, 0x80, 0x00, 0xC3,
+ 0x81, 0x00, 0xC3, 0x82, 0x00, 0xC3, 0x83, 0x00, 0xC3, 0x84, 0x00, 0xC3,
+ 0x85, 0x00, 0xC3, 0x86, 0x00, 0xC3, 0x87, 0x00, 0xC3, 0x88, 0x00, 0xC3,
+ 0x89, 0x00, 0xC3, 0x8A, 0x00, 0xC3, 0x8B, 0x00, 0xC3, 0x8C, 0x00, 0xC3,
+ 0x8D, 0x00, 0xC3, 0x8E, 0x00, 0xC3, 0x8F, 0x00, 0xC3, 0x90, 0x00, 0xC3,
+ 0x91, 0x00, 0xC3, 0x92, 0x00, 0xC3, 0x93, 0x00, 0xC3, 0x94, 0x00, 0xC3,
+ 0x95, 0x00, 0xC3, 0x96, 0x00, 0xC3, 0x98, 0x00, 0xC3, 0x99, 0x00, 0xC3,
+ 0x9A, 0x00, 0xC3, 0x9B, 0x00, 0xC3, 0x9C, 0x00, 0xC3, 0x9D, 0x00, 0xC3,
+ 0x9E, 0x00, 0xC5, 0xB8, 0x00, 0xC4, 0x80, 0x00, 0xC4, 0x82, 0x00, 0xC4,
+ 0x84, 0x00, 0xC4, 0x86, 0x00, 0xC4, 0x88, 0x00, 0xC4, 0x8A, 0x00, 0xC4,
+ 0x8C, 0x00, 0xC4, 0x8E, 0x00, 0xC4, 0x90, 0x00, 0xC4, 0x92, 0x00, 0xC4,
+ 0x94, 0x00, 0xC4, 0x96, 0x00, 0xC4, 0x98, 0x00, 0xC4, 0x9A, 0x00, 0xC4,
+ 0x9C, 0x00, 0xC4, 0x9E, 0x00, 0xC4, 0xA0, 0x00, 0xC4, 0xA2, 0x00, 0xC4,
+ 0xA4, 0x00, 0xC4, 0xA6, 0x00, 0xC4, 0xA8, 0x00, 0xC4, 0xAA, 0x00, 0xC4,
+ 0xAC, 0x00, 0xC4, 0xAE, 0x00, 0x49, 0x00, 0xC4, 0xB2, 0x00, 0xC4, 0xB4,
+ 0x00, 0xC4, 0xB6, 0x00, 0xC4, 0xB9, 0x00, 0xC4, 0xBB, 0x00, 0xC4, 0xBD,
+ 0x00, 0xC4, 0xBF, 0x00, 0xC5, 0x81, 0x00, 0xC5, 0x83, 0x00, 0xC5, 0x85,
+ 0x00, 0xC5, 0x87, 0x00, 0xC5, 0x8A, 0x00, 0xC5, 0x8C, 0x00, 0xC5, 0x8E,
+ 0x00, 0xC5, 0x90, 0x00, 0xC5, 0x92, 0x00, 0xC5, 0x94, 0x00, 0xC5, 0x96,
+ 0x00, 0xC5, 0x98, 0x00, 0xC5, 0x9A, 0x00, 0xC5, 0x9C, 0x00, 0xC5, 0x9E,
+ 0x00, 0xC5, 0xA0, 0x00, 0xC5, 0xA2, 0x00, 0xC5, 0xA4, 0x00, 0xC5, 0xA6,
+ 0x00, 0xC5, 0xA8, 0x00, 0xC5, 0xAA, 0x00, 0xC5, 0xAC, 0x00, 0xC5, 0xAE,
+ 0x00, 0xC5, 0xB0, 0x00, 0xC5, 0xB2, 0x00, 0xC5, 0xB4, 0x00, 0xC5, 0xB6,
+ 0x00, 0xC5, 0xB9, 0x00, 0xC5, 0xBB, 0x00, 0xC5, 0xBD, 0x00, 0x53, 0x00,
+ 0xC9, 0x83, 0x00, 0xC6, 0x82, 0x00, 0xC6, 0x84, 0x00, 0xC6, 0x87, 0x00,
+ 0xC6, 0x8B, 0x00, 0xC6, 0x91, 0x00, 0xC7, 0xB6, 0x00, 0xC6, 0x98, 0x00,
+ 0xC8, 0xBD, 0x00, 0xC8, 0xA0, 0x00, 0xC6, 0xA0, 0x00, 0xC6, 0xA2, 0x00,
+ 0xC6, 0xA4, 0x00, 0xC6, 0xA7, 0x00, 0xC6, 0xAC, 0x00, 0xC6, 0xAF, 0x00,
+ 0xC6, 0xB3, 0x00, 0xC6, 0xB5, 0x00, 0xC6, 0xB8, 0x00, 0xC6, 0xBC, 0x00,
+ 0xC7, 0xB7, 0x00, 0xC7, 0x84, 0x00, 0xC7, 0x84, 0x00, 0xC7, 0x87, 0x00,
+ 0xC7, 0x87, 0x00, 0xC7, 0x8A, 0x00, 0xC7, 0x8A, 0x00, 0xC7, 0x8D, 0x00,
+ 0xC7, 0x8F, 0x00, 0xC7, 0x91, 0x00, 0xC7, 0x93, 0x00, 0xC7, 0x95, 0x00,
+ 0xC7, 0x97, 0x00, 0xC7, 0x99, 0x00, 0xC7, 0x9B, 0x00, 0xC6, 0x8E, 0x00,
+ 0xC7, 0x9E, 0x00, 0xC7, 0xA0, 0x00, 0xC7, 0xA2, 0x00, 0xC7, 0xA4, 0x00,
+ 0xC7, 0xA6, 0x00, 0xC7, 0xA8, 0x00, 0xC7, 0xAA, 0x00, 0xC7, 0xAC, 0x00,
+ 0xC7, 0xAE, 0x00, 0xC7, 0xB1, 0x00, 0xC7, 0xB1, 0x00, 0xC7, 0xB4, 0x00,
+ 0xC7, 0xB8, 0x00, 0xC7, 0xBA, 0x00, 0xC7, 0xBC, 0x00, 0xC7, 0xBE, 0x00,
+ 0xC8, 0x80, 0x00, 0xC8, 0x82, 0x00, 0xC8, 0x84, 0x00, 0xC8, 0x86, 0x00,
+ 0xC8, 0x88, 0x00, 0xC8, 0x8A, 0x00, 0xC8, 0x8C, 0x00, 0xC8, 0x8E, 0x00,
+ 0xC8, 0x90, 0x00, 0xC8, 0x92, 0x00, 0xC8, 0x94, 0x00, 0xC8, 0x96, 0x00,
+ 0xC8, 0x98, 0x00, 0xC8, 0x9A, 0x00, 0xC8, 0x9C, 0x00, 0xC8, 0x9E, 0x00,
+ 0xC8, 0xA2, 0x00, 0xC8, 0xA4, 0x00, 0xC8, 0xA6, 0x00, 0xC8, 0xA8, 0x00,
+ 0xC8, 0xAA, 0x00, 0xC8, 0xAC, 0x00, 0xC8, 0xAE, 0x00, 0xC8, 0xB0, 0x00,
+ 0xC8, 0xB2, 0x00, 0xC8, 0xBB, 0x00, 0xE2, 0xB1, 0xBE, 0x00, 0xE2, 0xB1,
+ 0xBF, 0x00, 0xC9, 0x81, 0x00, 0xC9, 0x86, 0x00, 0xC9, 0x88, 0x00, 0xC9,
+ 0x8A, 0x00, 0xC9, 0x8C, 0x00, 0xC9, 0x8E, 0x00, 0xE2, 0xB1, 0xAF, 0x00,
+ 0xE2, 0xB1, 0xAD, 0x00, 0xE2, 0xB1, 0xB0, 0x00, 0xC6, 0x81, 0x00, 0xC6,
+ 0x86, 0x00, 0xC6, 0x89, 0x00, 0xC6, 0x8A, 0x00, 0xC6, 0x8F, 0x00, 0xC6,
+ 0x90, 0x00, 0xEA, 0x9E, 0xAB, 0x00, 0xC6, 0x93, 0x00, 0xEA, 0x9E, 0xAC,
+ 0x00, 0xC6, 0x94, 0x00, 0xEA, 0x9E, 0x8D, 0x00, 0xEA, 0x9E, 0xAA, 0x00,
+ 0xC6, 0x97, 0x00, 0xC6, 0x96, 0x00, 0xEA, 0x9E, 0xAE, 0x00, 0xE2, 0xB1,
+ 0xA2, 0x00, 0xEA, 0x9E, 0xAD, 0x00, 0xC6, 0x9C, 0x00, 0xE2, 0xB1, 0xAE,
+ 0x00, 0xC6, 0x9D, 0x00, 0xC6, 0x9F, 0x00, 0xE2, 0xB1, 0xA4, 0x00, 0xC6,
+ 0xA6, 0x00, 0xC6, 0xA9, 0x00, 0xEA, 0x9E, 0xB1, 0x00, 0xC6, 0xAE, 0x00,
+ 0xC9, 0x84, 0x00, 0xC6, 0xB1, 0x00, 0xC6, 0xB2, 0x00, 0xC9, 0x85, 0x00,
+ 0xC6, 0xB7, 0x00, 0xEA, 0x9E, 0xB2, 0x00, 0xEA, 0x9E, 0xB0, 0x00, 0xCE,
+ 0x99, 0x00, 0xCD, 0xB0, 0x00, 0xCD, 0xB2, 0x00, 0xCD, 0xB6, 0x00, 0xCF,
+ 0xBD, 0x00, 0xCF, 0xBE, 0x00, 0xCF, 0xBF, 0x00, 0xCE, 0x86, 0x00, 0xCE,
+ 0x88, 0x00, 0xCE, 0x89, 0x00, 0xCE, 0x8A, 0x00, 0xCE, 0x91, 0x00, 0xCE,
+ 0x92, 0x00, 0xCE, 0x93, 0x00, 0xCE, 0x94, 0x00, 0xCE, 0x95, 0x00, 0xCE,
+ 0x96, 0x00, 0xCE, 0x97, 0x00, 0xCE, 0x98, 0x00, 0xCE, 0x99, 0x00, 0xCE,
+ 0x9A, 0x00, 0xCE, 0x9B, 0x00, 0xCE, 0x9C, 0x00, 0xCE, 0x9D, 0x00, 0xCE,
+ 0x9E, 0x00, 0xCE, 0x9F, 0x00, 0xCE, 0xA0, 0x00, 0xCE, 0xA1, 0x00, 0xCE,
+ 0xA3, 0x00, 0xCE, 0xA3, 0x00, 0xCE, 0xA4, 0x00, 0xCE, 0xA5, 0x00, 0xCE,
+ 0xA6, 0x00, 0xCE, 0xA7, 0x00, 0xCE, 0xA8, 0x00, 0xCE, 0xA9, 0x00, 0xCE,
+ 0xAA, 0x00, 0xCE, 0xAB, 0x00, 0xCE, 0x8C, 0x00, 0xCE, 0x8E, 0x00, 0xCE,
+ 0x8F, 0x00, 0xCE, 0x92, 0x00, 0xCE, 0x98, 0x00, 0xCE, 0xA6, 0x00, 0xCE,
+ 0xA0, 0x00, 0xCF, 0x8F, 0x00, 0xCF, 0x98, 0x00, 0xCF, 0x9A, 0x00, 0xCF,
+ 0x9C, 0x00, 0xCF, 0x9E, 0x00, 0xCF, 0xA0, 0x00, 0xCF, 0xA2, 0x00, 0xCF,
+ 0xA4, 0x00, 0xCF, 0xA6, 0x00, 0xCF, 0xA8, 0x00, 0xCF, 0xAA, 0x00, 0xCF,
+ 0xAC, 0x00, 0xCF, 0xAE, 0x00, 0xCE, 0x9A, 0x00, 0xCE, 0xA1, 0x00, 0xCF,
+ 0xB9, 0x00, 0xCD, 0xBF, 0x00, 0xCE, 0x95, 0x00, 0xCF, 0xB7, 0x00, 0xCF,
+ 0xBA, 0x00, 0xD0, 0x90, 0x00, 0xD0, 0x91, 0x00, 0xD0, 0x92, 0x00, 0xD0,
+ 0x93, 0x00, 0xD0, 0x94, 0x00, 0xD0, 0x95, 0x00, 0xD0, 0x96, 0x00, 0xD0,
+ 0x97, 0x00, 0xD0, 0x98, 0x00, 0xD0, 0x99, 0x00, 0xD0, 0x9A, 0x00, 0xD0,
+ 0x9B, 0x00, 0xD0, 0x9C, 0x00, 0xD0, 0x9D, 0x00, 0xD0, 0x9E, 0x00, 0xD0,
+ 0x9F, 0x00, 0xD0, 0xA0, 0x00, 0xD0, 0xA1, 0x00, 0xD0, 0xA2, 0x00, 0xD0,
+ 0xA3, 0x00, 0xD0, 0xA4, 0x00, 0xD0, 0xA5, 0x00, 0xD0, 0xA6, 0x00, 0xD0,
+ 0xA7, 0x00, 0xD0, 0xA8, 0x00, 0xD0, 0xA9, 0x00, 0xD0, 0xAA, 0x00, 0xD0,
+ 0xAB, 0x00, 0xD0, 0xAC, 0x00, 0xD0, 0xAD, 0x00, 0xD0, 0xAE, 0x00, 0xD0,
+ 0xAF, 0x00, 0xD0, 0x80, 0x00, 0xD0, 0x81, 0x00, 0xD0, 0x82, 0x00, 0xD0,
+ 0x83, 0x00, 0xD0, 0x84, 0x00, 0xD0, 0x85, 0x00, 0xD0, 0x86, 0x00, 0xD0,
+ 0x87, 0x00, 0xD0, 0x88, 0x00, 0xD0, 0x89, 0x00, 0xD0, 0x8A, 0x00, 0xD0,
+ 0x8B, 0x00, 0xD0, 0x8C, 0x00, 0xD0, 0x8D, 0x00, 0xD0, 0x8E, 0x00, 0xD0,
+ 0x8F, 0x00, 0xD1, 0xA0, 0x00, 0xD1, 0xA2, 0x00, 0xD1, 0xA4, 0x00, 0xD1,
+ 0xA6, 0x00, 0xD1, 0xA8, 0x00, 0xD1, 0xAA, 0x00, 0xD1, 0xAC, 0x00, 0xD1,
+ 0xAE, 0x00, 0xD1, 0xB0, 0x00, 0xD1, 0xB2, 0x00, 0xD1, 0xB4, 0x00, 0xD1,
+ 0xB6, 0x00, 0xD1, 0xB8, 0x00, 0xD1, 0xBA, 0x00, 0xD1, 0xBC, 0x00, 0xD1,
+ 0xBE, 0x00, 0xD2, 0x80, 0x00, 0xD2, 0x8A, 0x00, 0xD2, 0x8C, 0x00, 0xD2,
+ 0x8E, 0x00, 0xD2, 0x90, 0x00, 0xD2, 0x92, 0x00, 0xD2, 0x94, 0x00, 0xD2,
+ 0x96, 0x00, 0xD2, 0x98, 0x00, 0xD2, 0x9A, 0x00, 0xD2, 0x9C, 0x00, 0xD2,
+ 0x9E, 0x00, 0xD2, 0xA0, 0x00, 0xD2, 0xA2, 0x00, 0xD2, 0xA4, 0x00, 0xD2,
+ 0xA6, 0x00, 0xD2, 0xA8, 0x00, 0xD2, 0xAA, 0x00, 0xD2, 0xAC, 0x00, 0xD2,
+ 0xAE, 0x00, 0xD2, 0xB0, 0x00, 0xD2, 0xB2, 0x00, 0xD2, 0xB4, 0x00, 0xD2,
+ 0xB6, 0x00, 0xD2, 0xB8, 0x00, 0xD2, 0xBA, 0x00, 0xD2, 0xBC, 0x00, 0xD2,
+ 0xBE, 0x00, 0xD3, 0x81, 0x00, 0xD3, 0x83, 0x00, 0xD3, 0x85, 0x00, 0xD3,
+ 0x87, 0x00, 0xD3, 0x89, 0x00, 0xD3, 0x8B, 0x00, 0xD3, 0x8D, 0x00, 0xD3,
+ 0x80, 0x00, 0xD3, 0x90, 0x00, 0xD3, 0x92, 0x00, 0xD3, 0x94, 0x00, 0xD3,
+ 0x96, 0x00, 0xD3, 0x98, 0x00, 0xD3, 0x9A, 0x00, 0xD3, 0x9C, 0x00, 0xD3,
+ 0x9E, 0x00, 0xD3, 0xA0, 0x00, 0xD3, 0xA2, 0x00, 0xD3, 0xA4, 0x00, 0xD3,
+ 0xA6, 0x00, 0xD3, 0xA8, 0x00, 0xD3, 0xAA, 0x00, 0xD3, 0xAC, 0x00, 0xD3,
+ 0xAE, 0x00, 0xD3, 0xB0, 0x00, 0xD3, 0xB2, 0x00, 0xD3, 0xB4, 0x00, 0xD3,
+ 0xB6, 0x00, 0xD3, 0xB8, 0x00, 0xD3, 0xBA, 0x00, 0xD3, 0xBC, 0x00, 0xD3,
+ 0xBE, 0x00, 0xD4, 0x80, 0x00, 0xD4, 0x82, 0x00, 0xD4, 0x84, 0x00, 0xD4,
+ 0x86, 0x00, 0xD4, 0x88, 0x00, 0xD4, 0x8A, 0x00, 0xD4, 0x8C, 0x00, 0xD4,
+ 0x8E, 0x00, 0xD4, 0x90, 0x00, 0xD4, 0x92, 0x00, 0xD4, 0x94, 0x00, 0xD4,
+ 0x96, 0x00, 0xD4, 0x98, 0x00, 0xD4, 0x9A, 0x00, 0xD4, 0x9C, 0x00, 0xD4,
+ 0x9E, 0x00, 0xD4, 0xA0, 0x00, 0xD4, 0xA2, 0x00, 0xD4, 0xA4, 0x00, 0xD4,
+ 0xA6, 0x00, 0xD4, 0xA8, 0x00, 0xD4, 0xAA, 0x00, 0xD4, 0xAC, 0x00, 0xD4,
+ 0xAE, 0x00, 0xD4, 0xB1, 0x00, 0xD4, 0xB2, 0x00, 0xD4, 0xB3, 0x00, 0xD4,
+ 0xB4, 0x00, 0xD4, 0xB5, 0x00, 0xD4, 0xB6, 0x00, 0xD4, 0xB7, 0x00, 0xD4,
+ 0xB8, 0x00, 0xD4, 0xB9, 0x00, 0xD4, 0xBA, 0x00, 0xD4, 0xBB, 0x00, 0xD4,
+ 0xBC, 0x00, 0xD4, 0xBD, 0x00, 0xD4, 0xBE, 0x00, 0xD4, 0xBF, 0x00, 0xD5,
+ 0x80, 0x00, 0xD5, 0x81, 0x00, 0xD5, 0x82, 0x00, 0xD5, 0x83, 0x00, 0xD5,
+ 0x84, 0x00, 0xD5, 0x85, 0x00, 0xD5, 0x86, 0x00, 0xD5, 0x87, 0x00, 0xD5,
+ 0x88, 0x00, 0xD5, 0x89, 0x00, 0xD5, 0x8A, 0x00, 0xD5, 0x8B, 0x00, 0xD5,
+ 0x8C, 0x00, 0xD5, 0x8D, 0x00, 0xD5, 0x8E, 0x00, 0xD5, 0x8F, 0x00, 0xD5,
+ 0x90, 0x00, 0xD5, 0x91, 0x00, 0xD5, 0x92, 0x00, 0xD5, 0x93, 0x00, 0xD5,
+ 0x94, 0x00, 0xD5, 0x95, 0x00, 0xD5, 0x96, 0x00, 0xF0, 0x90, 0x90, 0x80,
+ 0x00, 0xF0, 0x90, 0x90, 0x81, 0x00, 0xF0, 0x90, 0x90, 0x82, 0x00, 0xF0,
+ 0x90, 0x90, 0x83, 0x00, 0xF0, 0x90, 0x90, 0x84, 0x00, 0xF0, 0x90, 0x90,
+ 0x85, 0x00, 0xF0, 0x90, 0x90, 0x86, 0x00, 0xF0, 0x90, 0x90, 0x87, 0x00,
+ 0xF0, 0x90, 0x90, 0x88, 0x00, 0xF0, 0x90, 0x90, 0x89, 0x00, 0xF0, 0x90,
+ 0x90, 0x8A, 0x00, 0xF0, 0x90, 0x90, 0x8B, 0x00, 0xF0, 0x90, 0x90, 0x8C,
+ 0x00, 0xF0, 0x90, 0x90, 0x8D, 0x00, 0xF0, 0x90, 0x90, 0x8E, 0x00, 0xF0,
+ 0x90, 0x90, 0x8F, 0x00, 0xF0, 0x90, 0x90, 0x90, 0x00, 0xF0, 0x90, 0x90,
+ 0x91, 0x00, 0xF0, 0x90, 0x90, 0x92, 0x00, 0xF0, 0x90, 0x90, 0x93, 0x00,
+ 0xF0, 0x90, 0x90, 0x94, 0x00, 0xF0, 0x90, 0x90, 0x95, 0x00, 0xF0, 0x90,
+ 0x90, 0x96, 0x00, 0xF0, 0x90, 0x90, 0x97, 0x00, 0xF0, 0x90, 0x90, 0x98,
+ 0x00, 0xF0, 0x90, 0x90, 0x99, 0x00, 0xF0, 0x90, 0x90, 0x9A, 0x00, 0xF0,
+ 0x90, 0x90, 0x9B, 0x00, 0xF0, 0x90, 0x90, 0x9C, 0x00, 0xF0, 0x90, 0x90,
+ 0x9D, 0x00, 0xF0, 0x90, 0x90, 0x9E, 0x00, 0xF0, 0x90, 0x90, 0x9F, 0x00,
+ 0xF0, 0x90, 0x90, 0xA0, 0x00, 0xF0, 0x90, 0x90, 0xA1, 0x00, 0xF0, 0x90,
+ 0x90, 0xA2, 0x00, 0xF0, 0x90, 0x90, 0xA3, 0x00, 0xF0, 0x90, 0x90, 0xA4,
+ 0x00, 0xF0, 0x90, 0x90, 0xA5, 0x00, 0xF0, 0x90, 0x90, 0xA6, 0x00, 0xF0,
+ 0x90, 0x90, 0xA7, 0x00, 0xF0, 0x90, 0x92, 0xB0, 0x00, 0xF0, 0x90, 0x92,
+ 0xB1, 0x00, 0xF0, 0x90, 0x92, 0xB2, 0x00, 0xF0, 0x90, 0x92, 0xB3, 0x00,
+ 0xF0, 0x90, 0x92, 0xB4, 0x00, 0xF0, 0x90, 0x92, 0xB5, 0x00, 0xF0, 0x90,
+ 0x92, 0xB6, 0x00, 0xF0, 0x90, 0x92, 0xB7, 0x00, 0xF0, 0x90, 0x92, 0xB8,
+ 0x00, 0xF0, 0x90, 0x92, 0xB9, 0x00, 0xF0, 0x90, 0x92, 0xBA, 0x00, 0xF0,
+ 0x90, 0x92, 0xBB, 0x00, 0xF0, 0x90, 0x92, 0xBC, 0x00, 0xF0, 0x90, 0x92,
+ 0xBD, 0x00, 0xF0, 0x90, 0x92, 0xBE, 0x00, 0xF0, 0x90, 0x92, 0xBF, 0x00,
+ 0xF0, 0x90, 0x93, 0x80, 0x00, 0xF0, 0x90, 0x93, 0x81, 0x00, 0xF0, 0x90,
+ 0x93, 0x82, 0x00, 0xF0, 0x90, 0x93, 0x83, 0x00, 0xF0, 0x90, 0x93, 0x84,
+ 0x00, 0xF0, 0x90, 0x93, 0x85, 0x00, 0xF0, 0x90, 0x93, 0x86, 0x00, 0xF0,
+ 0x90, 0x93, 0x87, 0x00, 0xF0, 0x90, 0x93, 0x88, 0x00, 0xF0, 0x90, 0x93,
+ 0x89, 0x00, 0xF0, 0x90, 0x93, 0x8A, 0x00, 0xF0, 0x90, 0x93, 0x8B, 0x00,
+ 0xF0, 0x90, 0x93, 0x8C, 0x00, 0xF0, 0x90, 0x93, 0x8D, 0x00, 0xF0, 0x90,
+ 0x93, 0x8E, 0x00, 0xF0, 0x90, 0x93, 0x8F, 0x00, 0xF0, 0x90, 0x93, 0x90,
+ 0x00, 0xF0, 0x90, 0x93, 0x91, 0x00, 0xF0, 0x90, 0x93, 0x92, 0x00, 0xF0,
+ 0x90, 0x93, 0x93, 0x00, 0xF0, 0x90, 0xB2, 0x80, 0x00, 0xF0, 0x90, 0xB2,
+ 0x81, 0x00, 0xF0, 0x90, 0xB2, 0x82, 0x00, 0xF0, 0x90, 0xB2, 0x83, 0x00,
+ 0xF0, 0x90, 0xB2, 0x84, 0x00, 0xF0, 0x90, 0xB2, 0x85, 0x00, 0xF0, 0x90,
+ 0xB2, 0x86, 0x00, 0xF0, 0x90, 0xB2, 0x87, 0x00, 0xF0, 0x90, 0xB2, 0x88,
+ 0x00, 0xF0, 0x90, 0xB2, 0x89, 0x00, 0xF0, 0x90, 0xB2, 0x8A, 0x00, 0xF0,
+ 0x90, 0xB2, 0x8B, 0x00, 0xF0, 0x90, 0xB2, 0x8C, 0x00, 0xF0, 0x90, 0xB2,
+ 0x8D, 0x00, 0xF0, 0x90, 0xB2, 0x8E, 0x00, 0xF0, 0x90, 0xB2, 0x8F, 0x00,
+ 0xF0, 0x90, 0xB2, 0x90, 0x00, 0xF0, 0x90, 0xB2, 0x91, 0x00, 0xF0, 0x90,
+ 0xB2, 0x92, 0x00, 0xF0, 0x90, 0xB2, 0x93, 0x00, 0xF0, 0x90, 0xB2, 0x94,
+ 0x00, 0xF0, 0x90, 0xB2, 0x95, 0x00, 0xF0, 0x90, 0xB2, 0x96, 0x00, 0xF0,
+ 0x90, 0xB2, 0x97, 0x00, 0xF0, 0x90, 0xB2, 0x98, 0x00, 0xF0, 0x90, 0xB2,
+ 0x99, 0x00, 0xF0, 0x90, 0xB2, 0x9A, 0x00, 0xF0, 0x90, 0xB2, 0x9B, 0x00,
+ 0xF0, 0x90, 0xB2, 0x9C, 0x00, 0xF0, 0x90, 0xB2, 0x9D, 0x00, 0xF0, 0x90,
+ 0xB2, 0x9E, 0x00, 0xF0, 0x90, 0xB2, 0x9F, 0x00, 0xF0, 0x90, 0xB2, 0xA0,
+ 0x00, 0xF0, 0x90, 0xB2, 0xA1, 0x00, 0xF0, 0x90, 0xB2, 0xA2, 0x00, 0xF0,
+ 0x90, 0xB2, 0xA3, 0x00, 0xF0, 0x90, 0xB2, 0xA4, 0x00, 0xF0, 0x90, 0xB2,
+ 0xA5, 0x00, 0xF0, 0x90, 0xB2, 0xA6, 0x00, 0xF0, 0x90, 0xB2, 0xA7, 0x00,
+ 0xF0, 0x90, 0xB2, 0xA8, 0x00, 0xF0, 0x90, 0xB2, 0xA9, 0x00, 0xF0, 0x90,
+ 0xB2, 0xAA, 0x00, 0xF0, 0x90, 0xB2, 0xAB, 0x00, 0xF0, 0x90, 0xB2, 0xAC,
+ 0x00, 0xF0, 0x90, 0xB2, 0xAD, 0x00, 0xF0, 0x90, 0xB2, 0xAE, 0x00, 0xF0,
+ 0x90, 0xB2, 0xAF, 0x00, 0xF0, 0x90, 0xB2, 0xB0, 0x00, 0xF0, 0x90, 0xB2,
+ 0xB1, 0x00, 0xF0, 0x90, 0xB2, 0xB2, 0x00, 0xF0, 0x91, 0xA2, 0xA0, 0x00,
+ 0xF0, 0x91, 0xA2, 0xA1, 0x00, 0xF0, 0x91, 0xA2, 0xA2, 0x00, 0xF0, 0x91,
+ 0xA2, 0xA3, 0x00, 0xF0, 0x91, 0xA2, 0xA4, 0x00, 0xF0, 0x91, 0xA2, 0xA5,
+ 0x00, 0xF0, 0x91, 0xA2, 0xA6, 0x00, 0xF0, 0x91, 0xA2, 0xA7, 0x00, 0xF0,
+ 0x91, 0xA2, 0xA8, 0x00, 0xF0, 0x91, 0xA2, 0xA9, 0x00, 0xF0, 0x91, 0xA2,
+ 0xAA, 0x00, 0xF0, 0x91, 0xA2, 0xAB, 0x00, 0xF0, 0x91, 0xA2, 0xAC, 0x00,
+ 0xF0, 0x91, 0xA2, 0xAD, 0x00, 0xF0, 0x91, 0xA2, 0xAE, 0x00, 0xF0, 0x91,
+ 0xA2, 0xAF, 0x00, 0xF0, 0x91, 0xA2, 0xB0, 0x00, 0xF0, 0x91, 0xA2, 0xB1,
+ 0x00, 0xF0, 0x91, 0xA2, 0xB2, 0x00, 0xF0, 0x91, 0xA2, 0xB3, 0x00, 0xF0,
+ 0x91, 0xA2, 0xB4, 0x00, 0xF0, 0x91, 0xA2, 0xB5, 0x00, 0xF0, 0x91, 0xA2,
+ 0xB6, 0x00, 0xF0, 0x91, 0xA2, 0xB7, 0x00, 0xF0, 0x91, 0xA2, 0xB8, 0x00,
+ 0xF0, 0x91, 0xA2, 0xB9, 0x00, 0xF0, 0x91, 0xA2, 0xBA, 0x00, 0xF0, 0x91,
+ 0xA2, 0xBB, 0x00, 0xF0, 0x91, 0xA2, 0xBC, 0x00, 0xF0, 0x91, 0xA2, 0xBD,
+ 0x00, 0xF0, 0x91, 0xA2, 0xBE, 0x00, 0xF0, 0x91, 0xA2, 0xBF, 0x00, 0xE1,
+ 0x8F, 0xB0, 0x00, 0xE1, 0x8F, 0xB1, 0x00, 0xE1, 0x8F, 0xB2, 0x00, 0xE1,
+ 0x8F, 0xB3, 0x00, 0xE1, 0x8F, 0xB4, 0x00, 0xE1, 0x8F, 0xB5, 0x00, 0xD0,
+ 0x92, 0x00, 0xD0, 0x94, 0x00, 0xD0, 0x9E, 0x00, 0xD0, 0xA1, 0x00, 0xD0,
+ 0xA2, 0x00, 0xD0, 0xA2, 0x00, 0xD0, 0xAA, 0x00, 0xD1, 0xA2, 0x00, 0xEA,
+ 0x99, 0x8A, 0x00, 0xEA, 0x9D, 0xBD, 0x00, 0xE2, 0xB1, 0xA3, 0x00, 0xE1,
+ 0xB8, 0x80, 0x00, 0xE1, 0xB8, 0x82, 0x00, 0xE1, 0xB8, 0x84, 0x00, 0xE1,
+ 0xB8, 0x86, 0x00, 0xE1, 0xB8, 0x88, 0x00, 0xE1, 0xB8, 0x8A, 0x00, 0xE1,
+ 0xB8, 0x8C, 0x00, 0xE1, 0xB8, 0x8E, 0x00, 0xE1, 0xB8, 0x90, 0x00, 0xE1,
+ 0xB8, 0x92, 0x00, 0xE1, 0xB8, 0x94, 0x00, 0xE1, 0xB8, 0x96, 0x00, 0xE1,
+ 0xB8, 0x98, 0x00, 0xE1, 0xB8, 0x9A, 0x00, 0xE1, 0xB8, 0x9C, 0x00, 0xE1,
+ 0xB8, 0x9E, 0x00, 0xE1, 0xB8, 0xA0, 0x00, 0xE1, 0xB8, 0xA2, 0x00, 0xE1,
+ 0xB8, 0xA4, 0x00, 0xE1, 0xB8, 0xA6, 0x00, 0xE1, 0xB8, 0xA8, 0x00, 0xE1,
+ 0xB8, 0xAA, 0x00, 0xE1, 0xB8, 0xAC, 0x00, 0xE1, 0xB8, 0xAE, 0x00, 0xE1,
+ 0xB8, 0xB0, 0x00, 0xE1, 0xB8, 0xB2, 0x00, 0xE1, 0xB8, 0xB4, 0x00, 0xE1,
+ 0xB8, 0xB6, 0x00, 0xE1, 0xB8, 0xB8, 0x00, 0xE1, 0xB8, 0xBA, 0x00, 0xE1,
+ 0xB8, 0xBC, 0x00, 0xE1, 0xB8, 0xBE, 0x00, 0xE1, 0xB9, 0x80, 0x00, 0xE1,
+ 0xB9, 0x82, 0x00, 0xE1, 0xB9, 0x84, 0x00, 0xE1, 0xB9, 0x86, 0x00, 0xE1,
+ 0xB9, 0x88, 0x00, 0xE1, 0xB9, 0x8A, 0x00, 0xE1, 0xB9, 0x8C, 0x00, 0xE1,
+ 0xB9, 0x8E, 0x00, 0xE1, 0xB9, 0x90, 0x00, 0xE1, 0xB9, 0x92, 0x00, 0xE1,
+ 0xB9, 0x94, 0x00, 0xE1, 0xB9, 0x96, 0x00, 0xE1, 0xB9, 0x98, 0x00, 0xE1,
+ 0xB9, 0x9A, 0x00, 0xE1, 0xB9, 0x9C, 0x00, 0xE1, 0xB9, 0x9E, 0x00, 0xE1,
+ 0xB9, 0xA0, 0x00, 0xE1, 0xB9, 0xA2, 0x00, 0xE1, 0xB9, 0xA4, 0x00, 0xE1,
+ 0xB9, 0xA6, 0x00, 0xE1, 0xB9, 0xA8, 0x00, 0xE1, 0xB9, 0xAA, 0x00, 0xE1,
+ 0xB9, 0xAC, 0x00, 0xE1, 0xB9, 0xAE, 0x00, 0xE1, 0xB9, 0xB0, 0x00, 0xE1,
+ 0xB9, 0xB2, 0x00, 0xE1, 0xB9, 0xB4, 0x00, 0xE1, 0xB9, 0xB6, 0x00, 0xE1,
+ 0xB9, 0xB8, 0x00, 0xE1, 0xB9, 0xBA, 0x00, 0xE1, 0xB9, 0xBC, 0x00, 0xE1,
+ 0xB9, 0xBE, 0x00, 0xE1, 0xBA, 0x80, 0x00, 0xE1, 0xBA, 0x82, 0x00, 0xE1,
+ 0xBA, 0x84, 0x00, 0xE1, 0xBA, 0x86, 0x00, 0xE1, 0xBA, 0x88, 0x00, 0xE1,
+ 0xBA, 0x8A, 0x00, 0xE1, 0xBA, 0x8C, 0x00, 0xE1, 0xBA, 0x8E, 0x00, 0xE1,
+ 0xBA, 0x90, 0x00, 0xF0, 0x9E, 0xA4, 0x80, 0x00, 0xF0, 0x9E, 0xA4, 0x81,
+ 0x00, 0xF0, 0x9E, 0xA4, 0x82, 0x00, 0xF0, 0x9E, 0xA4, 0x83, 0x00, 0xF0,
+ 0x9E, 0xA4, 0x84, 0x00, 0xF0, 0x9E, 0xA4, 0x85, 0x00, 0xF0, 0x9E, 0xA4,
+ 0x86, 0x00, 0xF0, 0x9E, 0xA4, 0x87, 0x00, 0xF0, 0x9E, 0xA4, 0x88, 0x00,
+ 0xF0, 0x9E, 0xA4, 0x89, 0x00, 0xF0, 0x9E, 0xA4, 0x8A, 0x00, 0xF0, 0x9E,
+ 0xA4, 0x8B, 0x00, 0xF0, 0x9E, 0xA4, 0x8C, 0x00, 0xF0, 0x9E, 0xA4, 0x8D,
+ 0x00, 0xE1, 0xBA, 0x92, 0x00, 0xF0, 0x9E, 0xA4, 0x8E, 0x00, 0xF0, 0x9E,
+ 0xA4, 0x8F, 0x00, 0xF0, 0x9E, 0xA4, 0x90, 0x00, 0xF0, 0x9E, 0xA4, 0x91,
+ 0x00, 0xF0, 0x9E, 0xA4, 0x92, 0x00, 0xF0, 0x9E, 0xA4, 0x93, 0x00, 0xF0,
+ 0x9E, 0xA4, 0x94, 0x00, 0xF0, 0x9E, 0xA4, 0x95, 0x00, 0xF0, 0x9E, 0xA4,
+ 0x96, 0x00, 0xF0, 0x9E, 0xA4, 0x97, 0x00, 0xF0, 0x9E, 0xA4, 0x98, 0x00,
+ 0xF0, 0x9E, 0xA4, 0x99, 0x00, 0xF0, 0x9E, 0xA4, 0x9A, 0x00, 0xF0, 0x9E,
+ 0xA4, 0x9B, 0x00, 0xF0, 0x9E, 0xA4, 0x9C, 0x00, 0xF0, 0x9E, 0xA4, 0x9D,
+ 0x00, 0xF0, 0x9E, 0xA4, 0x9E, 0x00, 0xF0, 0x9E, 0xA4, 0x9F, 0x00, 0xF0,
+ 0x9E, 0xA4, 0xA0, 0x00, 0xF0, 0x9E, 0xA4, 0xA1, 0x00, 0xE1, 0xBA, 0x94,
+ 0x00, 0xE1, 0xB9, 0xA0, 0x00, 0xE1, 0xBA, 0xA0, 0x00, 0xE1, 0xBA, 0xA2,
+ 0x00, 0xE1, 0xBA, 0xA4, 0x00, 0xE1, 0xBA, 0xA6, 0x00, 0xE1, 0xBA, 0xA8,
+ 0x00, 0xE1, 0xBA, 0xAA, 0x00, 0xE1, 0xBA, 0xAC, 0x00, 0xE1, 0xBA, 0xAE,
+ 0x00, 0xE1, 0xBA, 0xB0, 0x00, 0xE1, 0xBA, 0xB2, 0x00, 0xE1, 0xBA, 0xB4,
+ 0x00, 0xE1, 0xBA, 0xB6, 0x00, 0xE1, 0xBA, 0xB8, 0x00, 0xE1, 0xBA, 0xBA,
+ 0x00, 0xE1, 0xBA, 0xBC, 0x00, 0xE1, 0xBA, 0xBE, 0x00, 0xE1, 0xBB, 0x80,
+ 0x00, 0xE1, 0xBB, 0x82, 0x00, 0xE1, 0xBB, 0x84, 0x00, 0xE1, 0xBB, 0x86,
+ 0x00, 0xE1, 0xBB, 0x88, 0x00, 0xE1, 0xBB, 0x8A, 0x00, 0xE1, 0xBB, 0x8C,
+ 0x00, 0xE1, 0xBB, 0x8E, 0x00, 0xE1, 0xBB, 0x90, 0x00, 0xE1, 0xBB, 0x92,
+ 0x00, 0xE1, 0xBB, 0x94, 0x00, 0xE1, 0xBB, 0x96, 0x00, 0xE1, 0xBB, 0x98,
+ 0x00, 0xE1, 0xBB, 0x9A, 0x00, 0xE1, 0xBB, 0x9C, 0x00, 0xE1, 0xBB, 0x9E,
+ 0x00, 0xE1, 0xBB, 0xA0, 0x00, 0xE1, 0xBB, 0xA2, 0x00, 0xE1, 0xBB, 0xA4,
+ 0x00, 0xE1, 0xBB, 0xA6, 0x00, 0xE1, 0xBB, 0xA8, 0x00, 0xE1, 0xBB, 0xAA,
+ 0x00, 0xE1, 0xBB, 0xAC, 0x00, 0xE1, 0xBB, 0xAE, 0x00, 0xE1, 0xBB, 0xB0,
+ 0x00, 0xE1, 0xBB, 0xB2, 0x00, 0xE1, 0xBB, 0xB4, 0x00, 0xE1, 0xBB, 0xB6,
+ 0x00, 0xE1, 0xBB, 0xB8, 0x00, 0xE1, 0xBB, 0xBA, 0x00, 0xE1, 0xBB, 0xBC,
+ 0x00, 0xE1, 0xBB, 0xBE, 0x00, 0xE1, 0xBC, 0x88, 0x00, 0xE1, 0xBC, 0x89,
+ 0x00, 0xE1, 0xBC, 0x8A, 0x00, 0xE1, 0xBC, 0x8B, 0x00, 0xE1, 0xBC, 0x8C,
+ 0x00, 0xE1, 0xBC, 0x8D, 0x00, 0xE1, 0xBC, 0x8E, 0x00, 0xE1, 0xBC, 0x8F,
+ 0x00, 0xE1, 0xBC, 0x98, 0x00, 0xE1, 0xBC, 0x99, 0x00, 0xE1, 0xBC, 0x9A,
+ 0x00, 0xE1, 0xBC, 0x9B, 0x00, 0xE1, 0xBC, 0x9C, 0x00, 0xE1, 0xBC, 0x9D,
+ 0x00, 0xE1, 0xBC, 0xA8, 0x00, 0xE1, 0xBC, 0xA9, 0x00, 0xE1, 0xBC, 0xAA,
+ 0x00, 0xE1, 0xBC, 0xAB, 0x00, 0xE1, 0xBC, 0xAC, 0x00, 0xE1, 0xBC, 0xAD,
+ 0x00, 0xE1, 0xBC, 0xAE, 0x00, 0xE1, 0xBC, 0xAF, 0x00, 0xE1, 0xBC, 0xB8,
+ 0x00, 0xE1, 0xBC, 0xB9, 0x00, 0xE1, 0xBC, 0xBA, 0x00, 0xE1, 0xBC, 0xBB,
+ 0x00, 0xE1, 0xBC, 0xBC, 0x00, 0xE1, 0xBC, 0xBD, 0x00, 0xE1, 0xBC, 0xBE,
+ 0x00, 0xE1, 0xBC, 0xBF, 0x00, 0xE1, 0xBD, 0x88, 0x00, 0xE1, 0xBD, 0x89,
+ 0x00, 0xE1, 0xBD, 0x8A, 0x00, 0xE1, 0xBD, 0x8B, 0x00, 0xE1, 0xBD, 0x8C,
+ 0x00, 0xE1, 0xBD, 0x8D, 0x00, 0xE1, 0xBD, 0x99, 0x00, 0xE1, 0xBD, 0x9B,
+ 0x00, 0xE1, 0xBD, 0x9D, 0x00, 0xE1, 0xBD, 0x9F, 0x00, 0xE1, 0xBD, 0xA8,
+ 0x00, 0xE1, 0xBD, 0xA9, 0x00, 0xE1, 0xBD, 0xAA, 0x00, 0xE1, 0xBD, 0xAB,
+ 0x00, 0xE1, 0xBD, 0xAC, 0x00, 0xE1, 0xBD, 0xAD, 0x00, 0xE1, 0xBD, 0xAE,
+ 0x00, 0xE1, 0xBD, 0xAF, 0x00, 0xE1, 0xBE, 0xBA, 0x00, 0xE1, 0xBE, 0xBB,
+ 0x00, 0xE1, 0xBF, 0x88, 0x00, 0xE1, 0xBF, 0x89, 0x00, 0xE1, 0xBF, 0x8A,
+ 0x00, 0xE1, 0xBF, 0x8B, 0x00, 0xE1, 0xBF, 0x9A, 0x00, 0xE1, 0xBF, 0x9B,
+ 0x00, 0xE1, 0xBF, 0xB8, 0x00, 0xE1, 0xBF, 0xB9, 0x00, 0xE1, 0xBF, 0xAA,
+ 0x00, 0xE1, 0xBF, 0xAB, 0x00, 0xE1, 0xBF, 0xBA, 0x00, 0xE1, 0xBF, 0xBB,
+ 0x00, 0xE1, 0xBE, 0x88, 0x00, 0xE1, 0xBE, 0x89, 0x00, 0xE1, 0xBE, 0x8A,
+ 0x00, 0xE1, 0xBE, 0x8B, 0x00, 0xE1, 0xBE, 0x8C, 0x00, 0xE1, 0xBE, 0x8D,
+ 0x00, 0xE1, 0xBE, 0x8E, 0x00, 0xE1, 0xBE, 0x8F, 0x00, 0xE1, 0xBE, 0x98,
+ 0x00, 0xE1, 0xBE, 0x99, 0x00, 0xE1, 0xBE, 0x9A, 0x00, 0xE1, 0xBE, 0x9B,
+ 0x00, 0xE1, 0xBE, 0x9C, 0x00, 0xE1, 0xBE, 0x9D, 0x00, 0xE1, 0xBE, 0x9E,
+ 0x00, 0xE1, 0xBE, 0x9F, 0x00, 0xE1, 0xBE, 0xA8, 0x00, 0xE1, 0xBE, 0xA9,
+ 0x00, 0xE1, 0xBE, 0xAA, 0x00, 0xE1, 0xBE, 0xAB, 0x00, 0xE1, 0xBE, 0xAC,
+ 0x00, 0xE1, 0xBE, 0xAD, 0x00, 0xE1, 0xBE, 0xAE, 0x00, 0xE1, 0xBE, 0xAF,
+ 0x00, 0xE1, 0xBE, 0xB8, 0x00, 0xE1, 0xBE, 0xB9, 0x00, 0xE1, 0xBE, 0xBC,
+ 0x00, 0xCE, 0x99, 0x00, 0xE1, 0xBF, 0x8C, 0x00, 0xE1, 0xBF, 0x98, 0x00,
+ 0xE1, 0xBF, 0x99, 0x00, 0xE1, 0xBF, 0xA8, 0x00, 0xE1, 0xBF, 0xA9, 0x00,
+ 0xE1, 0xBF, 0xAC, 0x00, 0xE1, 0xBF, 0xBC, 0x00, 0xE2, 0x84, 0xB2, 0x00,
+ 0xE2, 0x85, 0xA0, 0x00, 0xE2, 0x85, 0xA1, 0x00, 0xE2, 0x85, 0xA2, 0x00,
+ 0xE2, 0x85, 0xA3, 0x00, 0xE2, 0x85, 0xA4, 0x00, 0xE2, 0x85, 0xA5, 0x00,
+ 0xE2, 0x85, 0xA6, 0x00, 0xE2, 0x85, 0xA7, 0x00, 0xE2, 0x85, 0xA8, 0x00,
+ 0xE2, 0x85, 0xA9, 0x00, 0xE2, 0x85, 0xAA, 0x00, 0xE2, 0x85, 0xAB, 0x00,
+ 0xE2, 0x85, 0xAC, 0x00, 0xE2, 0x85, 0xAD, 0x00, 0xE2, 0x85, 0xAE, 0x00,
+ 0xE2, 0x85, 0xAF, 0x00, 0xE2, 0x86, 0x83, 0x00, 0xE2, 0x92, 0xB6, 0x00,
+ 0xE2, 0x92, 0xB7, 0x00, 0xE2, 0x92, 0xB8, 0x00, 0xE2, 0x92, 0xB9, 0x00,
+ 0xE2, 0x92, 0xBA, 0x00, 0xE2, 0x92, 0xBB, 0x00, 0xE2, 0x92, 0xBC, 0x00,
+ 0xE2, 0x92, 0xBD, 0x00, 0xE2, 0x92, 0xBE, 0x00, 0xE2, 0x92, 0xBF, 0x00,
+ 0xE2, 0x93, 0x80, 0x00, 0xE2, 0x93, 0x81, 0x00, 0xE2, 0x93, 0x82, 0x00,
+ 0xE2, 0x93, 0x83, 0x00, 0xE2, 0x93, 0x84, 0x00, 0xE2, 0x93, 0x85, 0x00,
+ 0xE2, 0x93, 0x86, 0x00, 0xE2, 0x93, 0x87, 0x00, 0xE2, 0x93, 0x88, 0x00,
+ 0xE2, 0x93, 0x89, 0x00, 0xE2, 0x93, 0x8A, 0x00, 0xE2, 0x93, 0x8B, 0x00,
+ 0xE2, 0x93, 0x8C, 0x00, 0xE2, 0x93, 0x8D, 0x00, 0xE2, 0x93, 0x8E, 0x00,
+ 0xE2, 0x93, 0x8F, 0x00, 0xE2, 0xB0, 0x80, 0x00, 0xE2, 0xB0, 0x81, 0x00,
+ 0xE2, 0xB0, 0x82, 0x00, 0xE2, 0xB0, 0x83, 0x00, 0xE2, 0xB0, 0x84, 0x00,
+ 0xE2, 0xB0, 0x85, 0x00, 0xE2, 0xB0, 0x86, 0x00, 0xE2, 0xB0, 0x87, 0x00,
+ 0xE2, 0xB0, 0x88, 0x00, 0xE2, 0xB0, 0x89, 0x00, 0xE2, 0xB0, 0x8A, 0x00,
+ 0xE2, 0xB0, 0x8B, 0x00, 0xE2, 0xB0, 0x8C, 0x00, 0xE2, 0xB0, 0x8D, 0x00,
+ 0xE2, 0xB0, 0x8E, 0x00, 0xE2, 0xB0, 0x8F, 0x00, 0xE2, 0xB0, 0x90, 0x00,
+ 0xE2, 0xB0, 0x91, 0x00, 0xE2, 0xB0, 0x92, 0x00, 0xE2, 0xB0, 0x93, 0x00,
+ 0xE2, 0xB0, 0x94, 0x00, 0xE2, 0xB0, 0x95, 0x00, 0xE2, 0xB0, 0x96, 0x00,
+ 0xE2, 0xB0, 0x97, 0x00, 0xE2, 0xB0, 0x98, 0x00, 0xE2, 0xB0, 0x99, 0x00,
+ 0xE2, 0xB0, 0x9A, 0x00, 0xE2, 0xB0, 0x9B, 0x00, 0xE2, 0xB0, 0x9C, 0x00,
+ 0xE2, 0xB0, 0x9D, 0x00, 0xE2, 0xB0, 0x9E, 0x00, 0xE2, 0xB0, 0x9F, 0x00,
+ 0xE2, 0xB0, 0xA0, 0x00, 0xE2, 0xB0, 0xA1, 0x00, 0xE2, 0xB0, 0xA2, 0x00,
+ 0xE2, 0xB0, 0xA3, 0x00, 0xE2, 0xB0, 0xA4, 0x00, 0xE2, 0xB0, 0xA5, 0x00,
+ 0xE2, 0xB0, 0xA6, 0x00, 0xE2, 0xB0, 0xA7, 0x00, 0xE2, 0xB0, 0xA8, 0x00,
+ 0xE2, 0xB0, 0xA9, 0x00, 0xE2, 0xB0, 0xAA, 0x00, 0xE2, 0xB0, 0xAB, 0x00,
+ 0xE2, 0xB0, 0xAC, 0x00, 0xE2, 0xB0, 0xAD, 0x00, 0xE2, 0xB0, 0xAE, 0x00,
+ 0xE2, 0xB1, 0xA0, 0x00, 0xC8, 0xBA, 0x00, 0xC8, 0xBE, 0x00, 0xE2, 0xB1,
+ 0xA7, 0x00, 0xE2, 0xB1, 0xA9, 0x00, 0xE2, 0xB1, 0xAB, 0x00, 0xE2, 0xB1,
+ 0xB2, 0x00, 0xE2, 0xB1, 0xB5, 0x00, 0xE2, 0xB2, 0x80, 0x00, 0xE2, 0xB2,
+ 0x82, 0x00, 0xE2, 0xB2, 0x84, 0x00, 0xE2, 0xB2, 0x86, 0x00, 0xE2, 0xB2,
+ 0x88, 0x00, 0xE2, 0xB2, 0x8A, 0x00, 0xE2, 0xB2, 0x8C, 0x00, 0xE2, 0xB2,
+ 0x8E, 0x00, 0xE2, 0xB2, 0x90, 0x00, 0xE2, 0xB2, 0x92, 0x00, 0xE2, 0xB2,
+ 0x94, 0x00, 0xE2, 0xB2, 0x96, 0x00, 0xE2, 0xB2, 0x98, 0x00, 0xE2, 0xB2,
+ 0x9A, 0x00, 0xE2, 0xB2, 0x9C, 0x00, 0xE2, 0xB2, 0x9E, 0x00, 0xE2, 0xB2,
+ 0xA0, 0x00, 0xE2, 0xB2, 0xA2, 0x00, 0xE2, 0xB2, 0xA4, 0x00, 0xE2, 0xB2,
+ 0xA6, 0x00, 0xE2, 0xB2, 0xA8, 0x00, 0xE2, 0xB2, 0xAA, 0x00, 0xE2, 0xB2,
+ 0xAC, 0x00, 0xE2, 0xB2, 0xAE, 0x00, 0xE2, 0xB2, 0xB0, 0x00, 0xE2, 0xB2,
+ 0xB2, 0x00, 0xE2, 0xB2, 0xB4, 0x00, 0xE2, 0xB2, 0xB6, 0x00, 0xE2, 0xB2,
+ 0xB8, 0x00, 0xE2, 0xB2, 0xBA, 0x00, 0xE2, 0xB2, 0xBC, 0x00, 0xE2, 0xB2,
+ 0xBE, 0x00, 0xE2, 0xB3, 0x80, 0x00, 0xE2, 0xB3, 0x82, 0x00, 0xE2, 0xB3,
+ 0x84, 0x00, 0xE2, 0xB3, 0x86, 0x00, 0xE2, 0xB3, 0x88, 0x00, 0xE2, 0xB3,
+ 0x8A, 0x00, 0xE2, 0xB3, 0x8C, 0x00, 0xE2, 0xB3, 0x8E, 0x00, 0xE2, 0xB3,
+ 0x90, 0x00, 0xE2, 0xB3, 0x92, 0x00, 0xE2, 0xB3, 0x94, 0x00, 0xE2, 0xB3,
+ 0x96, 0x00, 0xE2, 0xB3, 0x98, 0x00, 0xE2, 0xB3, 0x9A, 0x00, 0xE2, 0xB3,
+ 0x9C, 0x00, 0xE2, 0xB3, 0x9E, 0x00, 0xE2, 0xB3, 0xA0, 0x00, 0xE2, 0xB3,
+ 0xA2, 0x00, 0xE2, 0xB3, 0xAB, 0x00, 0xE2, 0xB3, 0xAD, 0x00, 0xE2, 0xB3,
+ 0xB2, 0x00, 0xE1, 0x82, 0xA0, 0x00, 0xE1, 0x82, 0xA1, 0x00, 0xE1, 0x82,
+ 0xA2, 0x00, 0xE1, 0x82, 0xA3, 0x00, 0xE1, 0x82, 0xA4, 0x00, 0xE1, 0x82,
+ 0xA5, 0x00, 0xE1, 0x82, 0xA6, 0x00, 0xE1, 0x82, 0xA7, 0x00, 0xE1, 0x82,
+ 0xA8, 0x00, 0xE1, 0x82, 0xA9, 0x00, 0xE1, 0x82, 0xAA, 0x00, 0xE1, 0x82,
+ 0xAB, 0x00, 0xE1, 0x82, 0xAC, 0x00, 0xE1, 0x82, 0xAD, 0x00, 0xE1, 0x82,
+ 0xAE, 0x00, 0xE1, 0x82, 0xAF, 0x00, 0xE1, 0x82, 0xB0, 0x00, 0xE1, 0x82,
+ 0xB1, 0x00, 0xE1, 0x82, 0xB2, 0x00, 0xE1, 0x82, 0xB3, 0x00, 0xE1, 0x82,
+ 0xB4, 0x00, 0xE1, 0x82, 0xB5, 0x00, 0xE1, 0x82, 0xB6, 0x00, 0xE1, 0x82,
+ 0xB7, 0x00, 0xE1, 0x82, 0xB8, 0x00, 0xE1, 0x82, 0xB9, 0x00, 0xE1, 0x82,
+ 0xBA, 0x00, 0xE1, 0x82, 0xBB, 0x00, 0xE1, 0x82, 0xBC, 0x00, 0xE1, 0x82,
+ 0xBD, 0x00, 0xE1, 0x82, 0xBE, 0x00, 0xE1, 0x82, 0xBF, 0x00, 0xE1, 0x83,
+ 0x80, 0x00, 0xE1, 0x83, 0x81, 0x00, 0xE1, 0x83, 0x82, 0x00, 0xE1, 0x83,
+ 0x83, 0x00, 0xE1, 0x83, 0x84, 0x00, 0xE1, 0x83, 0x85, 0x00, 0xE1, 0x83,
+ 0x87, 0x00, 0xE1, 0x83, 0x8D, 0x00, 0xEA, 0x99, 0x80, 0x00, 0xEA, 0x99,
+ 0x82, 0x00, 0xEA, 0x99, 0x84, 0x00, 0xEA, 0x99, 0x86, 0x00, 0xEA, 0x99,
+ 0x88, 0x00, 0xEA, 0x99, 0x8A, 0x00, 0xEA, 0x99, 0x8C, 0x00, 0xEA, 0x99,
+ 0x8E, 0x00, 0xEA, 0x99, 0x90, 0x00, 0xEA, 0x99, 0x92, 0x00, 0xEA, 0x99,
+ 0x94, 0x00, 0xEA, 0x99, 0x96, 0x00, 0xEA, 0x99, 0x98, 0x00, 0xEA, 0x99,
+ 0x9A, 0x00, 0xEA, 0x99, 0x9C, 0x00, 0xEA, 0x99, 0x9E, 0x00, 0xEA, 0x99,
+ 0xA0, 0x00, 0xEA, 0x99, 0xA2, 0x00, 0xEA, 0x99, 0xA4, 0x00, 0xEA, 0x99,
+ 0xA6, 0x00, 0xEA, 0x99, 0xA8, 0x00, 0xEA, 0x99, 0xAA, 0x00, 0xEA, 0x99,
+ 0xAC, 0x00, 0xEA, 0x9A, 0x80, 0x00, 0xEA, 0x9A, 0x82, 0x00, 0xEA, 0x9A,
+ 0x84, 0x00, 0xEA, 0x9A, 0x86, 0x00, 0xEA, 0x9A, 0x88, 0x00, 0xEA, 0x9A,
+ 0x8A, 0x00, 0xEA, 0x9A, 0x8C, 0x00, 0xEA, 0x9A, 0x8E, 0x00, 0xEA, 0x9A,
+ 0x90, 0x00, 0xEA, 0x9A, 0x92, 0x00, 0xEA, 0x9A, 0x94, 0x00, 0xEA, 0x9A,
+ 0x96, 0x00, 0xEA, 0x9A, 0x98, 0x00, 0xEA, 0x9A, 0x9A, 0x00, 0xEA, 0x9C,
+ 0xA2, 0x00, 0xEA, 0x9C, 0xA4, 0x00, 0xEA, 0x9C, 0xA6, 0x00, 0xEA, 0x9C,
+ 0xA8, 0x00, 0xEA, 0x9C, 0xAA, 0x00, 0xEA, 0x9C, 0xAC, 0x00, 0xEA, 0x9C,
+ 0xAE, 0x00, 0xEA, 0x9C, 0xB2, 0x00, 0xEA, 0x9C, 0xB4, 0x00, 0xEA, 0x9C,
+ 0xB6, 0x00, 0xEA, 0x9C, 0xB8, 0x00, 0xEA, 0x9C, 0xBA, 0x00, 0xEA, 0x9C,
+ 0xBC, 0x00, 0xEA, 0x9C, 0xBE, 0x00, 0xEA, 0x9D, 0x80, 0x00, 0xEA, 0x9D,
+ 0x82, 0x00, 0xEA, 0x9D, 0x84, 0x00, 0xEA, 0x9D, 0x86, 0x00, 0xEA, 0x9D,
+ 0x88, 0x00, 0xEA, 0x9D, 0x8A, 0x00, 0xEA, 0x9D, 0x8C, 0x00, 0xEA, 0x9D,
+ 0x8E, 0x00, 0xEA, 0x9D, 0x90, 0x00, 0xEA, 0x9D, 0x92, 0x00, 0xEA, 0x9D,
+ 0x94, 0x00, 0xEA, 0x9D, 0x96, 0x00, 0xEA, 0x9D, 0x98, 0x00, 0xEA, 0x9D,
+ 0x9A, 0x00, 0xEA, 0x9D, 0x9C, 0x00, 0xEA, 0x9D, 0x9E, 0x00, 0xEA, 0x9D,
+ 0xA0, 0x00, 0xEA, 0x9D, 0xA2, 0x00, 0xEA, 0x9D, 0xA4, 0x00, 0xEA, 0x9D,
+ 0xA6, 0x00, 0xEA, 0x9D, 0xA8, 0x00, 0xEA, 0x9D, 0xAA, 0x00, 0xEA, 0x9D,
+ 0xAC, 0x00, 0xEA, 0x9D, 0xAE, 0x00, 0xEA, 0x9D, 0xB9, 0x00, 0xEA, 0x9D,
+ 0xBB, 0x00, 0xEA, 0x9D, 0xBE, 0x00, 0xEA, 0x9E, 0x80, 0x00, 0xEA, 0x9E,
+ 0x82, 0x00, 0xEA, 0x9E, 0x84, 0x00, 0xEA, 0x9E, 0x86, 0x00, 0xEA, 0x9E,
+ 0x8B, 0x00, 0xEA, 0x9E, 0x90, 0x00, 0xEA, 0x9E, 0x92, 0x00, 0xEA, 0x9E,
+ 0x96, 0x00, 0xEA, 0x9E, 0x98, 0x00, 0xEA, 0x9E, 0x9A, 0x00, 0xEA, 0x9E,
+ 0x9C, 0x00, 0xEA, 0x9E, 0x9E, 0x00, 0xEA, 0x9E, 0xA0, 0x00, 0xEA, 0x9E,
+ 0xA2, 0x00, 0xEA, 0x9E, 0xA4, 0x00, 0xEA, 0x9E, 0xA6, 0x00, 0xEA, 0x9E,
+ 0xA8, 0x00, 0xEA, 0x9E, 0xB4, 0x00, 0xEA, 0x9E, 0xB6, 0x00, 0xEA, 0x9E,
+ 0xB3, 0x00, 0xE1, 0x8E, 0xA0, 0x00, 0xE1, 0x8E, 0xA1, 0x00, 0xE1, 0x8E,
+ 0xA2, 0x00, 0xE1, 0x8E, 0xA3, 0x00, 0xE1, 0x8E, 0xA4, 0x00, 0xE1, 0x8E,
+ 0xA5, 0x00, 0xE1, 0x8E, 0xA6, 0x00, 0xE1, 0x8E, 0xA7, 0x00, 0xE1, 0x8E,
+ 0xA8, 0x00, 0xE1, 0x8E, 0xA9, 0x00, 0xE1, 0x8E, 0xAA, 0x00, 0xE1, 0x8E,
+ 0xAB, 0x00, 0xE1, 0x8E, 0xAC, 0x00, 0xE1, 0x8E, 0xAD, 0x00, 0xE1, 0x8E,
+ 0xAE, 0x00, 0xE1, 0x8E, 0xAF, 0x00, 0xE1, 0x8E, 0xB0, 0x00, 0xE1, 0x8E,
+ 0xB1, 0x00, 0xE1, 0x8E, 0xB2, 0x00, 0xE1, 0x8E, 0xB3, 0x00, 0xE1, 0x8E,
+ 0xB4, 0x00, 0xE1, 0x8E, 0xB5, 0x00, 0xE1, 0x8E, 0xB6, 0x00, 0xE1, 0x8E,
+ 0xB7, 0x00, 0xE1, 0x8E, 0xB8, 0x00, 0xE1, 0x8E, 0xB9, 0x00, 0xE1, 0x8E,
+ 0xBA, 0x00, 0xE1, 0x8E, 0xBB, 0x00, 0xE1, 0x8E, 0xBC, 0x00, 0xE1, 0x8E,
+ 0xBD, 0x00, 0xE1, 0x8E, 0xBE, 0x00, 0xE1, 0x8E, 0xBF, 0x00, 0xE1, 0x8F,
+ 0x80, 0x00, 0xE1, 0x8F, 0x81, 0x00, 0xE1, 0x8F, 0x82, 0x00, 0xE1, 0x8F,
+ 0x83, 0x00, 0xE1, 0x8F, 0x84, 0x00, 0xE1, 0x8F, 0x85, 0x00, 0xE1, 0x8F,
+ 0x86, 0x00, 0xE1, 0x8F, 0x87, 0x00, 0xE1, 0x8F, 0x88, 0x00, 0xE1, 0x8F,
+ 0x89, 0x00, 0xE1, 0x8F, 0x8A, 0x00, 0xE1, 0x8F, 0x8B, 0x00, 0xE1, 0x8F,
+ 0x8C, 0x00, 0xE1, 0x8F, 0x8D, 0x00, 0xE1, 0x8F, 0x8E, 0x00, 0xE1, 0x8F,
+ 0x8F, 0x00, 0xE1, 0x8F, 0x90, 0x00, 0xE1, 0x8F, 0x91, 0x00, 0xE1, 0x8F,
+ 0x92, 0x00, 0xE1, 0x8F, 0x93, 0x00, 0xE1, 0x8F, 0x94, 0x00, 0xE1, 0x8F,
+ 0x95, 0x00, 0xE1, 0x8F, 0x96, 0x00, 0xE1, 0x8F, 0x97, 0x00, 0xE1, 0x8F,
+ 0x98, 0x00, 0xE1, 0x8F, 0x99, 0x00, 0xE1, 0x8F, 0x9A, 0x00, 0xE1, 0x8F,
+ 0x9B, 0x00, 0xE1, 0x8F, 0x9C, 0x00, 0xE1, 0x8F, 0x9D, 0x00, 0xE1, 0x8F,
+ 0x9E, 0x00, 0xE1, 0x8F, 0x9F, 0x00, 0xE1, 0x8F, 0xA0, 0x00, 0xE1, 0x8F,
+ 0xA1, 0x00, 0xE1, 0x8F, 0xA2, 0x00, 0xE1, 0x8F, 0xA3, 0x00, 0xE1, 0x8F,
+ 0xA4, 0x00, 0xE1, 0x8F, 0xA5, 0x00, 0xE1, 0x8F, 0xA6, 0x00, 0xE1, 0x8F,
+ 0xA7, 0x00, 0xE1, 0x8F, 0xA8, 0x00, 0xE1, 0x8F, 0xA9, 0x00, 0xE1, 0x8F,
+ 0xAA, 0x00, 0xE1, 0x8F, 0xAB, 0x00, 0xE1, 0x8F, 0xAC, 0x00, 0xE1, 0x8F,
+ 0xAD, 0x00, 0xE1, 0x8F, 0xAE, 0x00, 0xE1, 0x8F, 0xAF, 0x00, 0xEF, 0xBC,
+ 0xA1, 0x00, 0xEF, 0xBC, 0xA2, 0x00, 0xEF, 0xBC, 0xA3, 0x00, 0xEF, 0xBC,
+ 0xA4, 0x00, 0xEF, 0xBC, 0xA5, 0x00, 0xEF, 0xBC, 0xA6, 0x00, 0xEF, 0xBC,
+ 0xA7, 0x00, 0xEF, 0xBC, 0xA8, 0x00, 0xEF, 0xBC, 0xA9, 0x00, 0xEF, 0xBC,
+ 0xAA, 0x00, 0xEF, 0xBC, 0xAB, 0x00, 0xEF, 0xBC, 0xAC, 0x00, 0xEF, 0xBC,
+ 0xAD, 0x00, 0xEF, 0xBC, 0xAE, 0x00, 0xEF, 0xBC, 0xAF, 0x00, 0xEF, 0xBC,
+ 0xB0, 0x00, 0xEF, 0xBC, 0xB1, 0x00, 0xEF, 0xBC, 0xB2, 0x00, 0xEF, 0xBC,
+ 0xB3, 0x00, 0xEF, 0xBC, 0xB4, 0x00, 0xEF, 0xBC, 0xB5, 0x00, 0xEF, 0xBC,
+ 0xB6, 0x00, 0xEF, 0xBC, 0xB7, 0x00, 0xEF, 0xBC, 0xB8, 0x00, 0xEF, 0xBC,
+ 0xB9, 0x00, 0xEF, 0xBC, 0xBA, 0x00, 0x53, 0x53, 0x00, 0xCA, 0xBC, 0x4E,
+ 0x00, 0x4A, 0xCC, 0x8C, 0x00, 0xCE, 0x99, 0xCC, 0x88, 0xCC, 0x81, 0x00,
+ 0xCE, 0xA5, 0xCC, 0x88, 0xCC, 0x81, 0x00, 0xD4, 0xB5, 0xD5, 0x92, 0x00,
+ 0x48, 0xCC, 0xB1, 0x00, 0x54, 0xCC, 0x88, 0x00, 0x57, 0xCC, 0x8A, 0x00,
+ 0x59, 0xCC, 0x8A, 0x00, 0x41, 0xCA, 0xBE, 0x00, 0xCE, 0xA5, 0xCC, 0x93,
+ 0x00, 0xCE, 0xA5, 0xCC, 0x93, 0xCC, 0x80, 0x00, 0xCE, 0xA5, 0xCC, 0x93,
+ 0xCC, 0x81, 0x00, 0xCE, 0xA5, 0xCC, 0x93, 0xCD, 0x82, 0x00, 0xE1, 0xBC,
+ 0x88, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x89, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x8A, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x8B, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x8C, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x8D, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x8E, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x8F, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x88, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x89, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x8A, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x8B, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x8C, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x8D, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0x8E, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0x8F, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xA8, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xA9, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xAA, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xAB, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xAC, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xAD, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xAE, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xAF, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xA8, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xA9, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xAA, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xAB, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xAC, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xAD, 0xCE, 0x99, 0x00, 0xE1, 0xBC,
+ 0xAE, 0xCE, 0x99, 0x00, 0xE1, 0xBC, 0xAF, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xA8, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xA9, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xAA, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xAB, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xAC, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xAD, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xAE, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xAF, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xA8, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xA9, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xAA, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xAB, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xAC, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xAD, 0xCE, 0x99, 0x00, 0xE1, 0xBD,
+ 0xAE, 0xCE, 0x99, 0x00, 0xE1, 0xBD, 0xAF, 0xCE, 0x99, 0x00, 0xE1, 0xBE,
+ 0xBA, 0xCE, 0x99, 0x00, 0xCE, 0x91, 0xCE, 0x99, 0x00, 0xCE, 0x86, 0xCE,
+ 0x99, 0x00, 0xCE, 0x91, 0xCD, 0x82, 0x00, 0xCE, 0x91, 0xCD, 0x82, 0xCE,
+ 0x99, 0x00, 0xCE, 0x91, 0xCE, 0x99, 0x00, 0xE1, 0xBF, 0x8A, 0xCE, 0x99,
+ 0x00, 0xCE, 0x97, 0xCE, 0x99, 0x00, 0xCE, 0x89, 0xCE, 0x99, 0x00, 0xCE,
+ 0x97, 0xCD, 0x82, 0x00, 0xCE, 0x97, 0xCD, 0x82, 0xCE, 0x99, 0x00, 0xCE,
+ 0x97, 0xCE, 0x99, 0x00, 0xCE, 0x99, 0xCC, 0x88, 0xCC, 0x80, 0x00, 0xCE,
+ 0x99, 0xCC, 0x88, 0xCC, 0x81, 0x00, 0xCE, 0x99, 0xCD, 0x82, 0x00, 0xCE,
+ 0x99, 0xCC, 0x88, 0xCD, 0x82, 0x00, 0xCE, 0xA5, 0xCC, 0x88, 0xCC, 0x80,
+ 0x00, 0xCE, 0xA5, 0xCC, 0x88, 0xCC, 0x81, 0x00, 0xCE, 0xA1, 0xCC, 0x93,
+ 0x00, 0xCE, 0xA5, 0xCD, 0x82, 0x00, 0xCE, 0xA5, 0xCC, 0x88, 0xCD, 0x82,
+ 0x00, 0xE1, 0xBF, 0xBA, 0xCE, 0x99, 0x00, 0xCE, 0xA9, 0xCE, 0x99, 0x00,
+ 0xCE, 0x8F, 0xCE, 0x99, 0x00, 0xCE, 0xA9, 0xCD, 0x82, 0x00, 0xCE, 0xA9,
+ 0xCD, 0x82, 0xCE, 0x99, 0x00, 0xCE, 0xA9, 0xCE, 0x99, 0x00, 0x46, 0x46,
+ 0x00, 0x46, 0x49, 0x00, 0x46, 0x4C, 0x00, 0x46, 0x46, 0x49, 0x00, 0x46,
+ 0x46, 0x4C, 0x00, 0x53, 0x54, 0x00, 0x53, 0x54, 0x00, 0xD5, 0x84, 0xD5,
+ 0x86, 0x00, 0xD5, 0x84, 0xD4, 0xB5, 0x00, 0xD5, 0x84, 0xD4, 0xBB, 0x00,
+ 0xD5, 0x8E, 0xD5, 0x86, 0x00, 0xD5, 0x84, 0xD4, 0xBD, 0x00,
+};
+
diff --git a/vendor/nunicode/src/libnu/strcoll.c b/vendor/nunicode/src/libnu/strcoll.c
new file mode 100644
index 0000000000..d631f66343
--- /dev/null
+++ b/vendor/nunicode/src/libnu/strcoll.c
@@ -0,0 +1,452 @@
+#include <assert.h>
+
+#include <libnu/defines.h>
+#include <libnu/ducet.h>
+#include <libnu/strcoll.h>
+#include <libnu/strcoll_internal.h>
+
+#if (defined NU_WITH_Z_COLLATION) || (defined NU_WITH_N_COLLATION)
+
+int32_t _compound_weight(int32_t w,
+ const char **encoded, const char *limit,
+ nu_read_iterator_t read, nu_compound_read_t com,
+ const char **tail,
+ nu_codepoint_weight_t weight, void *context) {
+
+ const char *tailp = *tail;
+
+ const char *p = *encoded;
+ int32_t new_w = w;
+ int32_t consumed = 1; /* one codepoint was consumed at the top of the stack (_nu_strcoll) */
+
+ while (p < limit) {
+ uint32_t u = 0;
+
+ const char *np = com(p, limit, read, &u, &tailp);
+ new_w = weight(u, &w, context);
+
+ /* after this point, w might hold rollback value
+ * and new_w holds actual weight */
+
+ ++consumed;
+
+ if (new_w >= 0) {
+ /* if w == 0 or w == 1, then *p or *np is already pointing
+ * to needed place, otherwise re-read encoded in the forward
+ * direction preserving correctness of tail pointer */
+ if (w != 0 && w != 1) {
+ assert(consumed + w > 1);
+
+ np = *encoded;
+ tailp = *tail;
+
+ for (int32_t i = 0; i < consumed - w; ++i) {
+ np = com(np, limit, read, 0, &tailp);
+ }
+
+ w = 0;
+ }
+
+ *encoded = (w == 0 ? np : p);
+ *tail = tailp;
+
+ break;
+ }
+
+ p = np;
+ w = new_w;
+ }
+
+ if (new_w < 0) {
+ new_w = weight(0, &w, context);
+ }
+
+ assert(new_w >= 0);
+
+ return new_w;
+}
+
+inline
+int _nu_strcoll(const char *lhs, const char *lhs_limit,
+ const char *rhs, const char *rhs_limit,
+ nu_read_iterator_t it1, nu_read_iterator_t it2,
+ nu_compound_read_t com1, nu_compound_read_t com2,
+ nu_codepoint_weight_t weight, void *context,
+ ssize_t *collated_left, ssize_t *collated_right) {
+
+ int cmp = 0;
+
+ const char *lp = lhs, *rp = rhs;
+ const char *ltailp = 0, *rtailp = 0;
+
+ uint32_t u1 = 0, u2 = 0;
+
+ while ((lp < lhs_limit && rp < rhs_limit)
+ || (ltailp != 0 && rp < rhs_limit)
+ || (rtailp != 0 && lp < lhs_limit)) {
+
+ lp = com1(lp, lhs_limit, it1, &u1, &ltailp);
+ rp = com2(rp, rhs_limit, it2, &u2, &rtailp);
+
+#ifdef NU_DISABLE_CONTRACTIONS
+ /* if contractions are disabled, then same codepoints
+ * will produce same weights and there is no need
+ * to weight each, i.e. weight(u1) == weight(u2) and
+ * collation may proceed to next codepoints */
+ if (u1 != u2) {
+#endif
+ int32_t w1 = weight(u1, 0, context);
+ int32_t w2 = weight(u2, 0, context);
+
+ if (w1 < 0) {
+ w1 = _compound_weight(w1, &lp, lhs_limit,
+ it1, com1, &ltailp,
+ weight, context);
+ }
+
+ if (w2 < 0) {
+ w2 = _compound_weight(w2, &rp, rhs_limit,
+ it2, com2, &rtailp,
+ weight, context);
+ }
+
+ assert(w1 >= 0);
+ assert(w2 >= 0);
+
+ if (w1 < w2) {
+ cmp = -1;
+ break;
+ }
+ else if (w1 > w2) {
+ cmp = 1;
+ break;
+ }
+
+#ifdef NU_DISABLE_CONTRACTIONS
+ }
+#endif
+
+ if (u1 == 0 || u2 == 0) {
+ break;
+ }
+ }
+
+ /* collated_left and collated_right should count
+ * number of successfully collated bytes, not taking
+ * into account limits. therefore if cmp != 0,
+ * number of collated bytes is decreased by (at least) 1
+ * and cmp is limits-fixed afterwards */
+
+ if (collated_left != 0) {
+ *collated_left = (lp - lhs) - (cmp == 0 ? 0 : 1);
+ }
+
+ if (collated_right != 0) {
+ *collated_right = (rp - rhs) - (cmp == 0 ? 0 : 1);
+ }
+
+ if (cmp == 0) {
+ if (rp < rhs_limit && lp >= lhs_limit) {
+ cmp = -1;
+ }
+ else if (lp < lhs_limit && rp >= rhs_limit) {
+ cmp = 1;
+ }
+ }
+
+ return cmp;
+}
+
+inline
+const char* _nu_strchr(const char *lhs, const char *lhs_limit,
+ uint32_t c, nu_read_iterator_t read,
+ nu_compound_read_t com,
+ nu_casemapping_t casemap, nu_read_iterator_t casemap_read) {
+
+ const char *p = lhs;
+ const char *tail = 0;
+ uint32_t u = 0;
+
+ const char *rhs = 0;
+
+ if (casemap != 0) {
+ rhs = casemap(c);
+ if (rhs != 0) {
+ rhs = casemap_read(rhs, &c); /* read new lead codepoint */
+ }
+ }
+
+ while (p < lhs_limit) {
+ const char *np = com(p, lhs_limit, read, &u, &tail);
+
+ if (u == 0) {
+ break;
+ }
+
+ if (u == c) {
+ if (rhs == 0) {
+ return p;
+ }
+
+ /* rhs != 0 */
+
+ const char *rp = rhs;
+ uint32_t u2 = 0;
+
+ do {
+ rp = casemap_read(rp, &u2);
+
+ if (u2 == 0) {
+ return p; /* succ exit point */
+ }
+
+ if (np >= lhs_limit) {
+ return 0;
+ }
+
+ np = com(np, lhs_limit, read, &u, &tail);
+
+ if (u == 0) {
+ return 0;
+ }
+
+ if (u != u2) {
+ break;
+ }
+ }
+ while (u2 != 0);
+ }
+
+ p = np;
+ }
+
+ return 0;
+}
+
+inline
+const char* _nu_strrchr(const char *encoded, const char *limit,
+ uint32_t c, nu_read_iterator_t read,
+ nu_compound_read_t com,
+ nu_casemapping_t casemap, nu_read_iterator_t casemap_read) {
+
+ /* there is probably not much sense in finding string end by decoding it
+ * and then reverse read string again to find last codepoint, therefore
+ * this is a sequence of _nu_strchr() in forward direction
+ *
+ * please let me know if i'm wrong */
+
+ const char *p = encoded;
+ const char *last = 0;
+
+ while (p < limit) {
+ p = _nu_strchr(p, limit, c, read, com, casemap, casemap_read);
+
+ if (p == 0) {
+ return last;
+ }
+
+ last = p;
+ p = read(p, 0); /* skip one codepoint and continue */
+ }
+
+ return last;
+}
+
+inline
+const char* _nu_strstr(const char *haystack, const char *haystack_limit,
+ const char *needle, const char *needle_limit,
+ nu_read_iterator_t it1, nu_read_iterator_t it2,
+ nu_compound_read_t com1, nu_compound_read_t com2,
+ nu_casemapping_t casemap, nu_read_iterator_t casemap_read,
+ nu_codepoint_weight_t weight, void *context) {
+
+ uint32_t n0 = 0;
+ if (needle_limit != needle) {
+ it2(needle, &n0);
+ }
+
+ if (needle_limit == needle || n0 == 0) {
+ return haystack;
+ }
+
+ ssize_t needle_len = (needle_limit != NU_UNLIMITED
+ ? (needle_limit - needle)
+ : nu_strbytelen(needle, it2));
+
+ const char *h0 = haystack;
+ do {
+ h0 = _nu_strchr(h0, haystack_limit,
+ n0, it1,
+ com1,
+ casemap, casemap_read);
+
+ if (h0 == 0) {
+ break;
+ }
+
+ ssize_t collated_left = 0, collated_right = 0;
+ _nu_strcoll(h0, haystack_limit, needle, needle_limit,
+ it1, it2,
+ com1, com2,
+ weight, context,
+ &collated_left, &collated_right);
+
+ /* it doesn't matter what collate result is
+ * if whole needle was successfully collated */
+ if (collated_right >= needle_len) {
+ return h0;
+ }
+
+ /* skip one codepoint in haystack */
+ if (h0 < haystack_limit) {
+ h0 = it1(h0, 0);
+ }
+ }
+ while (h0 != 0 && h0 < haystack_limit);
+
+ return 0;
+}
+
+#ifdef NU_WITH_Z_COLLATION
+
+const char* nu_strchr(const char *encoded, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strchr(encoded, NU_UNLIMITED,
+ c, read,
+ nu_default_compound_read,
+ 0, 0);
+}
+
+const char* nu_strcasechr(const char *encoded, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strchr(encoded, NU_UNLIMITED,
+ c, read,
+ nu_nocase_compound_read,
+ NU_FOLDING_FUNCTION, nu_casemap_read);
+}
+
+const char* nu_strrchr(const char *encoded, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strrchr(encoded, NU_UNLIMITED,
+ c, read,
+ nu_default_compound_read,
+ 0, 0);
+}
+
+const char* nu_strrcasechr(const char *encoded, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strrchr(encoded, NU_UNLIMITED, c, read,
+ nu_nocase_compound_read,
+ NU_FOLDING_FUNCTION, nu_casemap_read);
+}
+
+int nu_strcoll(const char *s1, const char *s2,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read) {
+ return _nu_strcoll(s1, NU_UNLIMITED, s2, NU_UNLIMITED,
+ s1_read, s2_read,
+ nu_default_compound_read, nu_default_compound_read,
+ nu_ducet_weight, 0,
+ 0, 0);
+}
+
+int nu_strcasecoll(const char *s1, const char *s2,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read) {
+ return _nu_strcoll(s1, NU_UNLIMITED, s2, NU_UNLIMITED,
+ s1_read, s2_read,
+ nu_nocase_compound_read, nu_nocase_compound_read,
+ nu_ducet_weight, 0,
+ 0, 0);
+}
+
+const char* nu_strstr(const char *haystack, const char *needle,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read) {
+ return _nu_strstr(haystack, NU_UNLIMITED, needle, NU_UNLIMITED,
+ haystack_read, needle_read,
+ nu_default_compound_read, nu_default_compound_read,
+ 0, 0,
+ nu_ducet_weight, 0);
+}
+
+const char* nu_strcasestr(const char *haystack, const char *needle,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read) {
+ return _nu_strstr(haystack, NU_UNLIMITED, needle, NU_UNLIMITED,
+ haystack_read, needle_read,
+ nu_nocase_compound_read, nu_nocase_compound_read,
+ NU_FOLDING_FUNCTION, nu_casemap_read,
+ nu_ducet_weight, 0);
+}
+
+#endif /* NU_WITH_Z_COLLATION */
+
+#ifdef NU_WITH_N_COLLATION
+
+const char* nu_strnchr(const char *encoded, size_t max_len, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strchr(encoded, encoded + max_len,
+ c, read,
+ nu_default_compound_read,
+ 0, 0);
+}
+
+const char* nu_strcasenchr(const char *encoded, size_t max_len, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strchr(encoded, encoded + max_len,
+ c, read,
+ nu_nocase_compound_read,
+ NU_FOLDING_FUNCTION, nu_casemap_read);
+}
+
+const char* nu_strrnchr(const char *encoded, size_t max_len, uint32_t c, nu_read_iterator_t read) {
+ return _nu_strrchr(encoded, encoded + max_len,
+ c, read,
+ nu_default_compound_read,
+ 0, 0);
+}
+
+const char* nu_strrcasenchr(const char *encoded, size_t max_len, uint32_t c,
+ nu_read_iterator_t read) {
+ return _nu_strrchr(encoded, encoded + max_len,
+ c, read,
+ nu_nocase_compound_read,
+ NU_FOLDING_FUNCTION, nu_casemap_read);
+}
+
+int nu_strncoll(const char *s1, size_t s1_max_len,
+ const char *s2, size_t s2_max_len,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read) {
+ return _nu_strcoll(s1, s1 + s1_max_len, s2, s2 + s2_max_len,
+ s1_read, s2_read,
+ nu_default_compound_read, nu_default_compound_read,
+ nu_ducet_weight, 0,
+ 0, 0);
+}
+
+int nu_strcasencoll(const char *s1, size_t s1_max_len,
+ const char *s2, size_t s2_max_len,
+ nu_read_iterator_t s1_read, nu_read_iterator_t s2_read) {
+ return _nu_strcoll(s1, s1 + s1_max_len, s2, s2 + s2_max_len,
+ s1_read, s2_read,
+ nu_nocase_compound_read, nu_nocase_compound_read,
+ nu_ducet_weight, 0,
+ 0, 0);
+}
+
+const char* nu_strnstr(const char *haystack, size_t haystack_max_len,
+ const char *needle, size_t needle_max_len,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read) {
+ return _nu_strstr(haystack, haystack + haystack_max_len,
+ needle, needle + needle_max_len,
+ haystack_read, needle_read,
+ nu_default_compound_read, nu_default_compound_read,
+ 0, 0,
+ nu_ducet_weight, 0);
+}
+
+const char* nu_strcasenstr(const char *haystack, size_t haystack_max_len,
+ const char *needle, size_t needle_max_len,
+ nu_read_iterator_t haystack_read, nu_read_iterator_t needle_read) {
+ return _nu_strstr(haystack, haystack + haystack_max_len,
+ needle, needle + needle_max_len,
+ haystack_read, needle_read,
+ nu_nocase_compound_read, nu_nocase_compound_read,
+ NU_FOLDING_FUNCTION, nu_casemap_read,
+ nu_ducet_weight, 0);
+}
+
+#endif /* NU_WITH_N_COLLATION */
+
+#endif /* NU_WITH_Z_COLLATION || NU_WITH_N_COLLATION */
diff --git a/vendor/nunicode/src/libnu/strings.c b/vendor/nunicode/src/libnu/strings.c
new file mode 100644
index 0000000000..0eda8cf08f
--- /dev/null
+++ b/vendor/nunicode/src/libnu/strings.c
@@ -0,0 +1,89 @@
+#include <libnu/defines.h>
+#include <libnu/strings.h>
+
+#if defined (NU_WITH_Z_STRINGS) || defined(NU_WITH_N_STRINGS)
+
+static ssize_t _nu_strlen(const char *encoded, const char *limit, nu_read_iterator_t it) {
+ ssize_t len = 0;
+
+ const char *p = encoded;
+ while (p < limit) {
+ uint32_t u = 0;
+ p = it(p, &u);
+
+ if (u == 0) {
+ break;
+ }
+
+ ++len;
+ }
+
+ return len;
+}
+
+static ssize_t _nu_bytelen(const uint32_t *unicode, const uint32_t *limit, nu_write_iterator_t it) {
+ ssize_t len = 0;
+
+ const uint32_t *p = unicode;
+ while (p < limit) {
+ if (*p == 0) {
+ break;
+ }
+
+ /* nu_write_iterator_t will return offset relative to 0
+ * which is effectively bytes length of codepoint */
+ size_t byte_len = (size_t)it(*p, 0);
+ len += byte_len;
+
+ ++p;
+ }
+
+ return len;
+}
+
+static ssize_t _nu_strbytelen(const char *encoded, const char *limit, nu_read_iterator_t it) {
+ uint32_t u = 0;
+ const char *p = encoded;
+
+ while (p < limit) {
+ const char *np = it(p, &u);
+
+ if (u == 0) {
+ return (p - encoded);
+ }
+
+ p = np;
+ }
+
+ return 0;
+}
+
+#endif /* NU_WITH_N_STRINGS || NU_WITH_Z_STRINGS */
+
+#ifdef NU_WITH_Z_STRINGS
+
+ssize_t nu_strlen(const char *encoded, nu_read_iterator_t it) {
+ return _nu_strlen(encoded, NU_UNLIMITED, it);
+}
+
+ssize_t nu_bytelen(const uint32_t *unicode, nu_write_iterator_t it) {
+ return _nu_bytelen(unicode, NU_UNLIMITED, it);
+}
+
+ssize_t nu_strbytelen(const char *encoded, nu_read_iterator_t it) {
+ return _nu_strbytelen(encoded, NU_UNLIMITED, it);
+}
+
+#endif /* NU_WITH_Z_STRINGS */
+
+#ifdef NU_WITH_N_STRINGS
+
+ssize_t nu_strnlen(const char *encoded, size_t max_len, nu_read_iterator_t it) {
+ return _nu_strlen(encoded, encoded + max_len, it);
+}
+
+ssize_t nu_bytenlen(const uint32_t *unicode, size_t max_len, nu_write_iterator_t it) {
+ return _nu_bytelen(unicode, unicode + max_len, it);
+}
+
+#endif /* NU_WITH_N_STRINGS */
diff --git a/vendor/nunicode/src/libnu/tolower.c b/vendor/nunicode/src/libnu/tolower.c
new file mode 100644
index 0000000000..1ce229d370
--- /dev/null
+++ b/vendor/nunicode/src/libnu/tolower.c
@@ -0,0 +1,58 @@
+#include <assert.h>
+
+#include <libnu/casemap.h>
+
+#ifdef NU_WITH_TOLOWER
+
+#include <libnu/casemap_internal.h>
+#include "gen/_tolower.c"
+
+/* in nu_casemap_read (UTF-8), zero-terminated */
+static const char *__nu_final_sigma = "ς";
+
+const char* nu_tolower(uint32_t codepoint) {
+ return _nu_to_something(codepoint, NU_TOLOWER_G, NU_TOLOWER_G_SIZE,
+ NU_TOLOWER_VALUES_C, NU_TOLOWER_VALUES_I, NU_TOLOWER_COMBINED);
+}
+
+const char* _nu_tolower(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context) {
+
+ (void)(context);
+
+ uint32_t _u = 0;
+ const char *np = read(encoded, &_u);
+
+ if (u != 0) {
+ *u = _u;
+ }
+
+ /* handling of 0x03A3 ('Σ')
+ *
+ * this is the only language-independent exception described in
+ * SpecialCasing.txt (Unicode 7.0) */
+
+ assert(nu_casemap_read == nu_utf8_read);
+
+ if (_u == 0x03A3) {
+ if (np >= limit) {
+ *transform = __nu_final_sigma;
+ return np;
+ }
+
+ uint32_t nu = 0;
+ read(np, &nu);
+
+ if (nu == 0) {
+ *transform = __nu_final_sigma;
+ return np;
+ }
+ }
+
+ *transform = nu_tolower(_u);
+
+ return np;
+}
+
+#endif /* NU_WITH_TOLOWER */
diff --git a/vendor/nunicode/src/libnu/tounaccent.c b/vendor/nunicode/src/libnu/tounaccent.c
new file mode 100644
index 0000000000..ad5b269827
--- /dev/null
+++ b/vendor/nunicode/src/libnu/tounaccent.c
@@ -0,0 +1,57 @@
+#include <assert.h>
+
+#include <libnu/casemap.h>
+
+#ifdef NU_WITH_UNACCENT
+
+#include <libnu/casemap_internal.h>
+#include "gen/_tounaccent.c"
+
+const char* nu_tounaccent(uint32_t codepoint) {
+ typedef struct {
+ uint32_t block_start;
+ uint32_t block_end;
+ } block_t;
+
+ static const block_t blocks[] = {
+ { 0x0300, 0x036F }, /* Combining Diacritical Marks */
+ { 0x1AB0, 0x1AFF }, /* Combining Diacritical Marks Extended */
+ { 0x20D0, 0x20FF }, /* Combining Diacritical Marks for Symbols */
+ { 0x1DC0, 0x1DFF }, /* Combining Diacritical Marks Supplement */
+ };
+ static const size_t blocks_count = sizeof(blocks) / sizeof(*blocks);
+
+ /* check if codepoint itself is a diacritic,
+ * return empty string in that case
+ * (transform into empty string */
+ assert(nu_casemap_read == nu_utf8_read);
+ for (size_t i = 0; i < blocks_count; ++i) {
+ if (codepoint >= blocks[i].block_start && codepoint <= blocks[i].block_end) {
+ return ""; /* return zero-terminated empty string in nu_casemap_read (utf-8) */
+ }
+ }
+
+ return _nu_to_something(codepoint, NU_TOUNACCENT_G, NU_TOUNACCENT_G_SIZE,
+ NU_TOUNACCENT_VALUES_C, NU_TOUNACCENT_VALUES_I, NU_TOUNACCENT_COMBINED);
+}
+
+const char* _nu_tounaccent(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context) {
+
+ (void)(limit);
+ (void)(context);
+
+ uint32_t _u = 0;
+ const char *np = read(encoded, &_u);
+
+ *transform = nu_tounaccent(_u);
+
+ if (u != 0) {
+ *u = _u;
+ }
+
+ return np;
+}
+
+#endif /* NU_WITH_UNACCENT */
diff --git a/vendor/nunicode/src/libnu/toupper.c b/vendor/nunicode/src/libnu/toupper.c
new file mode 100644
index 0000000000..fad3941e6d
--- /dev/null
+++ b/vendor/nunicode/src/libnu/toupper.c
@@ -0,0 +1,32 @@
+#include <libnu/casemap.h>
+
+#ifdef NU_WITH_TOUPPER
+
+#include <libnu/casemap_internal.h>
+#include "gen/_toupper.c"
+
+const char* nu_toupper(uint32_t codepoint) {
+ return _nu_to_something(codepoint, NU_TOUPPER_G, NU_TOUPPER_G_SIZE,
+ NU_TOUPPER_VALUES_C, NU_TOUPPER_VALUES_I, NU_TOUPPER_COMBINED);
+}
+
+const char* _nu_toupper(const char *encoded, const char *limit, nu_read_iterator_t read,
+ uint32_t *u, const char **transform,
+ void *context) {
+
+ (void)(limit);
+ (void)(context);
+
+ uint32_t _u = 0;
+ const char *np = read(encoded, &_u);
+
+ *transform = nu_toupper(_u);
+
+ if (u != 0) {
+ *u = _u;
+ }
+
+ return np;
+}
+
+#endif /* NU_WITH_TOUPPER */
diff --git a/vendor/nunicode/src/libnu/utf8.c b/vendor/nunicode/src/libnu/utf8.c
new file mode 100644
index 0000000000..c9ea0fc819
--- /dev/null
+++ b/vendor/nunicode/src/libnu/utf8.c
@@ -0,0 +1,97 @@
+#include <libnu/utf8.h>
+
+#ifdef NU_WITH_UTF8_READER
+#ifdef NU_WITH_VALIDATION
+
+int nu_utf8_validread(const char *encoded, size_t max_len) {
+ int len = utf8_validread_basic(encoded, max_len);
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ /* Unicode core spec, D92, Table 3-7
+ */
+
+ switch (len) {
+ /* case 1: single byte sequence can't be > 0x7F and produce len == 1
+ */
+
+ case 2: {
+ uint8_t p1 = *(const unsigned char *)(encoded);
+
+ if (p1 < 0xC2) { /* 2-byte sequences with p1 > 0xDF are 3-byte sequences */
+ return 0;
+ }
+
+ /* the rest will be handled by utf8_validread_basic() */
+
+ break;
+ }
+
+ case 3: {
+ uint8_t p1 = *(const unsigned char *)(encoded);
+
+ /* 3-byte sequences with p1 < 0xE0 are 2-byte sequences,
+ * 3-byte sequences with p1 > 0xEF are 4-byte sequences */
+
+ uint8_t p2 = *(const unsigned char *)(encoded + 1);
+
+ if (p1 == 0xE0 && p2 < 0xA0) {
+ return 0;
+ }
+ else if (p1 == 0xED && p2 > 0x9F) {
+ return 0;
+ }
+
+ /* (p2 < 0x80 || p2 > 0xBF) and p3 will be covered
+ * by utf8_validread_basic() */
+
+ break;
+ }
+
+ case 4: {
+ uint8_t p1 = *(const unsigned char *)(encoded);
+
+ if (p1 > 0xF4) { /* 4-byte sequence with p1 < 0xF0 are 3-byte sequences */
+ return 0;
+ }
+
+ uint8_t p2 = *(const unsigned char *)(encoded + 1);
+
+ if (p1 == 0xF0 && p2 < 0x90) {
+ return 0;
+ }
+
+ /* (p2 < 0x80 || p2 > 0xBF) and the rest (p3, p4)
+ * will be covered by utf8_validread_basic() */
+
+ break;
+ }
+
+ } /* switch */
+
+ return len;
+}
+
+#endif /* NU_WITH_VALIDATION */
+#endif /* NU_WITH_UTF8_READER */
+
+#ifdef NU_WITH_UTF8_WRITER
+
+char* nu_utf8_write(uint32_t unicode, char *utf8) {
+ unsigned codepoint_len = utf8_codepoint_length(unicode);
+
+ if (utf8 != 0) {
+ switch (codepoint_len) {
+ case 1: *utf8 = (char)(unicode); break;
+ case 2: b2_utf8(unicode, utf8); break;
+ case 3: b3_utf8(unicode, utf8); break;
+ default: b4_utf8(unicode, utf8); break; /* len == 4 */
+ }
+ }
+
+ return utf8 + codepoint_len;
+}
+
+#endif /* NU_WITH_UTF8_WRITER */
diff --git a/vendor/nunicode/version.txt b/vendor/nunicode/version.txt
new file mode 100644
index 0000000000..6259340971
--- /dev/null
+++ b/vendor/nunicode/version.txt
@@ -0,0 +1 @@
+1.8